Dockerではなくsystemd.service?Linuxでのウェブアプリケーションデプロイ戦略を再考する
近年、"デプロイ=Docker + コンテナオーケストレーション(Kubernetes、ECSなど)"という公式がほぼ常識化しています。そのため、Linuxサーバにウェブアプリケーションを単に プロセス + systemdサービス で起動する手法は、古臭いと感じられることもあります。
しかし実際には、次のようなケースで systemdサービスでデプロイする方がシンプルで安定し、運用にやさしい 選択肢となることが多いです。
- 単一のウェブアプリケーション
- 小規模チーム/単純インフラ
- オンプレミスや規制が強い環境
この記事では、Linuxの systemd.service でウェブアプリケーションをデプロイする際に Dockerに比べてどんなメリットがあるか、そして どのような状況でsystemdベースのデプロイがより有効か を整理します。
1. systemdとDockerを簡単に押さえる
まず概念を非常に短くまとめると:
- Docker
- アプリケーションをイメージにパッケージ化し
- コンテナとして実行する技術
-
"環境をそのままカプセル化 → どこでも同じように実行" が強み
-
systemd
- 現代Linuxディストリビューションのデフォルトinitシステム
- 起動時にサービス(デーモン)を立ち上げ、停止したら再起動し、ログを管理する役割
*.serviceユニットファイルでプロセスを定義・管理
Dockerは アプリケーション環境をカプセル化するツール であり、systemdは Linuxでプロセスを管理するツール です。
両者は競合関係というより、むしろ "Dockerコンテナ 内で systemdを使う"、"Dockerデーモン自体をsystemdが管理する" など、共存するケースが多いです。
しかしここでは "ウェブアプリケーションをデプロイする際、Dockerを使わずにsystemdだけで運用するケース" に焦点を当てます。
2. Dockerではなくsystemd.serviceデプロイのメリット
2-1. シンプルさ:レイヤーが一段落減る
Dockerを使うと、運用スタックに次のような要素が追加されます。
- Dockerデーモン
- イメージビルドパイプライン
- イメージレジストリ(Registry)
- コンテナランタイムの権限/権限管理
対して、systemdベースのデプロイは:
- OSに必要なランタイム(Python/Node/Javaなど)をインストールし
- アプリケーションコードをデプロイし
- systemdサービスとして登録して実行
という 相対的にシンプルな構造 です。
小規模プロジェクトや内部サービスでは:
- "イメージビルド → プッシュ → プル → 再デプロイ" のプロセスがむしろ負担になることもあり
- サーバにSSHで
git pull+systemctl restartだけで済む方が速く直感的です。
2-2. Linuxとの自然な統合
systemdはLinuxの "窓口" のような存在で、OSレベルの機能と非常に親和性があります。
- ログ
journalctl -u myapp.serviceでサービスログを即座に確認- 起動自動実行
systemctl enable myapp.serviceで起動時に自動開始- リソース制限(cgroup)
MemoryMax、CPUQuotaなどで簡単にリソース制御- 依存関係管理
After=network.target/After=postgresql.serviceなどでサービス間の順序制御
Dockerでサービスを起動すると:
- コンテナ内外のログ/リソース/ネットワークを分けて見る必要がある
- 問題が起きたときに "コンテナ問題かホスト問題か" を分けて考える必要がある
単一・少数のウェブサービスを運用する場合、運用・デバッグ観点では systemd直結構造がより直感的 です。
2-3. リソースオーバーヘッドが少ない
Docker自体のオーバーヘッドは大きくありませんが、実際には次のような追加負担が伴います。
- 複数イメージ/レイヤーが蓄積しディスク使用量が増える
- 不要に起動しているコンテナが残る
- コンテナごとのログ/ボリューム管理
systemdベースのデプロイは:
- OS + ランタイム + アプリケーションコード程度で済む
- 特にディスク/メモリリソースがタイトな環境ではよりシンプルです。
小規模VMを複数運用したり、組み込み/低スペックサーバにデプロイする場合、systemdはより軽量に感じられます。
2-4. ネットワーク構造が直感的
Dockerコンテナを使うと、基本的に次を理解する必要があります。
- コンテナ内部IPとポート
- ホストとのポートマッピング
- ブリッジネットワーク / オーバレイネットワーク
対してsystemdサービスは:
- ホストのIP/ポートに直接バインド
- ファイアウォールルールもホスト基準で設定
そのため、基本的なネットワークデバッグがより単純 です。
- "このポートが開いているか?"
- "ファイアウォールで遮断されていないか?"
- "同一サーバの他サービスと衝突していないか?"
など、コンテナネットワークというレイヤーが減ることで効果があります。
2-5. 特定環境ではDockerが使えない
実際に頻繁に起こるケースです。
- 金融・公共・医療など規制が強いオンプレミス環境
- 運用ポリシー上 "コンテナランタイム禁止"
- インターネットが制限されており外部レジストリ使用が難しい
こうした場合、選択肢は "OS + systemd" しかありません。 この時、systemdをよく理解していれば、Dockerなしでも十分に:
- 自動再起動
- ログ管理
- リソース制限
- ヘルスチェック(間接的に)
を実装できます。
3. systemd.service例:ウェブアプリケーションデプロイ
簡単な例として、gunicorn で Django/Flask アプリをサービスすると仮定します。
3-1. ユニットファイル例
/etc/systemd/system/myapp.service:
[Unit]
Description=My Web Application (Gunicorn)
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/srv/myapp
EnvironmentFile=/etc/myapp.env
ExecStart=/usr/bin/gunicorn \
--workers 4 \
--bind 0.0.0.0:8000 \
config.wsgi:application
# プロセスが死んだら自動再起動
Restart=on-failure
RestartSec=5
# リソース制限例(任意)
# MemoryMax=512M
# CPUQuota=50%
[Install]
WantedBy=multi-user.target
環境変数は /etc/myapp.env のように分離します。
DJANGO_SETTINGS_MODULE=config.settings.prod
SECRET_KEY=super-secret-key
DATABASE_URL=postgres://...
その後のコマンドは非常にシンプルです。
# サービス登録 & 起動時自動実行
sudo systemctl enable myapp.service
# 起動 / 停止 / 再起動
sudo systemctl start myapp.service
sudo systemctl restart myapp.service
sudo systemctl stop myapp.service
# 状態 / ログ確認
sudo systemctl status myapp.service
sudo journalctl -u myapp.service -f
Linuxサーバに慣れた運用チームなら、追加の学習曲線なしで即運用可能です。
4. いつsystemdデプロイがDockerより優れるか?
まとめると、次のような状況では Dockerではなくsystemdデプロイを積極的に検討 すべきです。
4-1. 単一/小規模サービス、複雑なオーケストレーションが不要なとき
- ウェブアプリケーション 1〜2個
- DBは RDS などマネージドサービスを利用
- デプロイ対象サーバ数が多くない(例:1〜5台程度)
このようなケースでは:
- Docker + オーケストレーション導入コストが実際のメリットを上回る可能性がある
- systemd + 簡単なデプロイスクリプト(Ansible、Fabric など)で十分な場合が多い
4-2. 運用チーム/インフラチームが "Linuxサーバ + サービス" に慣れている組織
- 既存システムがほとんど
systemdベースで稼働 - 運用チームが
systemctl、journalctl、rsyslog、logrotateなどに精通
Dockerという新しいレイヤーを追加するより、既存運用スタック上にウェブアプリを自然に乗せる 方が効率的です。
4-3. 規制が強い、または Docker 使用が制限された環境
前述のように:
- 金融・公共・国防・医療
- 閉鎖ネットワーク/内部ネットワーク
- コンテナセキュリティ評価/認証手続きが面倒
Docker導入自体がプロジェクトリスクになる場合があります。こうしたケースでは:
- OSパッケージ / ランタイムをインストール
- コードをデプロイ
- systemdサービスを登録
という検証済みパターンが最も現実的です。
4-4. デバッグ/性能分析時にホストとの距離を縮めたいとき
- 直接
strace、perf、/procを覗き込みながらチューニングしたい - ネットワーク/ファイルシステム/リソース問題を一度に確認したい
この場合、コンテナをもう一層重ねるより、ホストプロセスとして稼働するウェブアプリを直接分析 した方が楽です。
5. もちろん、Dockerがより適した状況もある
ここまでsystemdデプロイのメリットを語りましたが、Dockerのメリットも明確です。
- イメージでビルド → どこでも同じ環境
- ローカル/ステージング/プロダクション環境の差を減らす
- CI/CDパイプラインとの自然な統合
- マルチサービス(ウェブ + ワーカー + クロン + DB など)構成
複数サーバ/環境に同じアプリケーションスタックを繰り返しデプロイ したい、 チーム内で環境差が大きい 場合は Docker がより良い選択になる可能性が高いです。
結局重要なのは:
"私たちのサービス規模、チーム構成、インフラ環境で どのツールが よりシンプルで、より安定し、運用が楽 か?"
という基準で選択することです。

6. まとめ:ツールより "状況" が先に来る
Linuxでウェブアプリケーションをデプロイする際、 "必ず Docker" でもなく、"Dockerは悪くて systemd が良い" でもありません。
- 単一サービス、単純インフラ、規制が強い環境 → systemd.service デプロイ がより現実的
- マルチサービス、さまざまな環境、頻繁なデプロイ/スケーリング → Dockerベースデプロイ がより価値を提供
Linuxサーバを使っているなら、一度は:
- "このサービスは Docker が必須か?"
- "systemd で上げると逆にシンプルになるか?"
と真剣に考えてみる価値があります。ツールは目的を達成する手段に過ぎず、シンプルさと運用のしやすさ が長期的に最大の生産性を生み出します。
コメントはありません。