DockerでNginx構築完全ガイド:設定ファイルのマウントからHTTPS化まで

はじめに
深夜1時、端末で docker restart nginx を7回叩いた後も、ブラウザには無情な「502 Bad Gateway」が表示されていました。
「設定ファイルは間違いなく書き換えたはずなのに、なぜ?」
Docker移行当初、Nginxの設定反映には本当に悩まされました。
DockerでNginxを扱う場合、ただ docker run するだけでは不十分です。設定ファイルの正しいマウント方法、SSL証明書の管理、コンテナ間の通信——これらには「Dockerならではの作法」があります。
この記事では、私が数々の失敗から学んだ**「Docker Nginxのベストプラクティス」**を共有します。設定ファイルが反映されない理由から、Let’s Encryptによる全自動HTTPS化、そして実用的なリバースプロキシ構成まで、現場で即使えるノウハウを詰め込みました。
基礎:設定ファイルを正しくマウントする
なぜイメージに焼き込まず、マウントするのか?
設定ファイルをDockerイメージの中に COPY してしまう方法もありますが、開発中は推奨しません。
設定を1行変えるたびにビルドし直すのは時間の無駄ですし、本番環境で急な設定変更が必要になった時、即座に対応できないからです。また、設定とコード(イメージ)は分離すべきです。
Nginxコンテナのディレクトリ構造
まずはコンテナ内のどのファイルを上書きすべきかを知りましょう。
/etc/nginx/
├── nginx.conf # メイン設定ファイル
├── conf.d/ # サイトごとの設定ファイル置き場
│ └── default.conf # 初期設定
/usr/share/nginx/html # 静的ファイルのルート
/var/log/nginx/ # ログディレクトリnginx.conf には通常 include /etc/nginx/conf.d/*.conf; と書かれており、conf.d 以下のファイルを読み込むようになっています。
【重要】正しいマウント手順
ステップ1:デフォルト設定をコピーする
いきなり空のファイルを作ると失敗します。まずはコンテナ内のデフォルト設定を取り出しましょう。
# 一時的にコンテナを起動
docker run --name nginx-temp -d nginx
# 設定ファイルをホスト側にコピー
mkdir -p ./nginx/conf
docker cp nginx-temp:/etc/nginx/nginx.conf ./nginx/conf/nginx.conf
docker cp nginx-temp:/etc/nginx/conf.d ./nginx/conf/conf.d
# 用済みなので削除
docker stop nginx-temp && docker rm nginx-tempステップ2:docker run でディレクトリごとマウント
ここで最大のポイントです。単一ファイルではなく、ディレクトリをマウントすることをお勧めします。
docker run -d --name my-nginx \
-p 80:80 -p 443:443 \
-v $(pwd)/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $(pwd)/nginx/conf/conf.d:/etc/nginx/conf.d \
-v $(pwd)/nginx/html:/usr/share/nginx/html \
-v $(pwd)/nginx/logs:/var/log/nginx \
nginxなぜディレクトリマウントなのか?(Vimユーザーへの警告)
LinuxでVimなどのエディタを使ってファイルを保存すると、実は「上書き」ではなく「新しいファイル(新しいinode)への置き換え」が行われることがあります。Dockerの単一ファイルマウントはinode(ファイルの物理的な場所)を監視しているため、inodeが変わるとリンク切れのような状態になり、ホスト側で編集してもコンテナ側に反映されなくなります。
ディレクトリマウントにすれば、フォルダの中身がどう変わろうと追従してくれるため、このトラブルを回避できます。
実践:HTTPS化(Let’s Encrypt自動更新)
本番環境にHTTPSは必須です。Certbot コンテナと連携させて、無料証明書(Let’s Encrypt)を自動取得・自動更新する構成を作りましょう。
Docker Compose構成例
version: '3'
services:
nginx:
image: nginx:latest
container_name: my-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
# Nginxを6時間ごとにリロード(証明書更新を反映するため)
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
# 12時間ごとに更新チェック
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"この構成のミソは、証明書ディレクトリを2つのコンテナで共有している点です。Certbotが更新したファイルを、Nginxが読み込みます。
最初の証明書取得手順
- Nginxの設定(conf.d/default.conf)に、認証用パスを通します。
location /.well-known/acme-challenge/ { root /var/www/certbot; } docker-compose up -dで起動。- Certbotを実行して証明書を取得。
docker-compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot -d yourdomain.com - Nginxの設定を書き換え、HTTPSを有効化してリロードします。
応用:コンテナ間のリバースプロキシ
Nginxを「入口」として、背後のAPIサーバー(Node.jsやPython等)にリクエストを振り分ける構成です。
Dockerのカスタムネットワーク機能を使うと、IPアドレスではなくコンテナ名で通信できます。これが非常に便利です。
手順
ネットワークを作成:
docker network create my-app-net両方のコンテナを同じネットワークに入れる:
# バックエンド docker run -d --name my-api --network my-app-net my-api-image # Nginx docker run -d --name nginx --network my-app-net -p 80:80 ... nginxNginx設定(conf.d/api.conf):
server { listen 80; server_name api.example.com; location / { # コンテナ名「my-api」がそのままドメインとして使える! proxy_pass http://my-api:3000; # クライアントのIPを正しく伝えるためのヘッダー proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
proxy_pass http://my-api:3000; のように、Dockerのサービス名をホスト名として記述できるのがポイントです。IPアドレスを調べる必要はありません。
まとめ
DockerでNginxを使いこなすための3つの鉄則:
- ディレクトリマウント:設定ファイルの編集トラブルを避けるために、親フォルダごとマウントする。
- Certbot連携:専用コンテナとボリューム共有を使って、HTTPS更新を自動化する。
- コンテナ名通信:Dockerネットワークを活用し、設定ファイルにはIPではなくコンテナ名を記述する。
これらを守れば、Nginxコンテナはあなたのインフラの強力なゲートウェイになります。
Docker Nginx構築フロー
設定マウントからHTTPS、リバースプロキシ設定まで
⏱️ Estimated time: 20 min
- 1
Step1: ステップ1:設定ファイルの抽出
一時コンテナを起動し、docker cp コマンドでデフォルトの nginx.conf と conf.d をホスト側にコピーします。これが運用のベースになります。 - 2
Step2: ステップ2:ディレクトリマウントで起動
docker run時に -v ./nginx/conf.d:/etc/nginx/conf.d のようにディレクトリ単位でマウントします。これによりファイルの追加や編集が即座に反映されます。 - 3
Step3: ステップ3:HTTPS化(Certbot)
CertbotコンテナとWebrootディレクトリを共有し、Let's Encrypt証明書を取得します。定期実行スクリプトで自動更新も設定します。 - 4
Step4: ステップ4:リバースプロキシ設定
同じDockerネットワーク内のアプリコンテナに対し、proxy_pass http://container-name:port; を設定します。コンテナ名での名前解決を活用しましょう。
FAQ
設定ファイルを変更したのにnginx -tが通らない、または反映されません。
バックエンドのコンテナに接続できません(502エラー)。
クライアントのIPアドレスがDockerゲートウェイのIPになってしまいます。
3 min read · 公開日: 2025年12月18日 · 更新日: 2026年1月22日
関連記事
Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践

Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践
Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド

Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド
Next.js ユニットテスト実践:Jest + React Testing Library 完全設定ガイド


コメント
GitHubアカウントでログインしてコメントできます