VPSでPythonを常時実行する方法|systemdで自動起動・再起動

Ubuntu VPSでPythonをsystemdサービスとして常時実行し、自動起動、再起動、ログ、更新、停止まで安全に管理する方法を解説します。
SSH画面でpython app.pyを実行しただけでは、通信切断やVPS再起動でプログラムが止まります。Ubuntuではsystemdへサービスとして登録すると、バックグラウンド実行、自動起動、異常終了時の再起動、ログ確認を一元管理できます。
本記事では、一般ユーザーのアプリをsystemdで動かす基本構成を扱います。自動売買や資金に関わる処理では、再実行による二重注文を防ぐ設計と監視を別途用意してください。
常時実行の方法を比較
| 方法 | 向く用途 | 注意点 |
|---|---|---|
| systemd | 本番の常駐アプリ・API・ワーカー | unitファイルの理解が必要 |
| cron | 決まった時刻の短い処理 | 常時プロセスの監視には不向き |
| tmux・screen | 手動検証、長い一時作業 | 自動復旧と状態管理が弱い |
| Docker | 環境をまとめて配布 | コンテナ運用の知識が必要 |
初心者が単一VPSで常駐させるなら、まずsystemdを覚えると応用しやすくなります。
1. 専用ユーザーと配置先を準備する
既存の管理ユーザーで動かす例として、アプリを/opt/myappへ配置します。本番ではアプリ専用ユーザーを作り、必要なファイルだけ読める権限にします。
sudo mkdir -p /opt/myapp
sudo chown -R appuser:appuser /opt/myapprootでPythonアプリを動かさず、特権ポートの公開はNginxへ任せます。
2. 仮想環境を作る
cd /opt/myapp
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtrequirements.txtやロックファイルで依存バージョンを管理します。手元とVPSでPythonバージョンが違わないか確認してください。
3. 手動で正常動作を確認する
systemdへ登録する前に、対象ユーザー、対象ディレクトリ、仮想環境のPythonで動かします。
cd /opt/myapp
/opt/myapp/.venv/bin/python /opt/myapp/app.py相対パス、書き込み先、ネットワーク、環境変数を確認します。手動で動かないプログラムはsystemdへ登録しても直りません。
4. systemdのunitファイルを作る
/etc/systemd/system/myapp.serviceを作成します。
[Unit]
Description=My Python Application
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=appuser
Group=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/.venv/bin/python /opt/myapp/app.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetRestart=alwaysは正常終了後も再実行します。バッチが完了する設計では無限再実行になるため、プログラムの性質に合わせて選びます。
5. サービスを有効化する
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myappVPSを再起動し、自動起動することも確認します。
sudo reboot再接続後にsystemctl status myappとアプリの実動作を確認してください。
6. ログを確認する
標準出力と標準エラーはjournaldで確認できます。
sudo journalctl -u myapp -n 100 --no-pager
sudo journalctl -u myapp -fログへAPIキー、アクセストークン、個人情報を出力しないようにします。長期運用ではログ容量と保存期間も監視します。
7. 環境変数と秘密情報を渡す
秘密情報をunitファイルやGitHubへ直接書かず、rootだけが読める環境ファイルや秘密管理サービスを使います。
EnvironmentFile=/etc/myapp/myapp.envsudo chown root:appuser /etc/myapp/myapp.env
sudo chmod 640 /etc/myapp/myapp.env秘密情報を変更したら、daemon-reloadではなくサービス再起動が必要か確認します。
8. アプリを安全に更新する
- バックアップまたはリリース単位の配置先を作る
- 新しい仮想環境で依存をインストールする
- テストを実行する
- サービスを切り替える
- ログとヘルスチェックを確認する
- 問題時に以前の版へ戻す
稼働中ファイルを直接上書きすると、中途半端な状態を読み込むことがあります。短時間停止できないAPIでは、複数プロセスやロードバランサーを検討します。
9. Web APIはNginxと組み合わせる
FlaskやDjangoの開発サーバーをそのまま外部公開せず、GunicornやUvicornなど用途に合う実行サーバーをsystemdで管理し、Nginxから127.0.0.1へ転送します。TLSと外部ポートはNginx側で管理します。
よくあるエラー
status=203/EXEC
ExecStartのパスが存在しない、実行権限がない可能性があります。仮想環境のPythonとスクリプトを絶対パスで指定します。
ModuleNotFoundError
systemdが別のPythonを使っている可能性があります。ExecStartが.venv/bin/pythonを指しているか、対象ユーザーで依存が入っているか確認します。
手動では動くがsystemdでは失敗する
作業ディレクトリ、環境変数、ファイル権限、PATHの違いを確認します。シェルの設定ファイルが自動で読み込まれるとは限りません。
監視で確認する項目
- サービスがactiveか
- 最終処理時刻が更新されているか
- 再起動回数が増えていないか
- CPU・メモリ・ディスクが逼迫していないか
- 外部APIの失敗率が上がっていないか
- 定期バックアップが成功しているか
プロセスが起動中でも処理が停止していることがあります。単なるプロセス監視に加え、業務上の結果を監視します。
まとめ
Pythonの常時実行は、仮想環境で手動確認した後、systemdへ専用ユーザー・絶対パス・再起動方針を登録します。再起動試験、ログ、秘密管理、監視まで揃えて運用を始めましょう。Web公開はNginxの設定方法も参照してください。