Compose の「systemd 管理外」問題と Quadlet が解決すること
docker-compose や podman-compose は開発環境での手軽さが魅力ですが、本番サーバーでそのまま使い続けるといくつかの問題が表面化します。最も典型的なのは「サーバー再起動後にコンテナが自動起動しない」というケースです。restart: always を compose ファイルに書いていても、compose デーモン自体が systemd で管理されていなければ意味がありません。
Podman 4.4 で安定リリースされた Quadlet は、このギャップを埋めるために設計された仕組みです。コンテナの定義を systemd ユニットファイル形式(.container 拡張子)で記述し、systemd のジェネレーター機構が自動的に通常の .service ファイルへ変換・管理します。結果として、コンテナのライフサイクル管理・自動再起動・依存関係制御をすべて systemd に統合できます。
Fedora 38 以降・RHEL 9.2 以降・Debian 12 以降では標準搭載されており、2026年時点では Podman 5.x 世代のディストリビューションで広く利用できます。
Quadlet の基本構造と動作原理
Quadlet のユニットファイルは、次の2つのディレクトリに配置します。
- システムサービス(root):
/etc/containers/systemd/ - ユーザーサービス(rootless):
~/.config/containers/systemd/
ファイルを配置した後に systemctl daemon-reload(rootless の場合は systemctl --user daemon-reload)を実行すると、podman-system-generator(または podman-user-generator)が動作して通常の .service ファイルを生成します。その後は systemctl start や systemctl enable で他のサービスと同様に操作できます。
拡張子と用途の対応は以下のとおりです。
.container:コンテナ本体の定義.volume:Podman ボリュームの定義.network:カスタムネットワークの定義.pod:Pod(複数コンテナのグループ)の定義.kube:Kubernetes YAML をそのまま起動する定義
Compose 定義を Quadlet ユニットファイルへ変換する手順
想定例として、次のような単純な compose 構成を移行します(架空のサービス構成です)。
# compose.yml(想定例)
services:
web:
image: docker.io/library/nginx:1.27
ports:
- "8080:80"
environment:
- APP_ENV=production
volumes:
- web-data:/usr/share/nginx/html
restart: always
volumes:
web-data:
これを Quadlet に変換するには、まずボリューム定義ファイルを作成します。
# /etc/containers/systemd/web-data.volume
[Volume]
Label=app=web
次にコンテナ定義ファイルを作成します。
# /etc/containers/systemd/web.container
[Unit]
Description=Nginx Web Container
After=network-online.target
[Container]
Image=docker.io/library/nginx:1.27
PublishPort=8080:80
Environment=APP_ENV=production
Volume=web-data.volume:/usr/share/nginx/html
[Service]
Restart=always
TimeoutStartSec=300
[Install]
WantedBy=multi-user.target
Volume= に web-data.volume と記述することで、同じディレクトリにある web-data.volume ファイルへの依存が自動的に解決されます。これが Quadlet の重要な設計で、ファイル名とサービス依存が一対一に対応します。
手動変換の手間を省きたい場合は、コミュニティツール podlet(containers/podlet)が compose ファイルを Quadlet ユニットファイルへ自動変換する機能を持っています。2024年時点で Rust 製の安定版がリリースされており、次のように使用できます。
podlet compose compose.yml
出力されたファイルを確認・調整した上でシステムディレクトリへ配置します。自動変換の結果をそのまま本番投入するのではなく、必ず内容をレビューする習慣をつけてください。
本番環境で考慮すべき設計ポイント
シークレット管理
compose ファイルでは環境変数に直接パスワードを書くケースがありますが、Quadlet では Secret= ディレクティブで Podman のシークレット機能と連携できます。事前に podman secret create でシークレットを登録しておき、コンテナ内からは /run/secrets/ 以下のファイルとして参照します。
[Container]
Secret=db-password,type=mount,target=/run/secrets/db_password
ネットワーク分離
複数コンテナが通信する構成では .network ファイルを用意して明示的にネットワークを定義します。Network=myapp.network と記述するだけで、各コンテナが同一ネットワークに参加し、コンテナ名で名前解決できるようになります。
起動順序の制御
compose の depends_on に相当する制御は [Unit] セクションの After= と Requires= で記述します。たとえばアプリコンテナがデータベースコンテナの後に起動すべき場合は次のように書きます。
[Unit]
After=db.service
Requires=db.service
Quadlet が生成するサービス名はファイル名から決まるため(db.container → db.service)、依存先のファイル名と合わせておく必要があります。
イメージ更新の自動化
Podman には podman auto-update コマンドがあり、io.containers.autoupdate=registry ラベルを付けたコンテナのイメージを定期的に確認・更新できます。systemd タイマーと組み合わせることで compose における watchtower 相当の機能を標準機能だけで実現できます。
動作検証と起動確認
ファイルを配置したら次の手順で検証します。
# ジェネレーターを再実行してユニットファイルを生成
systemctl daemon-reload
# 生成されたユニットファイルの内容を確認
systemctl cat web.service
# 起動テスト
systemctl start web.service
# 状態確認
systemctl status web.service
# ログ確認
journalctl -u web.service -f
systemctl cat web.service を実行すると Quadlet が生成した実際のユニットファイルの内容が表示されます。想定どおりの ExecStart が生成されているか、依存関係が正しく設定されているかをここで確認します。
また、podman ps でコンテナが実際に稼働しているか、podman inspect でマウントポイントやネットワーク設定が意図どおりか確認します。自動起動設定は systemctl enable web.service で有効化してから systemctl reboot(またはテスト環境での再起動)で検証するのが確実です。
ロールバック手順と切り戻し設計
Quadlet への移行後に問題が発生した場合の切り戻しは、compose 時代より明確に手順を整理できます。
Quadlet から compose への切り戻し
# 1. Quadlet サービスを停止・無効化
systemctl stop web.service
systemctl disable web.service
# 2. Quadlet ファイルを退避(削除ではなく移動)
mv /etc/containers/systemd/web.container /etc/containers/systemd/web.container.bak
mv /etc/containers/systemd/web-data.volume /etc/containers/systemd/web-data.volume.bak
# 3. ジェネレーターを再実行
systemctl daemon-reload
# 4. compose で再起動
podman-compose -f /path/to/compose.yml up -d
ロールバックを確実に行うために、移行前に旧 compose ファイルをバージョン管理下に残しておくことが重要です。また、Quadlet ファイル自体も Git 管理することで、設定変更の履歴管理と差分レビューが可能になります。
よくあるつまずきと注意点
一般的によく見られるつまずきとして、daemon-reload を忘れたためにユニットファイルが古いまま起動してしまうケースがあります。Quadlet ファイルを変更するたびに daemon-reload が必要な点は compose との大きな違いです。
また、rootless コンテナ(ユーザースペース)では systemctl --user と loginctl enable-linger の組み合わせが必要です。enable-linger を忘れると、ログアウト後にユーザーサービスが停止してしまいます。
# rootless 運用時のみ必要
loginctl enable-linger $USER
さらに、Podman 5.x(2024年リリース)から .pod ファイルのサポートが強化されています。複数コンテナを同一 Pod にまとめる構成は、Compose の network_mode: service: に近いユースケースに対応します。RHEL 10・Fedora 41 以降では Podman 5.x がデフォルトになっているため、利用環境に応じて Podman のバージョンと機能差異を確認してください。
Quadlet は compose の「手軽さ」と systemd の「堅牢さ」を両立するアプローチです。移行コストは主にユニットファイルの書き換えに集中しており、一度整備すれば運用の透明性・再起動耐性・ログ管理のすべてが systemd エコシステムに乗ります。段階的な移行(新規サービスから順に Quadlet 化する)も十分現実的な選択肢です。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
PR・広告
[試して理解]Linuxのしくみ 増補改訂版(Amazon)
プロセス・権限・ファイルシステムなどLinux内部を図解で理解できる一冊。運用判断の勘所に。
※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。
