nginx: use environment variables
Solution 1
The correct usage would be $SOME_IP_from_env
, but environment variables set from nginx.conf cannot be used in server, location or http blocks.
You can use environment variables if you use the openresty bundle, which includes Lua.
Solution 2
With NGINX Docker image
Apply envsubst
on template of the configuration file at container start. envsubst
is included in official NGINX docker images.
Environment variable is referenced in a form $VARIABLE
or ${VARIABLE}
.
nginx.conf.template:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
access_log off;
return 200 '${MESSAGE}';
add_header Content-Type text/plain;
}
}
}
Dockerfile:
FROM nginx:1.17.8-alpine
COPY ./nginx.conf.template /nginx.conf.template
CMD ["/bin/sh" , "-c" , "envsubst < /nginx.conf.template > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"]
Build and run docker:
docker build -t foo .
docker run --rm -it --name foo -p 8080:80 -e MESSAGE="Hellou World" foo
NOTE:If config template contains dollar sign $
which should not be substituted then list all used variables as parameter of envsubst
so that only those are replaced. E.g.:
CMD ["/bin/sh" , "-c" , "envsubst '$USER_NAME $PASSWORD $KEY' < /nginx.conf.template > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"]
Nginx Docker documentation for reference. Look for Using environment variables in nginx configuration.
Using environment variables in nginx configuration
Out-of-the-box, nginx doesn’t support environment variables inside most configuration blocks. But envsubst may be used as a workaround if you need to generate your nginx configuration dynamically before nginx starts.
Here is an example using docker-compose.yml:
web: image: nginx volumes: - ./mysite.template:/etc/nginx/conf.d/mysite.template ports: - "8080:80" environment: - NGINX_HOST=foobar.com - NGINX_PORT=80 command: /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
The
mysite.template
file may then contain variable references like this:
listen ${NGINX_PORT}
;
Solution 3
You can access the variables via modules - I found options for doing it with Lua and Perl.
Wrote about it on my company's blog:
The TL;DR:
env API_KEY;
And then:
http {
...
server {
location / {
# set var using Lua
set_by_lua $api_key 'return os.getenv("API_KEY")';
# set var using perl
perl_set $api_key 'sub { return $ENV{"API_KEY"}; }';
...
}
}
}
EDIT: original blog is dead, changed link to wayback machine cache
Solution 4
Since nginx 1.19 you can now use environment variables in your configuration with docker-compose. I used the following setup:
# file: docker/nginx/templates/default.conf.conf
upstream api-upstream {
server ${API_HOST};
}
# file: docker-compose.yml
services:
nginx:
image: nginx:1.19-alpine
environment:
NGINX_ENVSUBST_TEMPLATE_SUFFIX: ".conf"
API_HOST: api.example.com
I found this answer on other thread: https://stackoverflow.com/a/62844707/4479861
schickling
Updated on July 09, 2022Comments
-
schickling almost 2 years
I have the following scenario: I have an env variable
$SOME_IP
defined and want to use it in a nginx block. Referring to the nginx documentation I use theenv
directive in thenginx.conf
file like the following:user www-data; worker_processes 4; pid /run/nginx.pid; env SOME_IP;
Now I want to use the variable for a
proxy_pass
. I tried it like the following:location / { proxy_pass http://$SOME_IP:8000; }
But I end up with this error message:
nginx: [emerg] unknown "some_ip" variable
-
schickling about 10 yearsThanks! But is there no option to use variables defined in
nginx.conf
in server blocks? -
Ben Whaley about 10 yearsIn a server block you an use the syntax
set $var "value";
and then refer to $var throughout your configuration. But you cannot use env vars. -
lsl about 7 yearsSaving people some time (the above requires a custom build), you can use a template and a tool called envsubst serverfault.com/a/755541/116508 did this for docker and it works, just specify the env vars or you might wipe out vars in nginx unintentionally e.g.
$host
-
HermanTheGermanHesse over 4 yearsThe link seems not to lead to where you probably wanted it to lead :)
-
Kajsa about 4 yearsIs there a way to check the output when launching this config through a helm install?
-
kikito about 4 years@Kajsa you might want to make that comment into a SO question (with proper tags like
helm
etc). It will get more visibility and more chances of being answered by someone with Helm knowledge (which I am not). -
Hunter_71 over 3 yearsIt's worth to mention, that: 1) it uses a template files 2) template files should be created inside
/etc/nginx/templates/
with defined suffix 3) after replacing env vars it automatically creates target configuration file insideconf.d
without suffix (conf.d/default.conf
for this example) 4) default template extension is.template
5) more can be found inside original answer :) -
Ilya Kolesnikov about 3 yearsIt is not a feature of nginx itself but of it's official docker container, description is here hub.docker.com/_/nginx in paragraph "Using environment variables in nginx configuration (new in 1.19)"
-
Marc almost 3 yearsWhat is this
_from_env
suffix?? -
Tobias over 2 yearsI like that solution, however it didn't work at the beginning, although I followed @Hunter_71's tips. That's because the Docker container has to start the
docker-entrypoint.sh
script in order to runenvsubst
which does the actual replacement. I had aCMD
command defined in my Dockerfile, which makes the defaultENTRYPOINT
obsolete. Removing my CMD and placing it in a script which I copied to the/docker-entrypoint.d/
directory resolved the issue. Scripts in that directory are automatically executed by the defaultdocker-entrypoint.sh
. -
lance-java over 2 yearsUnfortunately my nginx.conf contained some dollar signs which I didn't want replaced so had to pass an explicit list to envsubst . Would be nice if envsubst was smart enough to only replace values which are set in the environment
-
protocod about 2 yearsNot a good idea, envsubst will substitute default env used by nginx.