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

ででます。

Jun 26 23:26:13 v157-7-52-193 systemd: Failed at step EXEC spawning /home/centos/slackbot/run.py: Permission denied
Jun 26 23:26:13 v157-7-52-193 systemd: rund.service: main process exited, code=exited, status=203/EXEC
Jun 26 23:26:13 v157-7-52-193 systemd: Unit rund.service entered failed state.
Jun 26 23:26:13 v157-7-52-193 systemd: rund.service failed.

が出た場合はパーミッションエラーの可能性が高いです。755か確認しましょう

Jun 26 23:31:55 v157-7-52-193 systemd: Failed at step EXEC spawning /home/centos/slackbot/run.py: No such file or directory
Jun 26 23:31:55 v157-7-52-193 systemd: rund.service: main process exited, code=exited, status=203/EXEC
Jun 26 23:31:55 v157-7-52-193 systemd: Unit rund.service entered failed state.
Jun 26 23:31:55 v157-7-52-193 systemd: rund.service failed.
Jun 26 23:31:56 v157-7-52-193 systemd: rund.service holdoff time over, scheduling restart.
Jun 26 23:31:56 v157-7-52-193 systemd: Stopped Python Slack Bot.
Jun 26 23:31:56 v157-7-52-193 systemd: start request repeated too quickly for rund.service
Jun 26 23:31:56 v157-7-52-193 systemd: Failed to start Python Slack Bot.
Jun 26 23:31:56 v157-7-52-193 systemd: Unit rund.service entered failed state.
Jun 26 23:31:56 v157-7-52-193 systemd: rund.service failed.

のエラーが出た場合は、改行コードが\r\nで保存されてしまったため、Linuxの\nに直す必要がある。かもしれません
訂正コマンドは以下になります

sed -i 's/\r//' <対象のファイル>

参考サイト:http://totech.hateblo.jp/entry/2014/03/19/174129

個人支援・寄付について

サイトラボでは個人支援・寄付を受けております。ご協力いただける方はお願いいたします。当サイトではビットコインで受け付けております。

  • ビットコイン:3LHnADwZwUbic2L45EnVJEykiG6KfbqrwS