Docker container で nginx を起動するときとか、nginx.conf で何かしらのパラメータを動的に設定したいことがあると思います。server_name
とか。
今回は nginx.conf で何とかして環境変数を読み込む手法を紹介します。
TL;DR
__env
ディレクティブ__と ngx_http_perl_module (or lua_nginx_module) を使って、環境変数を nginx 変数に設定する。
Example
server_name
を環境変数 SERVER_NAME
から動的に読み込む例を示します。
user nginx;
worker_processes 4;
env SERVER_NAME;
http {
perl_set $server_name_from_env 'sub { return $ENV{"SERVER_NAME"}; }';
# ...
server {
server_name $server_name_from_env;
# ...
}
}
こうしておけば、docker run -e SERVER_NAME=hoge.example.com hoge/nginx
みたいに都度 SERVER_NAME
を設定できます。
くわしく
nginx は起動時に親プロセスの環境変数を引き継ぎません。ですが、env
ディレクティブを使えば特定の環境変数を nginx に引き継がせることができます。
env
ディレクティブは main コンテキスト、つまり user
とかと同じ階層でのみ宣言できます。
env ENV_NAME
このまま $ENV_NAME
みたいに参照できたら良いのですが、nginx はそれほど親切に作られていません。ここで読み込んだ環境変数を何らかの方法で nginx 変数に代入してやる必要があります。
そこで、perl_set
ディレクティブを用いて Perl スクリプト経由で nginx 変数に代入します。
perl_set
は ngx_http_perl_module に含まれているため、素の nginx では使えません。nginx ビルド時に入れてやる必要があります。
./configure --with-http_perl_module
perl_set
は Perl スクリプトの戻り値を nginx 変数に代入します。今回は環境変数 ENV
を読み込んで返すだけの簡単なスクリプトを用います。あと、代入先の変数名と環境変数名は分けてやる必要があります。環境変数名に _from_env
とか付けたのを nginx 変数名にしときましょう。
perl_set
ディレクティブは http コンテキストでのみ宣言できます。
http {
perl_set $env_name_from_env 'sub { return $ENV{"ENV_NAME"}; }';
# ...
}
最後に、設定したいパラメータにて上記の nginx 変数を入れてやれば ok です。
hoge_param $env_name_from_env
環境変数で動的に設定できないもの
http コンテキストで初めて nginx 変数に読み込める以上、main コンテキストで設定するパラメータについては上記の手法が使えません。
例えば以下のようなもの、
user
worker_processes
どうしてもこれらのパラメータを動的設定したい場合は、sed とか ERB を使って nginx.conf 自体を動的生成する必要があるでしょう。
あわせて読みたい
-
http://nginx.org/en/docs/ngx_core_module.html#env
-
env
ディレクティブについての公式リファレンス
-
-
https://www.ruby-forum.com/topic/2583637
- Lua 経由で設定する例。すでに lua_nginx_module をロードしているならこっちの方が良いかも。
-
http://heartbeats.jp/hbblog/2014/07/3-tips-for-nginx-on-docker.html
-
perl_set
とset_by_lua
両方についての説明
-