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)
  • MemoryMaxCPUQuota などで簡単にリソース制御
  • 依存関係管理
  • 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 ベースで稼働
  • 運用チームが systemctljournalctlrsysloglogrotate などに精通

Dockerという新しいレイヤーを追加するより、既存運用スタック上にウェブアプリを自然に乗せる 方が効率的です。

4-3. 規制が強い、または Docker 使用が制限された環境

前述のように:

  • 金融・公共・国防・医療
  • 閉鎖ネットワーク/内部ネットワーク
  • コンテナセキュリティ評価/認証手続きが面倒

Docker導入自体がプロジェクトリスクになる場合があります。こうしたケースでは:

  • OSパッケージ / ランタイムをインストール
  • コードをデプロイ
  • systemdサービスを登録

という検証済みパターンが最も現実的です。

4-4. デバッグ/性能分析時にホストとの距離を縮めたいとき

  • 直接 straceperf/proc を覗き込みながらチューニングしたい
  • ネットワーク/ファイルシステム/リソース問題を一度に確認したい

この場合、コンテナをもう一層重ねるより、ホストプロセスとして稼働するウェブアプリを直接分析 した方が楽です。


5. もちろん、Dockerがより適した状況もある

ここまでsystemdデプロイのメリットを語りましたが、Dockerのメリットも明確です。

  • イメージでビルド → どこでも同じ環境
  • ローカル/ステージング/プロダクション環境の差を減らす
  • CI/CDパイプラインとの自然な統合
  • マルチサービス(ウェブ + ワーカー + クロン + DB など)構成

複数サーバ/環境に同じアプリケーションスタックを繰り返しデプロイ したい、 チーム内で環境差が大きい 場合は Docker がより良い選択になる可能性が高いです。

結局重要なのは:

"私たちのサービス規模、チーム構成、インフラ環境で どのツールが よりシンプルで、より安定し、運用が楽 か?"

という基準で選択することです。


image

6. まとめ:ツールより "状況" が先に来る

Linuxでウェブアプリケーションをデプロイする際、 "必ず Docker" でもなく、"Dockerは悪くて systemd が良い" でもありません。

  • 単一サービス、単純インフラ、規制が強い環境 → systemd.service デプロイ がより現実的
  • マルチサービス、さまざまな環境、頻繁なデプロイ/スケーリング → Dockerベースデプロイ がより価値を提供

Linuxサーバを使っているなら、一度は:

  • "このサービスは Docker が必須か?"
  • "systemd で上げると逆にシンプルになるか?"

と真剣に考えてみる価値があります。ツールは目的を達成する手段に過ぎず、シンプルさと運用のしやすさ が長期的に最大の生産性を生み出します。