Rails&pumaで、開発と本番の両方の環境でSSL化をしたくなることがあると思います。
私の場合、ローカルは自己証明書、本番は認証局で登録されている正式な証明書を使いSSL化をしようかなと考えていました。そのためにはNginxのconfファイルに記載する各証明書のパスは開発と本番では別になるため、その部分だけ環境変数で使い分けをしようということになりました。
その時に行った実装手順をメモします。
前提
やり方は、環境変数名を記載したファイルから、環境変数に代入した値に変換されたファイルを生成するenvsubstというコマンドを使用します。
実装手順
環境変数は${SSL_CERTIFICATE_PATH}
のように記述する。
※下記のファイルでは、${SSL_CERTIFICATE_PATH}
と${SSL_CERTIFICATE_KEY_PATH}
の2つを記述しています。
upstream app {
server unix:///app/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate ${SSL_CERTIFICATE_PATH}; # 環境変数
ssl_certificate_key ${SSL_CERTIFICATE_KEY_PATH}; # 環境変数
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /app/public;
location / {
proxy_pass http://app;
proxy_set_header X-Real-IP $remote_addr;
index index.html index.htm;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
client_max_body_size 100m;
error_page 404 /404.html;
error_page 505 502 503 504 /500.html;
try_files $uri/index.html $uri @app;
keepalive_timeout 5;
}
Dockerfileにて、default.conf.templateを配置する。
FROM nginx:1.16
RUN apt-get update && \
apt-get install -y apt-utils \
locales && \
echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen ja_JP.UTF-8
ENV LC_ALL ja_JP.UTF-8
# 初期状態の設定ファイル
ADD ./docker/nginx/nginx.conf /etc/nginx/nginx.conf
ADD ./docker/nginx/default.conf.template /etc/nginx/conf.d/default.conf.template
変換する環境変数をnginxサービスのcommandキーのように指定し、envsubstを動くようにする。
環境変数に代入する値はenvironmentキーで設定する。
version: '2'
services:
app:
# ・・・省略
db:
# ・・・省略
nginx:
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
ports:
- '80:80'
- '443:443'
volumes:
- sockets:/app/tmp/sockets
- ./docker/nginx/ssl:/etc/nginx/ssl
depends_on:
- app
command: /bin/sh -c "envsubst '$$SSL_CERTIFICATE_PATH $$SSL_CERTIFICATE_KEY_PATH'< /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
environment:
SSL_CERTIFICATE_PATH: /etc/nginx/ssl/server.crt
SSL_CERTIFICATE_KEY_PATH: /etc/nginx/ssl/server.key
# ・・・省略
下記のコマンドでコンテナを立ち上げる時、envsubstコマンドが実行され、環境変数名を記載したファイル(default.conf.template)から、環境変数に代入した値に変換されたファイル(default.conf)が生成されました。
$ docker-compose up -d
参考
envsubstを使ってDockerで設定ファイルに環境変数を埋め込めこむ汎用的なパターン - Qiita
さいごに
パスとファイル名さえ間違えなければ躓くことは無いのではないかと思います。
本番環境でもうまくいくようにこれから試してみます。