経緯
nginxの環境変数の扱いに思ったより手こずったので、記録を残しておきます。
本番環境とステージング環境はほぼほぼ一緒なので、一緒の設定で、環境変数を使って使い分けられないかと思いました。
ただ、docker composeを用いているので、いつものようにenvファイル等で指定しても動かない...
解決法1
nginx v1.9以前の設定です。
まず、nginx.confのtemplateファイルを作成します。
利用したい環境変数を、${ENV_VAR}
のような形で指定します。
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream my-app-1 {
server my-app-1:${PORT};
}
そして、envsubstで置換します。注意点は、nginx.conf
では、$host
のような記述がデフォルトでサポートされており、envsubstではそれも環境変数として認識されてしまいます。置換する環境変数の値だけを変えたい場合は以下のように設定できます。
envsubst '$$PORT' < nginx.conf.template > nginx.conf
そして、docker composeで起動時のエントリポイントをこのbashを実行するように設定してあげます。
version: '2'
services:
nginx:
image: nginx:alpine
command: >
/bin/sh -c
"envsubst '
$$NGINX_SERVER_NAME
$$NGINX_UPSTREAM_HOST
$$NGINX_UPSTREAM_PORT
'< /etc/nginx/nginx.conf.template
> /etc/nginx/nginx.conf
&& nginx -g 'daemon off;'"
volumes:
- ./nginx.conf.template:/etc/nginx/nginx.conf.template
ports:
- 8080:80
environment:
NGINX_SERVER_NAME: "test.example.com"
NGINX_UPSTREAM_HOST: "hoge"
NGINX_UPSTREAM_PORT: "80"
ちなみに、bashファイルを作成する方法もあります。
#!/bin/sh
envsubst '$$PORT' < nginx.conf.template > nginx.conf
version: '2'
services:
nginx:
image: nginx:alpine
command: "chmod +x /docker-entrypoint.d/sample.sh"
volumes:
- ./nginx.conf.template:/etc/nginx/nginx.conf.template
- ./sample.sh:/docker-entrypoint.d/sample.sh
ports:
- 8080:80
でも上記の方法だと、ステージングと本番で環境変数を渡すbashを別々に作らないといけないような気がします...
解決法2
のちに知ったのですが、dockerのnginxでは、 v1.9以上 だと、自動的にnginx.conf.tamplate
ファイルを、自動的に置換するスクリプトが動きます。
templateフォルダを作成し、nginx.conf.tamplate
をtamplateフォルダ配下におきます。
そして、以下のように/etc/nginx/templates
にマウントすることでenvsubstで処理されます。
version: "3"
services:
nginx:
image: nginx:1.21.4
volumes:
- ./templates:/etc/nginx/templates
ports:
- "8080:80"
environment:
- NGINX_HOST=localhost
- NGINX_PORT=80
- PHP_HOST=php
置換されたファイルは/etc/nginx/conf.d/
フォルダに作成されます。
最後に
実際にやってみて、やっぱり2番目の解決法が1番目と比べて楽でした。
バージョンアップ大切。
参考文献