はじめに
このドキュメントは、Docker上でNginxを使い、SSL/TLS証明書を導入してHTTPS通信を実現する手順をわかりやすくまとめた入門ガイドです。
目的
- 安全な通信(HTTPS)を構築する方法を実践的に学びます。
- 証明書の取得からNginx設定、Docker Composeでの環境構築、動作確認まで一連の流れを扱います。
対象読者
- Webサービスを公開したい開発者や運用担当者向けです。
- DockerとNginxの基本的な操作がわかる方を想定しますが、初めての方でも理解できるよう手順を丁寧に説明します。
前提条件
- DockerとDocker Composeがインストール済みであること。
- ドメイン名を取得できること(自己署名証明書の検証も説明します)。
本書の流れ
各章で具体的な設定例やコマンドを示します。実際のファイル構成や注意点も扱うため、読みながら環境構築を進められます。まずは全体像をつかんでから、順に進めてください。
SSL証明書の種類と取得方法
概要
Docker環境でNginxを使う際、外部と安全に通信するためにSSL証明書が必要です。主な選択肢は無料のLet’s Encrypt、自己署名証明書、そして有料の商用証明書です。
Let’s Encrypt(無料)
Let’s Encryptは自動で証明書を発行・更新します。生成される主なファイルはfullchain.pem(証明書連鎖)とprivkey.pem(秘密鍵)です。一般的にはcertbotを使い、HTTPチャレンジ(80番ポート)かDNSチャレンジを選びます。Dockerではcertbotコンテナを使うかホスト側で発行し、生成物をNginxコンテナにマウントします。
自己署名証明書(開発用)
テスト環境では自己署名で十分です。OpenSSLで秘密鍵と証明書を作成します。例:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout privkey.pem -out fullchain.pem -subj "/CN=example.local"
自己署名はブラウザで警告が出る点に注意してください。
商用証明書
企業向けやEVが必要な場合は有料を選びます。ワイルドカード(*.example.com)やSAN(複数ドメイン対応)など、用途に応じて選びます。
取得後の配置と更新
取得したfullchain.pemとprivkey.pemをNginxの参照先に配置し、コンテナ起動時にボリュームでマウントします。Let’s Encryptは定期的に更新が必要ですので、certbot renewを自動化してください。
小さな注意点
- 秘密鍵は安全に保管してください。
- 本番では自己署名は避けてください。
Nginxの基本的なSSL設定
目的と全体像
NginxでHTTPSを使うには、(1)HTTP(80番)からHTTPS(443番)へリダイレクトする、(2)443でSSLを有効にして証明書を指定する、主にこの2つを設定します。
HTTPからHTTPSへリダイレクト(例)
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
この設定で全てのアクセスがHTTPSに誘導されます。
HTTPSの基本設定(例)
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
root /var/www/html;
index index.html;
}
実務上の注意点
- パスは実際の証明書ファイルに合わせること。Let’s Encryptなら/etc/letsencrypt/live/ドメイン/fullchain.pemとprivkey.pemを使います。
- 秘密鍵の権限は厳しく(例: chmod 600)設定してください。Nginxが読み取れる所有者にする必要があります。
- 設定変更後は必ず構文チェック(sudo nginx -t)を行い、問題なければ再読み込み(sudo systemctl reload nginx)してください。
よくあるトラブル
- パス間違いで404や鍵読込エラー
- ポート開放(ファイアウォール)忘れ
- 自己署名証明書の場合、ブラウザで警告が出ます。
SSL/TLSプロトコルの設定
概要
NginxでTLSのバージョンを制限すると安全性が高まります。TLSv1.2とTLSv1.3を有効にし、古いTLS/SSL(SSLv2/SSLv3/TLSv1.0/TLSv1.1)は無効にします。これにより既知の脆弱性を避けられます。
有効化と無効化の指定方法
Nginxの設定に次のように書きます。
ssl_protocols TLSv1.2 TLSv1.3;
この一行でサーバー側で許可するプロトコルを限定します。
暗号スイート(ssl_ciphers)の設定
安全で互換性のある暗号を指定します。例:
ssl_ciphers ‘ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:…’;
ssl_prefer_server_ciphers on;
具体例はOSやOpenSSLのバージョンで変わります。TLS1.3では暗号選択が自動化されるため、主にTLS1.2向けを設定します。
セッションキャッシュとタイムアウト
セッションキャッシュと有効期限を設定するとハンドシェイク負荷を下げられます。例:
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
また、TLSセッション再利用やチケットを使うと性能が向上します。サーバーでのチケット管理は注意深く行ってください。
設定例(serverブロック内)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ‘高セキュリティ列挙子’;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
動作確認
openssl s_clientやSSL Labsなどでプロトコルと暗号の有効/無効を確認します。テストを繰り返して互換性と安全性のバランスを取ってください。
Docker Composeを用いた環境構築
概要
Docker ComposeでNginxとCertbotを一緒に動かし、証明書を共有する方法をわかりやすく説明します。Certbotで取得した証明書をボリュームに保存し、Nginxがそれを読み取る構成にします。
docker-compose.ymlの例
version: '3'
services:
nginx:
image: nginx:stable
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./data/certbot:/etc/letsencrypt
- ./data/www:/var/www/certbot
restart: always
certbot:
image: certbot/certbot
volumes:
- ./data/certbot:/etc/letsencrypt
- ./data/www:/var/www/certbot
entrypoint: ["/bin/sh","-c"]
command: "sleep infinity"
Nginx設定のポイント
・証明書と鍵は /etc/letsencrypt/live/ドメイン/ に置かれます。Nginxのssl_certificateにそのパスを指定してください。
・HTTPチャレンジを使う場合、webrootは /var/www/certbot に合わせます。
証明書の取得と更新
初回取得例:
docker-compose run --rm certbot \
certonly --webroot -w /var/www/certbot \
-d example.com -m you@example.com --agree-tos --no-eff-email
更新は定期的に docker-compose run --rm certbot renew を実行し、その後 docker-compose restart nginx で反映します。
注意点
・ファイル権限に注意してください。ホスト側のパーミッションでNginxが読める必要があります。
・80/443ポートを開放しておいてください。
・自動化するならcronやホストのシステムdで定期実行すると便利です。
リバースプロキシとしてのSSL設定
概要
複数のバックエンドをNginxで公開するとき、SSLはNginx側で終端(TLS終端)するのが一般的です。ここではサブドメインごとの証明書と、単一ドメインでパスごとに複数サービスをルーティングする方法を具体例で示します。
サブドメインごとの証明書設定
サブドメイン毎に別証明書を使う場合は、SNIによりNginxがホスト名に応じて証明書を選びます。例:
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://api_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
同様に www.example.com や admin.example.com 用の server ブロックを用意します。静的ファイルやキャッシュ設定は各ブロックで調整してください。
パスベースで単一ドメインの下にルーティング
一つの証明書で複数サービスを公開する場合、パスで振り分けます。例:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location /api/ {
proxy_pass http://api_upstream/;
proxy_set_header Host $host;
}
location /app/ {
proxy_pass http://app_upstream/;
proxy_set_header Host $host;
}
}
パス書き換えが必要な場合は proxy_pass の末尾スラッシュや rewrite を使って正しく転送します。
共通の注意点
- HTTPは自動でHTTPSへリダイレクトしてください(listen 80 で return 301 https://$host$request_uri;)。
- 証明書チェーンと権限(ファイルパーミッション)を確認してください。
- proxy_set_header で Host と X-Forwarded-* を渡し、バックエンドが元のホストやクライアントIPを得られるようにします。
- WebSocketや長時間接続では proxy_read_timeout を調整します。
この章では設定の実例を示しました。運用時はログや証明書の自動更新(例: certbot renew)も組み合わせると安心です。
HTTPSアクセスの動作確認
確認手順の流れ
NginxでSSLを設定したら、まず実際にHTTPSでサイトにアクセスして動作を確かめます。順を追って簡単に確認します。
ブラウザでの確認
- ブラウザのアドレスバーにhttps://your-domain.exampleを入力します。
- 鍵マーク(南京錠)が表示されれば基本は成功です。クリックすると証明書の発行者、有効期限、対象ドメインを確認できます。
- ページ内の画像やスクリプトがhttpで読み込まれていると「混在コンテンツ」警告が出ます。必要ならソースを修正してください。
コマンドラインでの確認
- curlで接続確認: curl -I https://your-domain.example でHTTPステータスとTLSハンドシェイクの簡単な確認ができます。
外部サービスでの評価
- SSL Labs(https://www.ssllabs.com/ssltest/)などにドメインを入力すると、証明書チェーン、プロトコル、脆弱性の評価を受けられます。総合スコアで弱点を把握できます。
よくある問題と対応
- 鍵マークが表示されない:中間証明書が未設定の場合があります。チェーンを確認し、nginxに中間証明書を結合したファイルを指定してください。
- リダイレクトが効かない:HTTP→HTTPSのリダイレクト設定を再確認します。
これらの手順で公開前にHTTPS動作をしっかり確認してください。
パフォーマンス最適化
概要
HTTP/2で同時リクエストを効率化し、Nginx 1.25.0以降ではHTTP/3(QUIC)も利用できます。ここでは有効化例と実運用で効くチューニングを分かりやすく解説します。
HTTP/2の有効化
Nginxでの有効化は簡単です。サーバーブロックに以下を追加します。
listen 443 ssl http2;
ssl_certificate /etc/ssl/example.crt;
ssl_certificate_key /etc/ssl/example.key;
これでブラウザは1つの接続で複数リクエストを並列処理します。静的ファイルの読み込みが速くなります。
HTTP/3(QUIC)の設定例
HTTP/3はTLS 1.3を必須にします。基本例:
listen 443 quic reuseport;
ssl_protocols TLSv1.3;
ssl_certificate ...;
ssl_certificate_key ...;
add_header Alt-Svc 'h3=":443"';
利用にはNginxを対応ビルドで用意してください。
チューニング例(実践的)
- TLSセッション再利用:ssl_session_cache shared:SSL:10m;
- OCSP stapling:ssl_stapling on; ssl_stapling_verify on;
- ファイル送信最適化:sendfile on; tcp_nopush on; tcp_nodelay on;
- 圧縮:gzip on; または brotli を検討
- ワーカー設定:worker_processes auto; worker_connections 1024;
注意点
QUICはUDPを使います。ファイアウォールやロードバランサ設定を確認してください。プロダクション投入前にブラウザ互換性とフォールバック動作を必ず確認します。












