ポートマッピング

DockerBeginner
オンラインで実践に進む

はじめに

コンテナでは、分離が重要な特徴です。デフォルトでは、コンテナのネットワークはホストシステムから分離されています。そのため、コンテナ内で動作している Web サーバーが正常でも、ポートを明示的に公開しない限り、外部からアクセスできないことがあります。

ポートマッピングは、この分離された状態をつなぎます。ホスト上で選択したポートから、コンテナ内で選択したポートへトラフィックを転送します。分離されたサービスにどのようにアクセスできるようにするかを理解するうえで、これはコンテナネットワーキングの最も基本的で重要な仕組みの 1 つです。

この公開処理を行わなければ、コンテナ内のサービスが完全に正常でも、実質的にはコンテナ自身のネットワーク名前空間からしか利用できません。

この実験では、次の操作を行います。

  • Nginx Web サーバーのコンテナを起動する。
  • ホストのポート 8080 をコンテナのポート 80 にマッピングする。
  • マッピングを確認し、サービスにアクセスする。
  • リソースをクリーンアップする。

コンテナのポートを公開する

このステップでは、Nginx イメージを使用して新しい Docker コンテナを起動します。

Nginx は Web サーバーで、デフォルトではコンテナ内のポート 80 で待ち受けます。ただし、コンテナは分離されているため、ポート 80 は LabEx 環境から自動的にアクセスできません。そこで、ホストマシンのポート 8080 を、コンテナ内のポート 80 にマッピングします。

ポートマッピングの構文は -p <host_port>:<container_port> です。

この順序は重要です。左側はクライアントが接続するホストのポートで、右側はコンテナ内でアプリケーションが実際に待ち受けているポートです。

ターミナルで次のコマンドを実行します。

docker run -d -p 8080:80 --name my-nginx nginx

コマンドの内容:

  • docker run: コンテナを作成して起動するコマンドです。
  • -d: コンテナを detached モード(バックグラウンド)で実行します。
  • -p 8080:80: ポートマッピングを指定するフラグです。
    • 8080: ホストマシン(LabEx 環境)上のポートです。
    • 80: コンテナ内のポートです(Nginx が待ち受けているポート)。
  • --name my-nginx: コンテナに my-nginx という名前を付けます。
  • nginx: 使用するイメージです。

成功すると、Docker は長い Container ID を表示します。

この時点で、Docker が Nginx 自体を変更したわけではありません。ホストのポートに到着したリクエストを、コンテナのサービス用ポートへ転送するネットワークルールを作成しただけです。

ポート設定を確認する

次に、コンテナが実行中で、ポートマッピングが正しく設定されていることを確認します。docker ps コマンドでこの情報を確認できます。

次のコマンドを実行します。

docker ps

次のような出力が表示されます。

CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                  NAMES
abc123456789   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 10 seconds   0.0.0.0:8080->80/tcp   my-nginx

出力の見方:

PORTS 列の 0.0.0.0:8080->80/tcp に注目してください。

  • 0.0.0.0:8080: ホストがすべてのネットワークインターフェースでポート 8080 を待ち受けていることを示します。
  • ->: 転送の方向を示します。
  • 80/tcp: コンテナ内の転送先ポートです。

これにより、マシンのポート 8080 に送られたすべてのトラフィックが、コンテナ内のポート 80 に転送されることを確認できます。

この転送があるため、ポートマッピングはコンテナのポートを「公開する(publishing)」とも表現されます。分離されているサービスを、ホストまたは外部クライアントから利用できるようにしているのです。

ポートだけを確認するには、次のコマンドも使用できます。

docker port my-nginx

サービスをテストする

ポートマッピングが完了したので、Web サーバーにアクセスできるかテストします。ホストのポート 8080 をマッピングしたため、localhost:8080 にリクエストを送信して Nginx サーバーにアクセスできます。

Web リクエストを送信するコマンドラインツール curl を使用します。

次のコマンドを実行します。

curl localhost:8080

期待される結果:

デフォルトの Nginx ウェルカムページの生の HTML コードが表示されます。

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome to nginx!</title>
...
    <h1>Welcome to nginx!</h1>
...
</html>

この HTML 出力が表示されたら成功です。リクエストがホスト(ポート 8080)からコンテナ(ポート 80)へ移動し、Nginx によって処理され、そのレスポンスがホストへ返されたことを示しています。

この往復通信によって、単にコンテナのプロセスが実行中であるだけでなく、ホストとコンテナの間のネットワークが機能していることを実際に確認できます。

リソースをクリーンアップする

最後のステップでは、環境をクリーンアップします。不要になったコンテナを停止して削除し、ポートとシステムリソースを解放することはよい習慣です。

まず、実行中のコンテナを停止します。

docker stop my-nginx

次に、停止したコンテナを削除します。

docker rm my-nginx

コンテナが削除されたことを確認します。

docker ps -a

一覧に my-nginx コンテナが表示されなければ、削除は完了です。

まとめ

この実験では、Docker のポートマッピングの基本を学びました。次の操作を完了しました。

  1. 起動: Nginx コンテナを detached モードで起動しました。
  2. マッピング: -p フラグを使用して、ホストのポート 8080 をコンテナのポート 80 にマッピングしました。
  3. 確認: docker ps を使用してポート設定を確認しました。
  4. アクセス: curl を使用してホストからサービスにアクセスしました。
  5. クリーンアップ: コンテナを削除しました。

ポートマッピングを理解することは、Web アプリケーションをデプロイするうえで不可欠です。分離されたコンテナ内で実行されているサービスに、外部からのトラフィックを到達させられるためです。