Webサーバーやデータベースは「起動したら動き続ける」ものです。docker run -it nginx で起動するとターミナルが nginx に占領され、Ctrl+C を押せばサービスが止まってしまいます。本番や開発での実用シーンでは -d(--detach)でコンテナをバックグラウンドで動かすのが基本パターンです。
この記事では -d の動作原理から、ログ確認・リソース監視・停止管理まで体系的に解説します。
目次
- なぜバックグラウンド実行が必要か
- -d の仕組み:Dockerデーモンに委譲する
- docker run -d の基本
- コンテナIDの活用
- 状態確認:docker ps / docker inspect
- ログ確認:docker logs
- リソース監視:docker stats / docker top
- 接続し直す:docker attach / docker exec -it
- 停止・再起動:docker stop / docker restart
- 複数コンテナをバックグラウンドで管理する
- 本番パターン:–restart と組み合わせる
- シミュレータで練習する
- まとめ
1. なぜバックグラウンド実行が必要か
コンテナをフォアグラウンドで起動した場合(-d なし)、コンテナのプロセスがターミナルを占有します。
# フォアグラウンド起動(ターミナルが占領される)
docker run nginx
# → nginx のアクセスログが流れ続ける
# → Ctrl+C を押すと SIGINT が送られ nginx が停止する
# → このターミナルでは他のコマンドが打てない
Webサーバー・データベース・メッセージキューといった常駐サービスはターミナルとは独立して動き続ける必要があります。
| 起動方法 | ターミナルの状態 | Ctrl+C の影響 | 適した用途 |
|---|---|---|---|
| フォアグラウンド(デフォルト) | 占有される | コンテナが停止する | 一時コマンド・デバッグ |
-d(デタッチ) |
すぐに返る | 影響なし | 常駐サービス・本番運用 |
2. -d の仕組み:Dockerデーモンに委譲する
-d(--detach)は「コンテナをDockerデーモン(dockerd)に引き渡し、ターミナルとの接続を切って制御を返す」オプションです。
デタッチしたコンテナの標準出力・標準エラー出力はDockerデーモンがすべて収集しています。後から docker logs で確認できるのはこのためです。
3. docker run -d の基本
docker run -d [その他オプション] イメージ名
# nginx をバックグラウンドで起動(ポート 8080 で公開)
docker run -d -p 8080:80 --name web nginx
# 出力: コンテナIDの完全形(64文字)が1行だけ返る
# a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890
# MySQL をバックグラウンドで起動
docker run -d \
--name db \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=myapp \
-p 3306:3306 \
mysql:8.0
# Redis をバックグラウンドで起動
docker run -d --name cache -p 6379:6379 redis:7
-d(デタッチ)と -it(インタラクティブ)は本質的に矛盾します。-d はターミナルとの接続を切り、-it はターミナルと接続します。両方指定すると -d が優先されるため -it は無効になります(Docker 20以降では警告が表示されます)。
4. コンテナIDの活用
docker run -d はコンテナIDを返します。このIDを変数に保存しておくと、後続のコマンドで便利に使えます。
# コンテナIDを変数に保存
CID=$(docker run -d nginx)
echo $CID
# a1b2c3d4e5f6...(64文字)
# 変数を使ってログ確認
docker logs $CID
# 変数を使って停止
docker stop $CID
# IDは先頭数文字で一意に識別できる(通常12文字で十分)
docker logs a1b2c3d4e5f6
docker stop a1b2
# --name を付けると ID ではなく名前で操作できる(推奨)
docker run -d --name web nginx
docker logs web
docker stop web
IDは再起動のたびに変わりますが、
--name で付けた名前は固定です。docker logs web・docker stop web・docker exec -it web bash のように、スクリプトや記憶に頼った操作が容易になります。
5. 状態確認:docker ps / docker inspect
docker ps で一覧確認
docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# a1b2c3d4e5f6 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp web
# f6e5d4c3b2a1 mysql:8.0 "docker-entrypoint.s…" 1 minute ago Up 1 minute 0.0.0.0:3306->3306/tcp db
STATUS 列の Up X minutes が running であることを示します。
docker inspect で詳細確認
# コンテナの全情報をJSON形式で確認
docker inspect web
# 特定の情報だけ取り出す
docker inspect --format='{{.State.Status}}' web
# running
docker inspect --format='{{.NetworkSettings.IPAddress}}' web
# 172.17.0.2
docker inspect --format='{{.Config.Image}}' web
# nginx
6. ログ確認:docker logs
デタッチしたコンテナのログは docker logs で確認します。コンテナのプロセスが stdout・stderr に出力した内容はすべてDockerデーモンが記録しています。
# ログをすべて表示
docker logs web
# リアルタイムで追跡(フォアグラウンドで見張る)
docker logs -f web
# 最後の50行のみ
docker logs --tail=50 web
# タイムスタンプ付きで最新100行をリアルタイム追跡
docker logs -ft --tail=100 web
# 時間範囲指定(過去1時間分)
docker logs --since=1h web
# 複数コンテナのログを同時に見る(ターミナルを複数開く)
# ターミナル1: docker logs -f web
# ターミナル2: docker logs -f db
デフォルトでは
json-file ドライバがログをホストディスクに蓄積し続けます。長期運用では --log-opt max-size=10m --log-opt max-file=3 でローテーションを設定するか、daemon.json でデフォルトを変更してください(第9章で詳しく解説)。
7. リソース監視:docker stats / docker top
# 実行中の全コンテナのリソース使用量をリアルタイム表示
docker stats
# CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
# a1b2c3d4e5f6 web 0.01% 6.734MiB / 15.55GiB 0.04% 1.2kB / 0B 0B / 0B
# f6e5d4c3b2a1 db 0.35% 382MiB / 15.55GiB 2.40% 5.6kB / 2.1kB 8.2MB / 12MB
# 特定コンテナのみ
docker stats web db
# 1回だけ取得してすぐ終了(スクリプト用)
docker stats --no-stream
# フォーマット指定
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# コンテナ内のプロセス一覧(top コマンドの docker 版)
docker top web
docker top web aux # ps aux 相当のオプションを渡せる
| docker stats の列 | 内容 |
|---|---|
| CPU % | ホストの全CPU対比でのCPU使用率 |
| MEM USAGE / LIMIT | 使用メモリ / 上限(–memory 未設定なら全メモリ) |
| MEM % | 上限に対するメモリ使用率 |
| NET I/O | ネットワーク受信 / 送信の累積量 |
| BLOCK I/O | ストレージ読み取り / 書き込みの累積量 |
| PIDS | コンテナ内の総プロセス数 |
8. 接続し直す:docker attach / docker exec -it
デタッチしたコンテナの中に入りたい場合は2つの方法があります。
方法1:docker exec -it(推奨)
# 実行中のコンテナに新しいシェルで接続
docker exec -it web bash
# コンテナ内で作業...
root@a1b2c3:/# nginx -t # 設定テスト
root@a1b2c3:/# cat /etc/nginx/nginx.conf
# exit してもコンテナは継続(PID 1 の nginx とは別プロセス)
root@a1b2c3:/# exit
# → web コンテナはまだ running
方法2:docker attach(注意が必要)
# PID 1 の stdout/stdin に直接接続する
docker attach web
# nginx の場合は出力だけが流れてくる(入力は受け付けない)
# Ctrl+C → nginx に SIGINT が送られてコンテナが停止する(危険!)
# 安全な抜け方: Ctrl+P → Ctrl+Q(デタッチ)
# → nginx は継続してホストに戻る
docker attach は PID 1 の入出力に直接繋がります。nginx・MySQL などのサービスに attach した状態で Ctrl+C を押すと、SIGINT が PID 1 に送られてサービスが停止します。サービスコンテナのデバッグには docker exec -it を使うのが安全です。
9. 停止・再起動:docker stop / docker restart
# グレースフルに停止(SIGTERM → 10秒後 SIGKILL)
docker stop web
# タイムアウトを延ばす(DBなど終了処理に時間がかかるサービス)
docker stop --time=30 db
# 複数コンテナをまとめて停止
docker stop web db cache
# 停止 → 起動(設定は変わらない)
docker restart web
# 再起動のタイムアウトを指定
docker restart --time=15 web
# 全実行中コンテナを一括停止(開発終了時など)
docker stop $(docker ps -q)
複数コンテナをシャットダウンするとき、依存関係がある場合は順序を意識します。例えば「アプリ → DB」の順で停止することで、アプリが DB 接続エラーを出さずに終了できます。Docker Compose を使うと依存関係を宣言でき、適切な順序で停止されます(第6章で詳しく解説)。
10. 複数コンテナをバックグラウンドで管理する
典型的なWebアプリケーションでは、nginx・アプリサーバー・DBを別々のコンテナで動かします。
# Web + DB + Redis を一斉起動
docker run -d --name db -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 mysql:8.0
docker run -d --name cache -p 6379:6379 redis:7
docker run -d --name app -p 8000:8000 -e DATABASE_URL=mysql://... myapp:latest
docker run -d --name proxy -p 80:80 -p 443:443 nginx
# 全コンテナの状態確認
docker ps
# CONTAINER ID IMAGE STATUS PORTS NAMES
# ... nginx Up 30s 0.0.0.0:80->80/tcp proxy
# ... myapp Up 31s 0.0.0.0:8000->8000/tcp app
# ... redis:7 Up 32s 0.0.0.0:6379->6379/tcp cache
# ... mysql:8.0 Up 33s 0.0.0.0:3306->3306/tcp db
# 全コンテナのリソース確認
docker stats --no-stream
複数コンテナを毎回
docker run コマンドで起動するのは煩雑です。Docker Compose(第6章)を使うと、コンテナ構成を compose.yml ファイルに定義でき、docker compose up -d 1コマンドで全コンテナを起動できます。
11. 本番パターン:–restart と組み合わせる
バックグラウンドサービスを本番で動かすとき、--restart ポリシーと -d を組み合わせることで自動復旧を実現します。
# 本番 nginx: クラッシュ時自動再起動 + ホスト再起動後も自動起動
docker run -d \
--name web \
--restart=unless-stopped \
-p 80:80 -p 443:443 \
nginx
# クラッシュしたときだけ最大3回再起動(バッチ的なサービス)
docker run -d \
--name worker \
--restart=on-failure:3 \
myworker:latest
# ホスト起動時に常に自動起動(完全な常駐サービス)
docker run -d \
--name db \
--restart=always \
-v dbdata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
mysql:8.0
| ポリシー | クラッシュ後 | ホスト再起動後 | docker stop 後 |
|---|---|---|---|
no(デフォルト) |
再起動しない | 起動しない | 停止のまま |
always |
再起動 | 自動起動 | 自動起動(意図的な停止も無視) |
unless-stopped |
再起動 | 自動起動 | 停止のまま(意図的な停止を維持) |
on-failure[:N] |
N回まで再起動 | △(終了コード次第) | 停止のまま |
再起動ポリシーの詳細は「第2章 2-3. コンテナのライフサイクル」を参照してください。
12. シミュレータで練習する
下のシミュレータでデタッチモードの典型的なワークフローを試してみましょう。右側のステータスパネルでコンテナの状態変化をリアルタイムに確認できます。
①
docker run -d -p 8080:80 nginx でバックグラウンド起動 → コンテナIDが返る②
docker ps で running を確認③
docker logs <ID> でログを確認④
docker run -d -p 6379:6379 redis でもう1台起動⑤
docker ps で2台同時に実行中であることを確認⑥
docker stop <ID> で1台停止 → docker ps と docker ps -a の差を確認
13. まとめ
| 操作 | コマンド | ポイント |
|---|---|---|
| バックグラウンド起動 | docker run -d IMAGE |
コンテナIDが返り、ターミナルがすぐ返る |
| 状態確認 | docker ps |
STATUS が Up なら running |
| ログ確認 | docker logs [-f] NAME |
-f でリアルタイム追跡 |
| リソース監視 | docker stats |
CPU・メモリ・ネットワークを一覧で確認 |
| シェル接続 | docker exec -it NAME bash |
exit してもコンテナは停止しない |
| 停止 | docker stop NAME |
SIGTERM → 猶予10秒 → SIGKILL |
| 再起動 | docker restart NAME |
stop + start を一発で |
| 自動復旧 | --restart=unless-stopped |
クラッシュ・ホスト再起動に対応 |
デタッチモードのベストプラクティス
- 常駐サービスには必ず
--nameを付けてIDではなく名前で管理する - デバッグは
docker exec -it NAME bash(attachは危険なケースがある) - 本番では
--restart=unless-stoppedを組み合わせる - ログのローテーションを設定して無制限な蓄積を防ぐ
- 複数コンテナは Docker Compose で宣言的に管理する(第6章)
次の記事「2-6. ポートマッピング(-p)とボリュームマウント(-v)」では、バックグラウンドで動くコンテナを外部からアクセス可能にする(ポートマッピング)と、データを永続化する(ボリューム)方法を解説します。
第2章が完了したら「第3章:Dockerfileによるイメージ構築」で独自イメージを作る方法に進みます。
参考リンク
- docker run –detach(公式) — デタッチモードの公式説明
- docker stats リファレンス(公式) — リソース監視コマンドの全オプション
- View container logs(公式) — ロギングドライバとローテーション設定
- docker attach(公式) — attach の挙動とデタッチキーシーケンス



コメント