Docker の Expose と Ports の違い
Docker では、docker create
または docker run
を使用してコンテナーを作成した後、コンテナーが外部サービスまたは他の外部コンテナーと対話するようにしたい場合があります。これを実現するには、ポートを外部で利用できるようにする必要があります。
この記事では、Docker でポートを公開するために使用できる 2つの重要な方法を紹介します。また、コンテナポートをホストポートにマップする方法と、メソッドの違いについても説明します。
Docker の EXPOSE
DockerFile 命令
Docker ファイルは、docker build
コマンドを使用してイメージをアセンブルするための指示を指定する単なるテキストファイルです。これらの中には、EXPOSE
命令があります。
EXPOSE
命令は、構築中のコンテナーが実行時に特定のネットワークポートでリッスンする必要があることを Docker に通知するために使用されます。ただし、この命令は単なる参照ポイントであり、コンテナポートをホストポートにマップしないことに注意してください。
構文:
EXPOSE <port>/<protocol>
Docker はデフォルトの TCP プロトコルを使用できるため、プロトコルを指定する必要はありません。ただし、UDP プロトコルなどの他のプロトコルを提供することはできます。
プロトコルが Nginx 公式 Docker ファイルで指定されていないため、Docker はデフォルトの TCP プロトコルを使用します。
COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE 80
STOPSIGNAL SIGQUIT
CMD ["nginx", "-g", "daemon off;"]
Docker レジストリから公式の Nginx イメージをプルし、コンテナーを作成して、コンテナーを実行するとします。その場合、ポート番号や使用されているプロトコルなど、コンテナから役立つ情報をすばやく特定できます。
~/isaac$ docker ps -a
出力:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99edfdea0443 nginx "/docker-entrypoint.…" 3 minutes ago Up 2 minutes 80/tcp nice_volhard
上記の出力は、Dockerfile と TCP プロトコルに記載されているように、Nginx コンテナがポート 80 で実行されていることを示しています。
または、以下に示すように、コンテナの作成時に --expose
タグを使用して実行時にポートを公開することもできます。
docker run --expose 80 nginx
次に、このポートをホストポート番号にバインドします。大文字の -P
タグまたは小文字の -p
タグを使用する必要があります。
どちらでも結果を得ることができますが、これらのタグには大きな違いがあります。
大文字の -P
タグを実行時に使用すると、公開されているすべてのタグをホスト上のランダムなポートにバインドできます。これにより、ポートの競合を回避できます。
$ docker run -d -P nginx
006b88a06e51eac45895f13b33a89221676029e8fa654aaaccc79b81f74efb4d
コード:
isaac$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
006b88a06e51 nginx "/docker-entrypoint.…" 27 seconds ago Up 6 seconds 0.0.0.0:49153->80/tcp angry_babbage
小文字の -p
タグを使用して、ホスト上の特定のポートにコンテナを公開することもできます。
Docker Compose のポート
Docker-compose は、Docker 上でマルチコンテナーアプリケーションを実行できるようにするユーティリティツールです。
docker-compose.yml
ファイルの下で、サービス、ファイルのバージョン、使用されるボリューム、サービスを接続するネットワークなど、他のファイル間でコンテナーを構成する方法を指定できます。
Dockerfile でポート番号を指定したのと同様に、docker-compose.yml
ファイルでもポート番号を指定する必要があります。これは、expose
または ports
命令を使用して行うことができます。
rabbitmq:
image: rabbitmq
expose:
- 3000
- 5000
expose
命令を使用すると、ポートを公開したり、ホストポートにバインドしたりせずに、ポートを公開できます。つまり、ポートはホストマシンに公開されず、他のサービスにのみ公開されます。
一方、ports
命令では、ホストとコンテナの両方のポート番号を指定できます。さらに、これらのポートは他のサービス間で共有され、ランダムまたは特定のポートに対してホストマシンに公開されます。
rabbitmq:
image: rabbitmq
ports:
- "8000:80"
- "5000: 70"
Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.
LinkedIn