はじめに
はじめて docker run する
hello-world から nginx の公開まで、最小のコマンドでコンテナの挙動を確かめます。-p / -d / --rm の 3 つだけ押さえれば最初は十分です。
最初の一歩: hello-world
hello-world はインストール直後の動作確認専用の小さなイメージです。
コンテナが 1 回起動してメッセージを表示し、すぐ終了します。
内部で起きていることは次の通り。
- クライアント(
dockerCLI)がサーバ(デーモン)に「hello-worldを起動したい」と依頼 - ローカルにイメージがなければ Docker Hub から pull
- イメージからコンテナを作り、プロセスを起動
- 標準出力に文字を出してプロセス終了 → コンテナ停止
bash
docker run hello-world
# 停止済みのコンテナも含めて確認
docker ps -anginx を 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 psとlsof -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 -aやdocker system dfで確認
