Pythonファイルをデーモン化してみる

Pythonファイルはコマンドで実行するには、毎回python ファイル名.py と打たなければいけません。これをデーモン化してみたいと思います。

デーモン化って何?

平たく言うと、自動起動したりCentOSコマンドでいうsystemctlコマンドで起動したりすることになります。

デーモン化はなぜ?

デーモン化する必要がそもそもあるの?と思われる方もいるかもしれません。例えば「ブラウザと連携(mod_wsgi)とか使えば良いんじゃないのか?」という意見もでると思います

デーモン化する理由

WEBサービスのようにブラウザで見せるのではなく、例えばslackbotのようにアプリと連携をする場合は、デーモン化すれば自動で実行されるので楽です。止めるときもsystemctlコマンドでできるので楽かなと思います。

簡単にできるの?

ini.dだとちょっと難しいらしいですが、systemctlならinit.dと比べると楽なのでやっていきます。簡単かどうかは・・・わからないです

デーモン化実行

CentOS7にApache or nginx + hhvmでWordPressを動かしてみるでも少し書いていますが、/etc/systemd/system/配下にファイルを作って置きます。

環境

今回の環境は以下のようになります

  • 実行ファイル:/home/macan/slackbot/run.py
  • 実行ユーザー:macan
  • パーミッション:755

となります。

run.pyの中身

Pythonファイルのソースコードはこんな感じです

#!/usr/local/pyenv/shims/python
#coding: utf-8

from slackbot.bot import Bot

def main():
    bot = Bot()
    bot.run()

if __name__ == "__main__":
    print ('slackbot開始')
    main()

rund.serviceファイルの作成

デーモンファイルは.serviceというファイル名なのでそれで作成します。ファイル名は任意です

[root@localhost ~]# vi  /etc/systemd/system/rund.service

[Unit]
Description=Python Slack Bot

[Service]
ExecStart=/home/macan/slackbot/run.py
Restart=on-failure
Type=simple
user=macan
group=macan

[Install]
WantedBy=multi-user.target

このようにします。Type=simpleにすることで自動的にPIDが作成されます。ExecStartがファイルのパスをさしてます。

リロード

デーモンをリロードします

[root@localhost ~]# systemctl daemon-reload

起動・確認

[root@localhost ~]# systemctl start rund
[root@localhost ~]# systemctl status rund
● rund.service - Python Slack Bot
   Loaded: loaded (/etc/systemd/system/rund.service; disabled; vendor preset: disabled)
   Active: active (running) since 木 2018-11-15 20:57:16 JST; 1s ago
 Main PID: 2026 (python)
   CGroup: /system.slice/rund.service
           └─2026 python /home/macan/slackbot/run.py

となっていれば起動成功です

起動エラー

[root@localhost ~]# systemctl status rund
● rund.service - Python Slack Bot
Loaded: loaded (/etc/systemd/system/rund.service; disabled; vendor preset: disabled)
Active: failed (Result: start-limit) since 木 2018-11-15 20:56:53 JST; 6s ago
Process: 2017 ExecStart=/home/macan/slackbot/run.py (code=exited, status=203/EXEC)
Main PID: 2017 (code=exited, status=203/EXEC)

のように、code=exited, status=203/EXECが出たときはログをみます

ログの確認

[root@localhost ~]# cat  /var/log/messages

Nov 15 18:28:58 localhost systemd: Unit rund.service entered failed state.
Nov 15 18:28:58 localhost systemd: rund.service failed.
Nov 15 18:28:58 localhost systemd: rund.service holdoff time over, scheduling restart.
Nov 15 18:28:58 localhost systemd: Started Python Slack Bot.
Nov 15 18:28:58 localhost systemd: Starting Python Slack Bot...
Nov 15 18:28:58 localhost systemd: Failed at step EXEC spawning /home/macan/slackbot/run.py: Exec format error
Nov 15 18:28:58 localhost systemd: rund.service: main process exited, code=exited, status=203/EXEC

Failed at step EXEC spawning /home/macan/slackbot/run.py: Exec format errorとでてました。ものこれがでたかたは1行目にPythonの宣言コードがあるか確認してください

#!/usr/local/pyenv/shims/python

がないと駄目です。Pythonのリンクの確認は

[macan@localhost ~]$ which python
/usr/local/pyenv/shims/python

ででます。