Nginxの設定ファイルに環境変数を埋め込むための2つの方法【envsubstで動的生成するか、Luaで変数を定義するか】
最近はNginxの設定ファイルを書く機会が多く、その中で環境変数をconfファイルに埋め込みたい場面に遭遇しました。
Nginxはデフォルトで環境変数の埋め込みをサポートしておらず、例えば開発環境時と本番稼働時でプロキシの向き先を変更したい場合などは一工夫が必要になります。
大きく分けて2つの方法からこれを実現できるので、その対策法を紹介します。
どんなアプローチになるのか
方針としては以下の2つになります。
- envsubstコマンドを使って、confファイルを動的に生成する
- LuaやPerlの組み込みモジュールを使って動的に値を設定する
結論からいうと、環境変数を埋め込むニーズだけを達成するのならば「1」のenvsubstを使う方がシンプルですが、既にLuaやPerlのモジュールを導入している場合は一つのconfファイルで完結するのでこちらを採用するのもアリかもしれません。
envsubstコマンドを使って、confファイルを動的に生成する
envsubst
はgettextに付随したライブラリで、削りに削られたAlpineでも利用できます。(ただしMacの場合はbrew install gettext
でインストールする必要があります)
envsubstを利用すると、以下のようなコマンドから変数を環境変数に置き換えてくれます。
envsubst < nginx.conf.template > nginx.conf
<
によって読み込まれたテンプレートファイルの中にある$
がついた変数を環境変数に置き換えて、>
で指定されたファイルに出力します。
通常のファイルならばこれだけでも十分ですが、nginxの場合はconfファイルに$uriといった$
マークがついた変数を利用していることが多く、envsubstに全ての置き換えを任せてしまうと、置換してほしくないところまで書き換えられてしまいます。
そんな時は置き換えを行う変数名だけを指定すると良いでしょう。
envsubst '$$variable_name1 $$variable_name2'< nginx.conf.template > nginx.conf
変数名の指定は「'$$~'」の箇所でここにはスペース区切りで複数の変数を指定することができます。
それでは実際にenvsubstを使った置き換えを見てみましょう。
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
server_name localhost;
listen 80;
location / {
rewrite ^(.*)$ http://test.com$uri redirect;
}
location ^~ / {
proxy_pass $API_ROOT;
}
}
}
export API_ROOT=my-api.com
envsubst '$$API_ROOT'< nginx.conf.template > nginx.conf
これを実行すると、以下のようなnginx.confが出力されます。
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
server_name localhost;
listen 80;
location / {
rewrite ^(.*)$ http://test.com$uri redirect;
}
location ^~ / {
proxy_pass my-api.com;
}
}
}
$API_ROOT
が環境変数で指定された「my-api.com」に変わっており、指定されていない$uriの箇所はそのままになっていますね👍
例えばdocker build
を行う前にenvsubstを用いてconfファイルを作成してから、Dockerfile内で作成したconfファイルをコピーすれば、擬似的に環境変数の動的な埋め込みが実現されるでしょう。(もちろんDockerの使用に限定されるわけではありません)
LuaやPerlの組み込みモジュールを使って動的に値を設定する
LuaやPerlから値を動的に定義しますが、これを実現するにはnginxのモジュールを入れなければなりません。
Luaの場合はOpenRestyというNginxの拡張版を用いることが多く、こちらのDockerイメージを使えば通常のNginxと(ほとんど)同様のものに加えて、Lua Moduleが標準で入っているので組み込み機能をすぐに利用できます。
(そもそもLuaとは組み込みに特化した軽量な言語のことで、動的型付けにも関わらずJavaと同等程度の速度を誇ります)
Perlも同様にモジュールを通じて利用しますが、nginxの公式イメージの中にperlタグがついたものがあるので、こちらを利用することになります。
ただしPerlの場合はAlpineではないので容量がかなり大きくなり、OpenRestyはAlpineだと十分軽量なので、容量を気にされる場合はOpenRestyを使うのがオススメです。
イメージ | 容量 |
---|---|
nginx:alpine | 約16MB |
nginx:perl | 約148MB |
openresty:alpine | 約23MB |
なおLuaやPerlを使って変数を設定するのはとても簡単です。
Luaを使うパターン
env SERVER_NAME;
http {
set_by_lua $API_ROOT 'return os.getenv("API_ROOT")';
}
Perlを使うパターン
env SERVER_NAME;
http {
perl_set $API_ROOT 'sub { return $ENV{"API_ROOT"}; }';
}
こうして一度セットされた変数は「$API_ROOT」のような形で参照できるので、後は通常のconfファイルと同様に記述すれば問題ありません。
ちなみにenv
はmainコンテキスト、set_by_lua
とperl_set
はhttpコンテキスト内にのみ定義できます。
最後に
Dockerコンテナ内にNginxを配置する場合、Dockerfileで処理を分岐できないために、Develop用・Production用と複数のconfファイルを用意するケースを見かけますが、以上で紹介した方法を活用することで動的に値を埋め込むことができます。
envsubstはLinux系ならばほぼ全てに付属しているパッケージなので、ぜひ活用してみてください。
Author And Source
この問題について(Nginxの設定ファイルに環境変数を埋め込むための2つの方法【envsubstで動的生成するか、Luaで変数を定義するか】), 我々は、より多くの情報をここで見つけました https://qiita.com/ttiger55/items/5d66108c56554889d8b8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .