からあげ日記

Webエンジニア的なこととか。

Python3 のスクリプトを Systemd でデーモン化

Python3 のスクリプトを Systemd でデーモン化( Systemd にスクリプトを登録)する方法とAnsible のサンプルです。

環境は Ubuntu 16.04 (64bit) です。

環境

2017/12/12 時点。

Ubuntu

# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"

# arch
x86_64

Systemd

# systemctl --version
systemd 229
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN

Python

# cd <project_root>
# ./venv/bin/python3.6 --version
Python 3.6.2

Systemd にスクリプトを登録

手順

/etc/systemd/system/<app_name>.service にサービス設定ファイルを追加。

[Unit]
Description=My Task Scheduling Script

[Service]
Type=simple
KillMode=control-group
ExecStart=<project_root>/venv/bin/python3 <project_root>/run.py
Restart=on-failure
User=<user>
Group=<group>

[Install]
WantedBy=multi-user.target

※ グローバルではなく <project_root>/venv/bin/ 以下の python3 を使用

venv を使用してライブラリをインストールしているため、 venv 上の python3 を使用します。

Type サービスの起動完了を判定するタイミング
  • simple
    • フォアグラウンドで実行を継続。コマンド実行後即起動完了判定
KillMode グループ内にプロセスが残っている場合の処理
  • control-group
    • グループ内の全プロセスを停止
Environment 環境変数
ExecStart サービス起動コマンド
ExecStop サービス停止コマンド
Restart サービスプロセス停止時の再起動条件
  • on-failure
    • プロセスがzero exit code 以外で停止した場合
User サービス実行ユーザ
Group サービス実行ユーザのグループ

その他のオプションについては以下を参照。

https://www.freedesktop.org/software/systemd/man/systemd.service.html

ansible

sudoers でコマンドの実行許可の設定

root 以外の特定のユーザで実行したい場合は、 sudoers の設定も行う。

手順

/etc/sudoers.d/ などに追記する。

Cmnd_Alias MY_APP = /bin/systemctl start <app_name>.service , /bin/systemctl stop <my_app>.service , /bin/systemctl status <app_name>.service

<user>       ALL = (root) NOPASSWD:/bin/su, MY_APP
Cmnd_Alias コマンドの一覧に名前をつける

実行例

$ sudo /bin/systemctl status myappd.service


^[[0;1;32m●^[[0m <app_name>.service -My App
   Loaded: loaded (/etc/systemd/system/<app_name>.service; enabled; vend
or preset: enabled)
   Active: ^[[0;1;32mactive (running)^[[0m since Wed 2017-12-12 13:13:0
2 JST; 28s ago
  Process: 10403 ExecStop=<project_root>/venv/bin/python3
lask shutdown_scheduler (code=exited, status=0/SUCCESS)
 Main PID: 10412 (python3)
   CGroup: /system.slice/<app_name>.service
           └─10412 <project_root>/venv/bin/python3 <project_root>/run.py

Dec 12 13:13:02 <server> systemd[1]: Started My App.

ansible

参考

qiita.com

よろしくない設定や間違っている部分があればご指摘いただければ幸いです。