はじめに

はじめて docker run する

hello-world から nginx の公開まで、最小のコマンドでコンテナの挙動を確かめます。-p / -d / --rm の 3 つだけ押さえれば最初は十分です。

はじめて docker run する diagram

最初の一歩: hello-world

hello-world はインストール直後の動作確認専用の小さなイメージです。

コンテナが 1 回起動してメッセージを表示し、すぐ終了します。

内部で起きていることは次の通り。

  1. クライアント(docker CLI)がサーバ(デーモン)に「hello-world を起動したい」と依頼
  2. ローカルにイメージがなければ Docker Hub から pull
  3. イメージからコンテナを作り、プロセスを起動
  4. 標準出力に文字を出してプロセス終了 → コンテナ停止
bash
docker run hello-world

# 停止済みのコンテナも含めて確認
docker ps -a

nginx を 1 コマンドで公開する

実アプリに近い例として、nginx(Web サーバ)を起動してブラウザからアクセスしてみます。

docker run --rm -d -p 8080:80 --name web nginx

各オプションの意味:

  • --rm: コンテナが停止したら自動削除。使い捨て前提で試すときに便利
  • -d: デタッチ(バックグラウンド)実行。ログは docker logs で見る
  • -p 8080:80: ホストの 8080 番をコンテナの 80 番にマッピング
  • --name web: 管理用のコンテナ名を付ける

ブラウザで http://localhost:8080 を開くと nginx のデフォルトページが見えます。

停止は docker stop web

--rm を付けているので停止と同時に削除されます。

-p / -d / --rm をもう少し掘り下げる

最初に覚えるフラグはこの 3 つで十分ですが、挙動をもう一段理解しておくと応用が利きます。

  • -p HOST:CONTAINER: ホスト側ポート番号と、コンテナ内のポート番号を対応付ける。-p 127.0.0.1:8080:80 のようにバインド先 IP も指定できる
  • -p 80 のように 1 つだけ書くと、コンテナ内の 80 にホスト側のランダムポートが割り当てられる。docker port <name> で実際のポートを確認
  • -d を付けずに前景起動すると Ctrl+C で止められるが、シェルを閉じると同時に止まる
  • --rm を付けずに実行したコンテナは停止後も残り、docker ps -a で見える。再度起動するには docker start <name>

長期運用するコンテナは通常 --rm を付けずに運用し、Compose や Kubernetes で管理するのが一般的です。

中に入って確認する: exec と logs

動いているコンテナの中で調査したいときは docker exec、ログを見たいときは docker logs を使います。

# nginx のコンテナ内でシェルを開く
docker exec -it web sh
# コンテナ内でファイル確認
ls /etc/nginx/conf.d
exit

# 直近のアクセスログを追尾
docker logs -f web

-it は「対話(interactive)+ 擬似端末(tty)」の省略形で、シェルを開くときはほぼ必須です。

docker run にも同じフラグがあり、docker run -it ubuntu bash のように使うとそのまま Ubuntu のシェルに入れます。

はじめてのつまずきポイント

初回の docker run でよく詰まるポイントをまとめます。

  • ポートが既に使われている: Bind for 0.0.0.0:8080 failed: port is already allocated。別のプロセスか、前の --rm なしコンテナが握っている。docker pslsof -i :8080 で確認
  • ローカルホストから見えない: WSL2 や VM 上では localhost がホスト OS と一致しないことがある。Docker Desktop は自動で転送するが、素の VM では VM の IP にアクセスする
  • コンテナ内でファイルを編集したら次回消える: --rm 付きコンテナは削除と同時にすべて消える。永続化したいデータは volume か bind mount を使う
  • プロセスが 1 つ終わるとコンテナも止まる: コンテナは PID 1 のプロセスに寿命が紐づく。sleep infinity のようなダミープロセスを使わず、実アプリの起動コマンドを CMD/ENTRYPOINT に書く
  • docker run を繰り返すとイメージが増える: 使い捨ては --rm で削除できるが、イメージ自体は残る。docker image prune -adocker system df で確認

関連トピック