【Docker】uWsgi+Flaskを使ってBackendをデーモン起動させる【systemctl】

前書き

前回の記事(Nginx+uWsgi+Flask)を自動起動してくれるようにします。

サービス起動デーモン化

Dockerを使用している場合、コンテナ起動時に--privileged (特権モード)とcommandに"/sbin/init"を追加しないと、
コンテナ起動時にsystemdにPID1が割り当てられない可能性があります。

qiita.com


systemctlを使ってuwsgi.iniファイルをサービスとして起動させます。
その為にsystemd/systemに以下の設定ファイルを作成します。
/usr/local/bin/uwsgiは"which uwsgi"とコマンドを実行した際に表示されるパスで結構です。

/etc/systemd/system/uwsgi.service

[Unit]
Description = uWSGI
After = syslog.target

[Service]
ExecStart = /usr/local/bin/uwsgi --ini /var/www/server/uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

systemctlでコマンドを実行します。

# systemctl status uwsgi
# systemctl start uwsgi
● uwsgi.service - uWSGI
   Loaded: loaded (/etc/systemd/system/uwsgi.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-01-12 03:33:07 UTC; 7s ago
 Main PID: 289 (uwsgi)
   Status: "uWSGI is ready"
    Tasks: 3 (limit: 2225)
   Memory: 18.5M

おっしゃ!起動したで〜
なおまだプログラム自体は動作しません。

エラー

いわゆるscrapingというモジュールが存在しないとのエラーです。
一見するとFlask関連のエラー出ないかと疑うが、そんなアホな。

Jan 08 08:56:06 4520ac1c5359 uwsgi[83]: ModuleNotFoundError: No module named 'scraping'


Docker環境で直接python main.pyを叩いた時は正常に動作しました。
おそらく考えられるのは、systemd経由でuwsgi.iniを実行した時にmodulesをmain.pyのみしかロードしていないとか?

よくよく調べてみると、プロジェクトフォルダの指定ができていなかったようで、この場合はchdirオプションで指定します。
uwsgi-docs.readthedocs.io

[uwsgi]
module = main
callable = app
master = true
http = :5000
chmod-socket = 666
chdir = /var/www/server ⬅︎こいつが欠落していた
wsgi-file = /var/www/server/main.py
py-autoreload = 0

正直セキュリティ関連はガバガバ(privilegedで起動させたりしてる、uid・pidの指定、Permission関連)なので追々。