How can I use environment variables in Nginx.conf
From the official Nginx docker file:
Using environment variables in nginx configuration:
Out-of-the-box, Nginx doesn't support using 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:
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 && nginx -g 'daemon off;'"
The mysite.template file may then contain variable references like this :
listen ${NGINX_PORT};
Update:
But you know this caused to its Nginx variables like this:
proxy_set_header X-Forwarded-Host $host;
damaged to:
proxy_set_header X-Forwarded-Host ;
So, to prevent that, i use this trick:
I have a script to run Nginx, that used on the docker-compose
file as command option for Nginx server, i named it run_nginx.sh
:
#!/usr/bin/env bash
export DOLLAR='$'
envsubst < nginx.conf.template > /etc/nginx/nginx.conf
nginx -g "daemon off;"
And because of defined new DOLLAR
variable on run_nginx.sh
script, now content of my nginx.conf.template
file for Nginx itself variable is like this:
proxy_set_header X-Forwarded-Host ${DOLLAR}host;
And for my defined variable is like this:
server_name ${WEB_DOMAIN} www.${WEB_DOMAIN};
Also here, there is my real use case for that.
The official nginx image recommends using envsubst
, but as pointed out by others it will replace also $host
and other variables, which is not desirable. But fortunately envsubst
can take as a parameter the names of variables to replace.
To avoid a very complex command parameter to the container (as in the linked example), you can write a Docker entrypoint script which will fill in the environment variables before executing the command. The entrypoint script is also a good place for validating the parameters and setting default values.
Here is an example of an nginx container which takes in API_HOST
and API_PORT
parameters as environment variables.
nginx-default.conf.template
resolver 127.0.0.11 valid=10s; # recover from the backend's IP changing
server {
listen 80;
location / {
root /usr/share/nginx/html;
}
location /api {
proxy_pass http://${API_HOST}:${API_PORT};
proxy_set_header Host $http_host;
}
}
docker-entrypoint.sh
#!/usr/bin/env sh
set -eu
envsubst '${API_HOST} ${API_PORT}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
exec "$@"
Dockerfile
FROM nginx:1.15-alpine
COPY nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]