DjangoとGunicorn / Uvicornを使用する非常にシンプルなWebサービスがあります。
foo.service
[Unit]
Description=Foo service
Requires=foo.socket
After=network.target
[Service]
User=foo
Group=www-data
Restart=on-failure
WorkingDirectory=/var/lib/foo/current/backend
ExecStart=/var/lib/foo/.local/bin/poetry run gunicorn \
--env DJANGO_SETTINGS_MODULE=foo.settings \
--capture-output \
--log-level info \
--bind unix:/run/foo.sock \
--worker-class uvicorn.workers.UvicornWorker \
--workers 4 \
foo.asgi:application
[Install]
WantedBy=multi-user.target
foo.socket
[Unit]
Description=Foo socket
[Socket]
ListenStream=/run/foo.sock
[Install]
WantedBy=sockets.target
サービスを有効にして開始しました。アプリケーションを再デプロイするときにアプリケーションをオフラインにしておく必要がありますが、データベースを移行して他のタスクを実行します。しかし、私が発行したとき:
sudo systemctl restart foo.service
このメッセージを受け取りました
Warning: Stopping foo.service, but it can still be activated by:
foo.socket
ソケットを再起動する必要がありますか?サービスを無効にしてソケットのみを有効にしますか? (このソケットはnginxで使用されます。)ここで最良の方法は何ですか?データベースを移行するときにソケットを介してサービスを有効にしたくありません。
答え1
これには3つのオプションがあります。
- 両方のデバイスを一緒に起動/停止します。これを行う必要があることを覚えておく必要があるため、これは最善の解決策ではありません。
sudo systemctl stop foo.{service,socket}
- 管理サービスのみ可能です。これには次のものが必要です。
[Install]
ソケット部分を下ろします。サービスはすでにRequires=
ソケットなので、これは必要ありません。サービスが起動すると、ソケットも起動します。PartOf=foo.service
ソケットセクションに追加されました[Unit]
。これは、停止または再起動時にfoo.service
コマンドがソケットに伝播されることを意味します。
# foo.service
[Unit]
Requires=foo.socket
After=network.target
[Service]
...
[Install]
WantedBy=multi-user.target
#foo.socket
[Unit]
PartOf=foo.service
[Socket]
ListenStream=/run/foo.sock
これで可能で、sudo systemctl {restart,stop,start} foo.service
ソケットは常に同期されます。
- ソケットのみを管理します。データがソケットに到着したときにのみサービスが実行されるため、このオプションをお勧めします。これを行うには:
Requires=
サービスから削除されました。サービスを直接起動しないので、これは必要ありません。[Install]
サービスからこの部分を削除してください。代わりにソケットを使用します。PartOf=foo.socket
サービスセクションに追加されました[Unit]
。アプリケーションがEOF
stdin または stdout で終了する場合、これは不要な場合があります。- サービスセクション
StandardInput=socket
に追加してください。[Service]
これは必ずしも必要ではありませんが、systemctl start foo.service
ソケットが起動しないと失敗します。
# foo.service
[Unit]
PartOf=foo.socket
After=network.target
[Service]
StandardInput=socket
...
#foo.socket
[Socket]
ListenStream=/run/foo.sock
[Install]
WantedBy=sockets.target