systemd ユニットファイル(.service)
『systemd』のユニットファイルは、サービス・タイマー・マウントなどシステムの構成要素を宣言的に定義するテキストファイルです。自作アプリをデーモンとして登録するには .service ファイルを作成し、[Unit]・[Service]・[Install] の3つのセクションで動作を記述します。登録後は systemctl コマンドで起動・停止・自動起動の管理が行えます。
構文
# =====================================================
# .service ファイルの基本構造
# =====================================================
#
# /etc/systemd/system/{サービス名}.service に配置します
# セクション ([Unit] / [Service] / [Install]) の順番は
# 慣例に従いますが、動作に影響はありません
# =====================================================
[Unit]
# サービスの説明(journalctl などで表示されます)
Description={サービスの説明文}
# このサービスを起動する前に完了しておくべきユニットを指定します
After={ユニット名}
# 強制依存: 指定ユニットが起動できない場合このサービスも起動しません
Requires={ユニット名}
# 弱い依存: 指定ユニットが起動できなくてもこのサービスは起動を試みます
Wants={ユニット名}
[Service]
# サービス本体のプロセス起動コマンド(フルパスで指定します)
ExecStart={コマンドのフルパス} {引数 ...}
# サービス停止時に実行するコマンド(省略可)
ExecStop={コマンドのフルパス} {引数 ...}
# サービス停止後に実行するコマンド(クリーンアップ処理など)
ExecStopPost={コマンドのフルパス} {引数 ...}
# サービスの実行ユーザーを指定します(root 以外を推奨します)
User={ユーザー名}
# サービスの実行グループを指定します(省略可)
Group={グループ名}
# プロセスの作業ディレクトリを指定します
WorkingDirectory={ディレクトリのフルパス}
# 環境変数を直接指定します(複数行記述可)
Environment="変数名=値"
# 環境変数を別ファイルから読み込みます
EnvironmentFile={.env ファイルのフルパス}
# プロセスの種類を指定します
# simple : ExecStart で起動したプロセスをメインとして扱います(デフォルト)
# forking : プロセスが fork してバックグラウンドに回る従来型デーモン向けです
# notify : sd_notify() でシステムに準備完了を通知するサービス向けです
# oneshot : 一度だけ実行して終了するタスク向けです
Type={simple|forking|notify|oneshot}
# クラッシュ時などの自動再起動の条件を指定します
# no : 再起動しません(デフォルト)
# always : 常に再起動します
# on-failure : 異常終了時のみ再起動します
Restart={no|always|on-failure|on-abnormal|on-success}
# 再起動までの待機秒数を指定します(デフォルト: 100ms)
RestartSec={秒数}
[Install]
# systemctl enable でシステムの起動時に連動して起動するターゲットを指定します
# multi-user.target は通常のマルチユーザーモード(ネットワーク起動後)です
WantedBy={ターゲット名}
構文一覧
| セクション | ディレクティブ | 説明 |
|---|---|---|
| [Unit] | Description | サービスの説明文です。systemctl status や journalctl のヘッダーに表示されます。 |
After | 起動順序の制御です。指定したユニットが起動した後にこのサービスを起動します。network.target や mysql.service などを指定します。 | |
Requires | 強い依存関係の宣言です。指定ユニットが起動に失敗するとこのサービスも起動しません。 | |
Wants | 弱い依存関係の宣言です。指定ユニットが失敗してもこのサービスは起動を試みます。 | |
| [Service] | ExecStart | サービス起動コマンドです。必須項目で、コマンドはフルパスで記述します。 |
ExecStop | サービス停止時に実行するコマンドです。省略時は SIGTERM が送られます。 | |
Restart | 再起動ポリシーの設定です。on-failure を指定するとクラッシュ時に自動復旧します。 | |
User / Group | 実行ユーザー・グループを指定します。root 以外の専用ユーザーを指定することでセキュリティを高められます。 | |
WorkingDirectory | プロセスの作業ディレクトリです。相対パスを使うコマンドがある場合に必ず指定します。 | |
Environment | 環境変数を直接記述します。Environment="NODE_ENV=production" のように記述します。 | |
EnvironmentFile | 環境変数を外部ファイルから読み込みます。.env ファイルのフルパスを指定します。 | |
Type | サービスの起動タイプです。通常の常駐プロセスには simple、fork するデーモンには forking を指定します。 | |
| [Install] | WantedBy | systemctl enable 時に自動起動を組み込むターゲットを指定します。通常は multi-user.target を指定します。 |
使用例
/etc/systemd/system/kyo-app.service
# ===================================================== # 草薙京のウェブアプリを systemd サービスとして登録する # Node.js アプリを kyo ユーザーで常駐させます # ===================================================== [Unit] # journalctl や systemctl status で表示される説明文です Description=Kyo Kusanagi Web Application # ネットワークが利用可能になった後に起動します After=network.target [Service] # サービスの実行ユーザーを専用の kyo ユーザーに限定します # root で動かすとセキュリティリスクが高まるため避けます User=kyo Group=kyo # アプリのソースコードが置かれたディレクトリを作業ディレクトリに指定します WorkingDirectory=/home/kyo/kyo-app # 本番環境であることを環境変数で伝えます Environment="NODE_ENV=production" Environment="PORT=3000" # シークレットキーなど秘匿情報は別ファイルに分離して読み込みます # /home/kyo/kyo-app/.env には SECRET_KEY=... のように記述します EnvironmentFile=/home/kyo/kyo-app/.env # Node.js アプリの起動コマンドをフルパスで指定します ExecStart=/usr/bin/node /home/kyo/kyo-app/server.js # 異常終了(クラッシュ)時に自動再起動します # 正常終了(exit 0)では再起動しません Restart=on-failure # 再起動前に 5 秒待機します(連続クラッシュ時の無限ループを防ぎます) RestartSec=5 [Install] # systemctl enable 実行時に multi-user.target(通常のマルチユーザー起動)に # 組み込まれます。サーバー起動時にこのサービスが自動的に起動するようになります WantedBy=multi-user.target
実行するコマンドは次の通りです。
$ sudo systemctl daemon-reload
$ sudo systemctl enable kyo-app.service
Created symlink /etc/systemd/system/multi-user.target.wants/kyo-app.service → /etc/systemd/system/kyo-app.service.
$ sudo systemctl start kyo-app.service
$ sudo systemctl status kyo-app.service
● kyo-app.service - Kyo Kusanagi Web Application
Loaded: loaded (/etc/systemd/system/kyo-app.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2026-03-25 12:00:00 JST; 3s ago
Main PID: 12480 (node)
Tasks: 11 (limit: 4915)
Memory: 38.2M
CPU: 412ms
CGroup: /system.slice/kyo-app.service
└─12480 /usr/bin/node /home/kyo/kyo-app/server.js
/etc/systemd/system/iori-worker.service
# ===================================================== # 八神庵のバックグラウンドワーカーを Python で登録する # キューからジョブを取り出して処理し続けるワーカーです # ===================================================== [Unit] Description=Iori Yagami Background Worker # ネットワークと Redis サービスが起動してから開始します After=network.target redis.service # Redis が動いていないとワーカーは動作しないため強い依存を宣言します Requires=redis.service [Service] User=iori Group=iori WorkingDirectory=/opt/iori-worker # Python の仮想環境を使う場合はフルパスで venv 内の python を指定します ExecStart=/opt/iori-worker/venv/bin/python worker.py # 環境変数ファイルから REDIS_URL や DATABASE_URL を読み込みます EnvironmentFile=/opt/iori-worker/.env # 常に再起動します(正常終了・異常終了を問わず常駐させます) Restart=always RestartSec=3 [Install] WantedBy=multi-user.target
実行するコマンドは次の通りです。
$ sudo systemctl daemon-reload $ sudo systemctl enable --now iori-worker.service Created symlink /etc/systemd/system/multi-user.target.wants/iori-worker.service → /etc/systemd/system/iori-worker.service. $ sudo journalctl -u iori-worker.service -f Mar 25 12:05:00 server iori-worker[12600]: Worker started. Waiting for jobs... Mar 25 12:05:12 server iori-worker[12600]: [JOB] Processing: render_flame_effect Mar 25 12:05:12 server iori-worker[12600]: [JOB] Done: render_flame_effect (0.83s)
サービスの一時停止・無効化・削除の流れ
# ----------------------------------------------- # サービスをいったん停止して無効化します # ----------------------------------------------- # サービスを停止します(プロセスは終了しますがユニットファイルは残ります) sudo systemctl stop kyo-app.service # 自動起動を無効化します(enable で作成したシンボリックリンクが削除されます) sudo systemctl disable kyo-app.service # ----------------------------------------------- # ユニットファイルを削除してサービスを完全に除去します # ----------------------------------------------- # ユニットファイル自体を削除します sudo rm /etc/systemd/system/kyo-app.service # systemd のデーモンにファイルの変更を反映させます # ファイルの追加・編集・削除後は必ず実行します sudo systemctl daemon-reload # 削除したサービスの残留情報をリセットします sudo systemctl reset-failed
実行するコマンドは次の通りです。
$ sudo systemctl daemon-reload $ sudo systemctl reset-failed $ systemctl status kyo-app.service Unit kyo-app.service could not be found.
概要
『systemd』のユニットファイルを使うと、自作のアプリやスクリプトをシステムの正式なサービスとして管理できます。/etc/systemd/system/ に配置した .service ファイルは、[Unit] セクションで起動順序と依存関係、[Service] セクションで実行コマンドやユーザー・再起動ポリシー、[Install] セクションで自動起動の組み込み先を定義します。ファイルを作成・編集した後は必ず sudo systemctl daemon-reload を実行して変更を反映させてください。サービスの起動・停止・状態確認は systemctl コマンドで行い、ログの確認には journalctl を使います。定期実行が必要な場合は .service と組み合わせて systemd タイマーを利用する方法もあります。実行ユーザーは root を避けて専用の一般ユーザーを指定し、EnvironmentFile でシークレットキーを本体ファイルから分離することで、権限の範囲を絞れます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。