systemdユニットファイルの編集は「systemctl edit」で!

西山
2026-01-09
2026-01-09

こんにちは。日々是発見が楽しみな西山です。

Linuxでデーモンの起動管理と言えばsystemd。そのユニットファイルの設定をデフォルトから変更したい時、みなさんはどうしていますか?
/usr/lib/systemd/systemにあるユニットファイルをおもむろにエディタで書き換えてないでしょうか。でもそれ、後々トラブルを招きかねないやり方です。
今日は正しい「systemdユニットファイルの書き換え方」を覚えて帰って下さいね。

ベタで書き換えると巻き戻されます!

/usr/lib/systemd/systemのユニットファイルを直接書き換えると、何が起こるでしょうか。
このファイルは、dnfやaptで配布・管理される対象のファイルです。つまり、dnf updateやapt upgradeでパッケージが更新されると、このファイルは上書きされてしまいます。なのでこのファイルを直接いじってはいけません。
いじった後にパッケージのupdateをかけると、編集したつもりの内容が初期状態に戻されてしまいます!

正しいやり方「systemctl edit」

ではユニットファイルの処理をカスタマイズするのはどうやればいいでしょうか?
「/etc/systemd/system/(ユニット名).service.d」というディレクトリを作成し、その中に「override.conf」というファイルを作って処理を書くと、デフォルトの内容を上書きしてカスタマイズできます。

これを手動で作りなさい、と書いている記事もたくさんあるのですが、ここで今日紹介する「systemctl edit」の出番です。
例えば、「systemctl edit dovecot.service」と実行する(要root権限)と、viやnanoが起動して以下のような編集画面が開きます。

### Editing /etc/systemd/system/dovecot.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file
【訳:ここから下のコメントまでの間にある内容は、ファイルの新しい内容になります。】



### Lines below this comment will be discarded
【訳:このコメントより下の行は破棄されます。】

### /usr/lib/systemd/system/dovecot.service
# # This file is part of Dovecot
# #
# # DO NOT CUSTOMIZE THIS FILE, INSTEAD
# # create the file:
# #     `/etc/systemd/system/dovecot.service.d/service.conf'.
# # or copy this as
# #     `/etc/systemd/system/dovecot.service` and edit then
# # and put your changes there

# [Unit]
# Description=Dovecot IMAP/POP3 email server
# Documentation=man:dovecot(1)
# Documentation=https://doc.dovecot.org/
# After=local-fs.target network-online.target dovecot-init.service
# Requires=dovecot-init.service

# [Service]
# Type=notify
# ExecStartPre=/usr/libexec/dovecot/prestartscript
# ExecStart=/usr/sbin/dovecot -F
# ExecReload=/usr/bin/doveadm reload
# ExecStop=/usr/bin/doveadm stop
# PrivateTmp=true
# NonBlocking=yes
# # this will make /usr /boot /etc read only for dovecot
# ProtectSystem=full
# ProtectHome=no
# PrivateDevices=true

# # You can add environment variables with e.g.:
# #Environment='CORE_OUTOFMEM=1'
# # If you have trouble with `Too many open files', increase
# LimitNOFILE=65535
# # If you want to allow the Dovecot services to produce core dumps, use:
# #LimitCORE=infinity

# [Install]
# WantedBy=multi-user.target

例えばここで、dovecotの起動オプションを変更したい、なんて時は

### Editing /etc/systemd/system/dovecot.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

ExecStart=/usr/sbin/dovecot -D

### Lines below this comment will be discarded

### /usr/lib/systemd/system/dovecot.service
...

 というように、上書きしたい内容をコメント行の間に書きます
そしてエディタで保存すると、

  • /etc/systemd/system/(ユニット名).service.dディレクトリを作成
  • その中にoverride.confを作成
  • 追記した内容をoverride.confに反映

という一連の動作が自動で行われます。

この操作をした後に「/etc/systemd/system/dovecot.service.d/override.conf」を見てみると、

ExecStart=/usr/sbin/dovecot -D

となっており、systemdのExecstartはこのoverride.confで上書きされているのが分かります。

ソフトウェアデフォルトの設定値とoverrideで変更された現在の設定値が両方ひと目で確認できる、そんな優れモノが「systemctl edit」です。

複数定義できる引数をカスタマイズする場合

ユニットファイルに書ける引数の中には、複数定義できるものがあります。
デーモン起動前/後にコマンドを実行させるExecStartPre/ExecStartPost、timerユニットでスケジュールを指定するOnCalenderなどは、ユニットファイル内で複数回定義できるようになっています。

では「デフォルト定義のOnCalenderは止めて、自分で決めた日時にtimerを実行したい!」なんて時はどう書くのが正しいでしょう?
overrideにOnCalenderを書き足しただけでは、デフォルトとoverride、両方のタイマーが有効となってユニットが起動されてしまいます。

OnCalendar=
OnCalendar=Mon..Fri 12:00:00

正解はまず「OnCalendar=」と書くことです。これでデフォルト定義の「OnCalendar」がクリアされるので、次の行に指定したいスケジュールを書きます。
これでデフォルト定義のスケジュールはトリガーされなくなり、カスタム定義したスケジュールのみが有効になります。

正しいやり方で作業しよう、正しい知識を広げよう

と、ここまで偉そうに語ってきた私ですが、「systemctl edit」を会得したのはつい2~3年ほど前のこと。それまでは上で書いた失敗パターンを全部踏み抜いてました(汗)。時間と手間をいっぱい無駄にしました……。

公式が準備している手順やコマンドはそれ相応の意味があって準備されているものなので、それを無視して我流を通すのは基本的によくないことです。
「systemctl edit」に関しては紹介している記事や、公式の立場からの情報が少ないなぁ……とも感じるのですが、せめて今回、この記事を読まれた方々には存在が広がってほしいと願います。