背景
本番でSSL通信するなら、ローカルの環境でもちゃんとSSLで開発をやるべきだよね。
前提
- 環境差異によるバグをへらす為に、Dockerコンテナを本番のAWS環境とローカル環境の双方で共通化。
- ローカルではdocker-composeを利用し、AWSではbuildspecで環境変数等はコントロール。
- AWS上ではALBを介す為、ALBでSSL証明書を管理し、コンテナへは80番ポートでアクセスする。
方法
AWS ALBの代替えとしてnginx-proxyを使います。
Let's EncryptでSSL化する場合はnginx-proxy推奨で、letsencrypt-nginx-proxy-companionというコンテナイメージがあります。
このコンテナはnginx-proxy同様に環境変数を設定するだけで自動でLet's Encryptの証明書を取得してくれます。
docker-compose.yml
version: '3.3'
services:
#--------------
# Proxy
#--------------
nginx-proxy:
image: jwilder/nginx-proxy
environment:
- "DHPARAM_GENERATION=false"
privileged: true
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- proxy:/usr/share/nginx/html
- proxy:/etc/nginx/vhost.d
- ./docker/encrypt/certs:/etc/nginx/certs:ro
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
#--------------
# letsencrypt
#--------------
letsencrypt-nginx:
image: jrcs/letsencrypt-nginx-proxy-companion
privileged: true
environment:
- NGINX_PROXY_CONTAINER=nginx-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- proxy:/etc/nginx/vhost.d
- proxy:/usr/share/nginx/html
- ./docker/encrypt/certs:/etc/nginx/certs:rw
depends_on:
- nginx-proxy
#--------------
# App
#--------------
app:
build:
context: .
dockerfile: ./docker/app/Dockerfile
environment:
- VIRTUAL_HOST=${APP_HOST}
- LETSENCRYPT_HOST=${APP_HOST}
- LETSENCRYPT_EMAIL=${APP_ADMIN_EMAIL}
- CERT_NAME=default
volumes:
- .:/var/www
volumes:
proxy:
今回のポイントは下記
- CERT_NAME=default
Let's Encryptで証明書を生成する場合、認証サーバーと通信を行い、認証サーバーから所有確認の為に、該当サーバーにアクセスを行います。ローカルだと、そのアクセスができない為、ドメインが指定された証明書を発行できません。
なので、オレオレ証明書として、default.certを吐き出してくれるので、それを利用します。