Opened 5 years ago
Last modified 4 years ago
#1785 new enhancement
Support access to environment variables in config file
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | other | Version: | 1.15.x |
Keywords: | Cc: | ||
uname -a: | |||
nginx -V: |
nginx version: nginx/1.10.3
built with OpenSSL 1.1.0f 25 May 2017 (running with OpenSSL 1.1.0j 20 Nov 2018) TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-0TiIP5/nginx-1.10.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-0TiIP5/nginx-1.10.3/debian/modules/nginx-auth-pam --add-dynamic-module=/build/nginx-0TiIP5/nginx-1.10.3/debian/modules/nginx-dav-ext-module --add-dynamic-module=/build/nginx-0TiIP5/nginx-1.10.3/debian/modules/nginx-echo --add-dynamic-module=/build/nginx-0TiIP5/nginx-1.10.3/debian/modules/nginx-upstream-fair --add-dynamic-module=/build/nginx-0TiIP5/nginx-1.10.3/debian/modules/ngx_http_substitutions_filter_module |
Description
Currently nginx doesn't directly support access to environment variables in the config file. This makes it difficult to use it in a 12-factor-app style setup, where the docker container / VM / machine image use environment variables for configuring things such as static assets.
One way to work around this is to use envsubst
to generate the config file on the fly. However, that means the target config file needs to be writable.
Another one would be to use something like ngx_http_lua_module. The process is two step: first, prevent the variable from being filtered out:
env MY_STATIC_ASSETS_PATH;
Then, set a variable using nginx syntax:
http { ... server { location /static { # set var using Lua set_by_lua $static_assets 'return os.getenv("MY_STATIC_ASSETS_PATH")'; alias "$static_assets" ... } } }
Since using the lua module seems heavy-handed for something like this, I'd like to propose a set_from_env directive that does exactly that. The result would be:
http { ... server { location /static { # set var using built in directive set_from_env $static_assets MY_STATIC_ASSETS_PATH; alias "$static_assets" ... } } }
+1 for this, here is our use-case:
In a kubernetes environment where we need a fixed configuration common across development, test and production environments. In Kubernetes any additional deployment-specific configuration is essentially passed to the application by environment variables set at startup.
Sometimes (this is just one example, there are other use cases) rewrites to environment-specific services are required, eg. dev must proxy for "service-X-dev" in dev, test for "service-X-tst" in test, and so forth - "service-X" might not even be in kubernetes yet. If our nginx config could read environment values, this can become straightforward and easy to understand.
I'm not saying there aren't other solutions to the above, but ability to configure map{...} output or variable value on the basis of an env variable can make this a lot easier. We don't really want to have pre-launch init script which reads the environment and generates a fragment of Nginx config file from it, it's a hacky solution and as the OP states, requires writing to the image filesystem.
We can't use the Lua module for info-security reasons - the whole point of choosing Nginx is for a small attack surface with minimal additional modules.
A directive something like this, probably in outermost context{...} scope, would likely suffice:
This would then only get evaluated once when first used after startup and be available therafter in all child scopes.