あらすじ
あるとき、FastAPI (Python) で WebApp を作りました。
で、その WebApp を裏で常に稼働し続ける、みたいなのができないかなと考えました。
そこで気がついたのが systemd。よく Apache とか Samba を systemctl
ってコマンドで起動したり停止したりするアレ。
そんなアレに自作のサービスを追加できないか、ということで試行錯誤したので、その日記をここに記すことにしました。
実際に作成してから半年近く経っての記事書きというのは内緒
やりたいこと
- 特定の Python ソースを venv 上で動かしたい
- Python ソースは
/opt/mozjpeg-webui/main.py
に設置 - 仮想環境 venv も同ディレクトリに作成
- Python ソースは
- 稼働を
systemctl
で制御したい - 自動起動も設定したい
下準備: Python 仮想環境構築・ソース配置
# すべてスーパーユーザ権限で
mkdir /opt/mozjpeg-webui
python3 -m venv /opt/mozjpeg-webui/.venv
/opt/mozjpeg-webui/bin/pip install -r /src-dir/requirements.txt
cp src-dir/* /opt/mozjpeg-webui/
Python 仮想環境というと、source ./bin/activate
で仮想環境入り、というのをよく見かけると思います。ただ、少量のコマンド実行だったら同じ bin
ディレクトリ内の pip
を直接起動してやった方が早いので、そうしています。
完成品
とりあえずこんな形で動きました。
[Unit]
Description=mozjpeg web application
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/mozjpeg-webui/
ExecStart=/opt/mozjpeg-webui/.venv/bin/python /opt/mozjpeg-webui/main.py
[Install]
WantedBy=multi-user.target
あとは作った .service
を /etc/systemd/system/
に置けば OK。
以下、各設定を適当に解説。(あまり正確じゃないかも)
After
このサービスが起きてからこれ (自分) を起こす、という依存関係設定。
(しっかり理解できていませんが、) ネットワークが動いてからじゃないとダメそうな気がするので After=network.target
としています。
WorkingDirecory
どこをカレントとして ExecStart=
のコマンドを実行するか設定。
WebApp サーバで、外部ファイル (HTML, CSS, JS とか) 読み込みを伴う上で、カレントが main.py
の位置でないといけないです。最初、これにちょっとハマりました。
WantedBy
OS 起動後、このターゲットに紐付いて起動、という設定。
これが無いと、自動起動設定 (enable/disable) が設定できません。
軽く調べると、多くのターゲットが multi-user.target
に紐付いているとか。とりあえず、適当に「OS 起動後でユーザログイン無しでも起動」なら、これでいいのかも。
他
-
Description
: サービス一覧などに表示する説明 -
Type
: どういった動作のさせ方なのかの設定, 詳細省略 -
ExecStart
: サービス起動時に実行するコマンド
あとがき
ExecStart
とかは分かりやすいのですが、正直 After
とか WantedBy
とかが良く分かっていません。よく仕組みを理解する必要がありそうです。
でも、とりあえず適当に動かすなら上の通りでもよさそう・・・かも。
参考