2.8 Dockerハンズオン|nginxでWebサーバを立ててブラウザからアクセスする【ポート転送の応用】

【第2章】イメージとコンテナの基本操作

Dockerハンズオン|nginxでWebサーバを立ててブラウザからアクセスする【ポート転送の応用】

2-7 では Python と PostgreSQL を使って、コンテナの中で完結する操作を体験しました。今回はいよいよコンテナの外(あなたのPCのブラウザ)からコンテナの中(nginx)にアクセスします。2-6 で学んだ -p ポート転送と -v ボリュームマウントの実戦投入編です。

💡 この記事のゴール
docker run -p 8080:80 nginx でWebサーバを起動、ブラウザで http://localhost:8080 を開いて nginx の画面を確認
docker logs でアクセスログが流れる様子を観察
-v で自分の書いた index.html を配信(カスタムHTMLの差し替え)
④ コンテナの中を覗いて、nginx がどこに設定ファイルを置いているか確認

目次

  1. 前提:ここまで学んだオプション
  2. なぜ nginx でハンズオン?
  3. Part 1:nginx を起動してブラウザでアクセス
  4. Part 2:アクセスログを観察する
  5. Part 3:自分の HTML を配信する(-v
  6. Part 4:コンテナの中身を覗いてみる(好奇心編)
  7. 後片付け
  8. 今回使ったオプションまとめ
  9. よくあるつまずき
  10. 次のステップ:第3章 → 自分専用イメージを作る

1. 前提:ここまで学んだオプション

第2章の前半で以下を身につけてきました。このハンズオンで一気に組み合わせて使います。

記事 学んだこと 今回使う場面
2-2 主要コマンド run / ps / logs / exec 全編
2-5 デタッチモード -d / --name nginx を常駐起動
2-6 ポートマッピング -p 8080:80 ブラウザから接続するための橋渡し
2-6 ボリュームマウント -v /host/path:/in/container 自作HTMLをコンテナに渡す
2-7 Python/Postgres ハンズオン docker exec -it で中に入る nginx の設定ファイルを覗く
⚠️ 事前確認
docker version が通ることと、ホスト側のポート 8080 が空いていること(他のアプリで使用中ならエラーになります)を確認してください。使用中の場合は -p 9080:80 のようにホスト側ポート番号を変えればOKです。

2. なぜ nginx でハンズオン?

nginx(エンジンエックス)は世界で最も使われているWebサーバの1つです。静的ファイル配信・リバースプロキシ・ロードバランサーなど、現場のあらゆる場所で登場します。

今回 nginx を題材に選んだ理由は2つ:

  • 起動して即アクセスできる:公式イメージは何も設定しなくてもデフォルトのWelcomeページを配信してくれる。つまりポート転送の効果がすぐ目で確認できる。
  • 設定ファイルの場所が決まっている/usr/share/nginx/html(公開ディレクトリ)、/etc/nginx/(設定)。これは -v ボリュームマウントの練習に最適。
💡 別のWebサーバでも同じパターン
httpd(Apache)・caddynode(Express等)・python:3.12(Flask/FastAPIアプリ)も全部同じ流れで動かせます。今日の学びはnginx以外にもそのまま使えます。

3. Part 1:nginx を起動してブラウザでアクセス

3-1. イメージを取得する

docker pull nginx

約 200MB 前後のイメージです。ダウンロード後、docker images で一覧を確認できます。

3-2. ポート転送付きで起動する

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

各オプションを確認しましょう。

オプション 役割
-d バックグラウンド起動(2-5 復習)
--name web 後で logs/exec/stop で指定するための名前
-p 8080:80 ホスト側 8080 番ポートをコンテナ内の 80 番に転送(2-6 復習)
nginx 使うイメージ(タグ省略で latest
💡 -p HOST:CONTAINER の順番を覚えるコツ
家の外(HOST)から、家の中(CONTAINER)へ」の順。左が外(ブラウザが叩く側)、右が中(nginxが待ち受ける側)。左右を間違えるとアクセスできません。

3-3. ブラウザで開いてみる

Webブラウザで次のURLを開いてください。

http://localhost:8080

Welcome to nginx!」の画面が表示されれば成功です。こんな画面です:



🔒 http://localhost:8080

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

✅ 確認
あなたは今、自分のPCにnginxをインストールせずにWebサーバを立てて、ブラウザからアクセスしました。これが Docker の一番わかりやすい嬉しさです。

3-4. 通信の流れを図で把握する

ブラウザから nginx までの通り道を整理しておきましょう。-p 8080:80 はこの「橋」を架けるオプションです。

【 localhost:8080 → nginx までのデータフロー 】
① ブラウザ
🌐 Chrome/Safari
localhost:8080

━▶
② ホストOS
💻 あなたのPC
:8080 で受ける

━▶
③ コンテナ「web」
📦 nginx プロセス
:80 で待ち受け

🔗 -p 8080:80 がホストの8080とコンテナの80を橋渡し
⚠️ ポート番号を変えるには
ホスト側を 9090 にしたいときは -p 9090:80。アクセスURLも http://localhost:9090 になります。コンテナ側(右の80) は nginx が待ち受けているポートなので基本は変えません。

3-5. シミュレータで同じ流れを試す

下のシミュレータで docker run -d nginxdocker psdocker exec -it と一連を体験できます(クイックアクションボタンが便利)。


4. Part 2:アクセスログを観察する

ブラウザでアクセスした時、nginx はアクセスログを出力しています。このログを見ると、いつ・どこから・どのURLに誰が来たかがわかります。

4-1. docker logs で見てみる

docker logs web

こんな行が並んでいるはずです(あなたがアクセスした回数だけ)。

172.17.0.1 - - [20/Apr/2026:03:15:22 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 ..."
172.17.0.1 - - [20/Apr/2026:03:15:22 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "-" "Mozilla/5.0 ..."
ログの一部 意味
172.17.0.1 アクセス元のIP(Docker内部ネットワーク経由で見えている)
GET / トップページへのリクエスト
200 正常応答(ステータスコード)
GET /favicon.ico ... 404 ブラウザが自動で探しに行ったファビコン(今は無いので404)

4-2. リアルタイムで流れを見る(-f フォロー)

docker logs -f web

この状態でブラウザをリロード(F5)すると、1行ずつログが増えていくのがリアルタイムで見えます。止めるときは Ctrl+C

💡 なぜ docker logs で nginx のログが見えるのか?
nginx 公式イメージは、アクセスログファイル /var/log/nginx/access.log をコンテナの標準出力に、エラーログを標準エラー出力にシンボリックリンクで繋いでいます。Docker は各コンテナの標準出力を記録しているので、docker logs で一括で見えるわけです。自作アプリでも print(...)console.log(...) をそのまま標準出力に出しておけば同じ仕組みで見られます。

5. Part 3:自分の HTML を配信する(-v

Welcome ページだけでは味気ないので、自分で書いた HTML を配信してみましょう。-v ボリュームマウント(2-6 復習)を使います。

5-1. 準備:カスタム index.html を作る

作業用ディレクトリを決めて、そこに index.html を1つ置きます。

# 作業用ディレクトリを作る
mkdir myhtml
cd myhtml

# index.html を作成(エディタで作ってもOK)
cat > index.html <<'EOF'
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="utf-8"><title>My Docker Page</title></head>
<body style="font-family:sans-serif;background:#e3f2fd;padding:2em">
  <h1>🐳 Docker ハンズオン成功!</h1>
  <p>これは -v でマウントした自作ページです。</p>
</body>
</html>
EOF

5-2. いったん古いコンテナを止める

docker stop web
docker rm web

5-3. ボリュームマウントで再起動

# macOS / Linux / WSL2
docker run -d --name web -p 8080:80 \
  -v "$(pwd)":/usr/share/nginx/html:ro nginx

# Windows PowerShell
docker run -d --name web -p 8080:80 `
  -v "${PWD}:/usr/share/nginx/html:ro" nginx

追加された -v オプションの中身:

部分 意味
$(pwd) / ${PWD} ホスト側の現在のディレクトリ(絶対パス)
:/usr/share/nginx/html nginx がデフォルトで HTML を探す場所(固定)
:ro read-only(コンテナから書き込ませない安全策)

5-4. ブラウザで確認

再び http://localhost:8080 を開いてください(F5でリロード)。先ほどの Welcome ページではなく、自分で書いた🐳のページが表示されているはずです:



🔒 http://localhost:8080

🐳 Docker ハンズオン成功!

これは -v でマウントした自作ページです。

Welcome ページと見比べると、同じ URL・同じコンテナなのに配信内容が入れ替わったことが一目瞭然です。これがボリュームマウントの威力です。

5-5. マウントの関係を図で整理

【ホストのディレクトリ ↔ コンテナ内のパスが繋がる】
🖥️ ホスト側
現在のディレクトリ
./myhtml/
├── index.html

📦 コンテナ内
nginx が HTML を探す場所
/usr/share/nginx/html/
├── index.html

🔗 -v $(pwd):/usr/share/nginx/html:ro で両者を紐付け
ホスト側の index.html を編集 → ブラウザをリロードするだけで反映(コンテナの再起動不要)
💡 ホット開発:保存 → ブラウザ更新で即反映
index.html をエディタで編集して保存すれば、コンテナを再起動しなくてもブラウザ更新で新しい内容が見られます。これが -v の本番での大きな価値:開発中はホストで編集、コンテナはそのまま動かし続ける

5-6. シミュレータでマウントの挙動を確認

下のシミュレータで「ホスト側で編集したファイルが、コンテナ内から見えるようになる」仕組みを可視化できます。


6. Part 4:コンテナの中身を覗いてみる(好奇心編)

ここは必須ではないですが、「コンテナって内部どうなってるの?」を体感するのに最高の素材です。2-7 と同じく docker exec -it で入ります。

docker exec -it web bash

コンテナ内のシェルに切り替わります。いくつか探検してみましょう。

6-1. nginx の公開ディレクトリを見る

root@xxx:/# ls /usr/share/nginx/html
index.html

root@xxx:/# cat /usr/share/nginx/html/index.html

ホスト側で書いた index.html が見えるはずです。これは -v マウントのおかげです。

6-2. nginx の設定ファイルを眺める

root@xxx:/# ls /etc/nginx/
conf.d/  fastcgi_params  mime.types  nginx.conf  ...

root@xxx:/# head -20 /etc/nginx/nginx.conf

全てのnginx設定がここに置かれています。本格的な運用ではこれらを -v や Dockerfile でカスタマイズします。

6-3. アクセスログの場所を確認

root@xxx:/# ls -la /var/log/nginx/
lrwxrwxrwx 1 root root 11 ... access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 ... error.log  -> /dev/stderr
💡 シンボリックリンクの正体
/dev/stdout /dev/stderr にリンクされているので、nginx がログに書き込む=コンテナの標準出力に出る=docker logs で見える、という設計になっています。「Dockerでログはどこ?」の答えはこれです。

探検が終わったらコンテナから抜けます。

root@xxx:/# exit

web コンテナは引き続き動いています(2-7 で学んだとおり、exec で入ったシェルを抜けてもコンテナは停止しません)。


7. 後片付け

docker stop web
docker rm web

イメージも不要なら削除。

docker rmi nginx
✅ ホスト側の myhtml/ は残る
-v でマウントしたのはホスト側のディレクトリなので、コンテナを消しても index.html はそのまま手元に残ります。これがボリュームマウントの「データはホスト側にある」メリットです。

8. 今回使ったオプションまとめ

オプション 役割 今回の使い方
-d バックグラウンド起動 nginx を常駐させる
--name web 名前付け logs/exec/stop で指定
-p 8080:80 ポート転送 ホスト8080 → コンテナ80
-v $(pwd):/usr/share/nginx/html:ro ボリュームマウント(読み取り専用) カスタム index.html を配信
docker logs web コンテナの標準出力を表示 アクセスログ観察
docker logs -f web ログをリアルタイム表示 ブラウザF5で流れを見る
docker exec -it web bash 動作中コンテナに入る 中身を探検

9. よくあるつまずき

症状 原因 対処
port is already allocated ホスト8080が他のアプリで使用中 -p 9080:80 のようにホスト側ポートを変える
ブラウザで「接続できません」 -p を付け忘れた/コンテナが起動していない docker ps で Up を確認、-p を付けて再起動
403 Forbidden が出る マウント先に index.html が無い/権限が無い ファイル名が index.html か、ホスト側で読める権限か確認
docker: Error response from daemon: invalid mount config(Windows) パスの書き方が違う PowerShell なら "${PWD}:/usr/share/nginx/html"、cmd なら "%cd%:/usr/share/nginx/html"
編集したのに反映されない ブラウザキャッシュ Ctrl+F5 でスーパーリロード
2回目の --name web でエラー 同名コンテナが残っている docker rm web で削除してから起動
WSL2でボリュームが空に見える Docker Desktop の file sharing 未許可 Docker Desktop → Settings → Resources → File Sharing でドライブ許可

10. 次のステップ:第3章 → 自分専用イメージを作る

今回は公式イメージをそのまま使って、外から -v で HTML を差し込む形でカスタマイズしました。小規模な確認や開発用にはこれで十分です。

ただ本番運用では、こんな要件が出てきます:

  • HTMLだけでなく nginx の設定自体を変えたい(リバースプロキシ設定・独自モジュール追加 等)
  • チームの他メンバーにも同じ環境を一発で配りたい
  • CI/CD パイプラインで自動ビルドしたい

そこで登場するのが Dockerfile。公式の nginx イメージを土台に、自分の HTML や設定を最初から焼き込んだ独自イメージを作れます。

【今回(2-8)→ 第3章の発展イメージ】
今回(2-8)
公式 nginx + -v で外からHTML注入
→ カスタマイズはマウントで

第3章(3-1, 3-4)
Dockerfile で HTML・設定を焼き込んだ
独自イメージを作る
→ 配布・自動ビルド可能

✅ 次のステップ
3-1 Dockerfile 完全入門で、FROM nginx から始まる Dockerfile を書いて、今回の index.html を含んだイメージを作ってみましょう。「docker builddocker push → 別のPCで docker pull → 動く」が1ループで体験できます。

11. まとめ

体験したこと 使ったコマンド 学んだこと
nginx をバックグラウンド起動 docker run -d --name web -p 8080:80 nginx -p HOST:CONTAINER でブラウザから到達可能に
アクセスログ観察 docker logs -f web コンテナの標準出力がログとして確認できる
カスタムHTML配信 -v $(pwd):/usr/share/nginx/html:ro ホスト側のファイルをコンテナに注入、編集→F5で即反映
コンテナ内を探検 docker exec -it web bash nginx の公開ディレクトリ・設定・ログのシンボリックリンク
後片付け docker stop / rm ホスト側のデータはマウント元に残る

これで第2章のハンズオン2本(2-7 Python/Postgres、2-8 nginx)をクリアしました。「コンテナの中で完結」も「外からアクセス・データ注入」も一通り体験できたので、第3章ではいよいよ自分専用のコンテナイメージを Dockerfile で作るステップに進みます。

参考リンク


Dockerの基礎を動画で体系的に学びませんか?

実務で使う基礎だけを3時間に凝縮。環境構築から丁寧に解説しています。

Udemy Docker入門講座 クーポン割引で講座を見る →

コメント

タイトルとURLをコピーしました