nikkie-ftnextの日記

イベントレポートや読書メモを発信

Dockerfile の EXPOSE 命令は、ドキュメントのためのもの(書かなくても docker run -p でポートは公開できます)

はじめに

七尾百合子さん、お誕生日 176日目 おめでとうございます! nikkieです。

同僚に教えていただいた件を自分でも調べ、自身の誤解に気づきました。

目次

結論:Dockerfile のドキュメントより

https://docs.docker.com/reference/dockerfile/#expose

The EXPOSE instruction doesn't actually publish the port.

EXPOSE命令は実際にはポートを公開しない(意訳)
たしかにdocker run -pしています

It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published.

  • イメージをビルドする人とコンテナを実行する人の間の一種のドキュメントとして機能する
  • どのポートを公開すると意図しているかを示すドキュメント

EXPOSEは必須だと思い込んできた

Docker に入門した当初から、ポートを公開するのに-pEXPOSEの両方が必要と思い込んできました。
当時の記事

直近のビルドした記事でもEXPOSEしています。

EXPOSEはなくともdocker run -pで動作する

直近記事の Dockerfile からEXPOSEを抜いたものを用意します

% docker build -t uv-practice-fastapi:0.1.2 .
% docker run --rm -p 8000:8000 uv-practice-fastapi:0.1.2

別ターミナル

% curl -sS http://127.0.0.1:8000/ | jq '.'
{
  "kokoro": "Friday",
  "aki": "Monday",
  "fuka": "Monday",
  "rion": "Friday",
  "subaru": "Sunday",
  "masamune": "Sunday",
  "ureshino": "Wednesday"
}

通信できてますね!

ということは、docker runのときにポートを指定するなんてこともできちゃいます1

-CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
+ENTRYPOINT [ "python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0" ]
+CMD ["--port", "8000"]
% docker build -t uv-practice-fastapi:0.1.3 .   
% docker run --rm -p 8080:8080 uv-practice-fastapi:0.1.3 --port 8080

docker runのドキュメント

docs.docker.com

終わりに

docker run -pでコンテナのポートをホストのポートにバインドして公開するには、Dockerfile のEXPOSEが必須と思い込んでいました。
今回認識したのは、EXPOSEはあくまでドキュメントということで、書いていなくてもdocker run -pでポートを公開できました。
書いたり書かないでみたりして、どう書いていくか(自分にとってのプラクティス)を探っていきます