2.5 docker run -d とは?デタッチモード・バックグラウンド実行を完全解説

【第2章】イメージとコンテナの基本操作

Webサーバーやデータベースは「起動したら動き続ける」ものです。docker run -it nginx で起動するとターミナルが nginx に占領され、Ctrl+C を押せばサービスが止まってしまいます。本番や開発での実用シーンでは -d--detach)でコンテナをバックグラウンドで動かすのが基本パターンです。

この記事では -d の動作原理から、ログ確認・リソース監視・停止管理まで体系的に解説します。


目次

  1. なぜバックグラウンド実行が必要か
  2. -d の仕組み:Dockerデーモンに委譲する
  3. docker run -d の基本
  4. コンテナIDの活用
  5. 状態確認:docker ps / docker inspect
  6. ログ確認:docker logs
  7. リソース監視:docker stats / docker top
  8. 接続し直す:docker attach / docker exec -it
  9. 停止・再起動:docker stop / docker restart
  10. 複数コンテナをバックグラウンドで管理する
  11. 本番パターン:–restart と組み合わせる
  12. シミュレータで練習する
  13. まとめ

1. なぜバックグラウンド実行が必要か

コンテナをフォアグラウンドで起動した場合(-d なし)、コンテナのプロセスがターミナルを占有します。

# フォアグラウンド起動(ターミナルが占領される)
docker run nginx
# → nginx のアクセスログが流れ続ける
# → Ctrl+C を押すと SIGINT が送られ nginx が停止する
# → このターミナルでは他のコマンドが打てない

Webサーバー・データベース・メッセージキューといった常駐サービスはターミナルとは独立して動き続ける必要があります。

起動方法 ターミナルの状態 Ctrl+C の影響 適した用途
フォアグラウンド(デフォルト) 占有される コンテナが停止する 一時コマンド・デバッグ
-d(デタッチ) すぐに返る 影響なし 常駐サービス・本番運用

2. -d の仕組み:Dockerデーモンに委譲する

-d--detach)は「コンテナをDockerデーモン(dockerd)に引き渡し、ターミナルとの接続を切って制御を返す」オプションです。

フォアグラウンド起動(-d なし):
ターミナル
(占有)

◀── stdin/stdout ──▶

コンテナ
PID 1: nginx

  Ctrl+C → SIGINT がコンテナに送られて停止
デタッチ起動(-d あり):
ターミナル
(すぐ返る)

◀── コンテナID返却 ──

dockerd(デーモン)
コンテナ
PID 1: nginx

  次のコマンドが打てる  |  Ctrl+C を押してもコンテナは影響を受けない

デタッチしたコンテナの標準出力・標準エラー出力は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 はターミナルと接続します。両方指定すると -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
💡 –name を使うと管理が楽になる
IDは再起動のたびに変わりますが、--name で付けた名前は固定です。docker logs webdocker stop webdocker 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 は継続してホストに戻る
⚠️ attach でサービスコンテナに Ctrl+C しない
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 Compose で管理する
複数コンテナを毎回 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 psrunning を確認
docker logs <ID> でログを確認
docker run -d -p 6379:6379 redis でもう1台起動
docker ps で2台同時に実行中であることを確認
docker stop <ID> で1台停止 → docker psdocker 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 bashattach は危険なケースがある)
  • 本番では --restart=unless-stopped を組み合わせる
  • ログのローテーションを設定して無制限な蓄積を防ぐ
  • 複数コンテナは Docker Compose で宣言的に管理する(第6章)
✅ 次のステップ
次の記事「2-6. ポートマッピング(-p)とボリュームマウント(-v)」では、バックグラウンドで動くコンテナを外部からアクセス可能にする(ポートマッピング)と、データを永続化する(ボリューム)方法を解説します。
第2章が完了したら「第3章:Dockerfileによるイメージ構築」で独自イメージを作る方法に進みます。

参考リンク

Dockerの基礎を動画で体系的に学びませんか?

実務で使う基礎だけを3時間に凝縮。環境構築から丁寧に解説しています。

Udemy Docker入門講座 クーポン割引で講座を見る →

コメント

タイトルとURLをコピーしました