Substitute environment variables in NGINX config from docker-compose
You can avoid some of the hassles with Compose interpreting environment variables by defining your own entrypoint. See this simple example:
- entrypoint.sh (make sure this file is executable)
#!/bin/sh
export NGINXPROXY
envsubst '${NGINXPROXY}' < /config.template > /etc/nginx/nginx.conf
exec "$@"
- docker-compose.yml
version: "3.7"
services:
front-end:
image: nginx
environment:
- NGINXPROXY=172.31.67.100:9300
ports:
- 80:80
volumes:
- ./config:/config.template
- ./entrypoint.sh:/entrypoint.sh
entrypoint: ["/entrypoint.sh"]
command: ["nginx", "-g", "daemon off;"]
My config
file has the same content as your nginx.conf
, aside from the fact that I had to comment the lines using the Perl module.
Note that I had to mount my config file to another location before I could envsubst
it. I encountered some strange behaviour in the form that the file ends up empty after the substitution, which can be avoided by this approach. It shouldn't be a problem in your specific case, because you already embed it in your image on build time.
EDIT
For completeness, to change your setup as little as possible, you just have to make sure that you export
your environment variable. Adapt your command like this:
command: ["/bin/bash", "-c", "export NGINXPROXY && envsubst '$$NGINXPROXY' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"]
...and you should be good to go. I would always recommend the "cleaner" way with defining your own entrypoint, though.
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
volumes:
- "./docker/nginx/templates:/etc/nginx/templates/"
environment:
NGINX_ENVSUBST_TEMPLATE_SUFFIX: ".conf"
API_HOST: api.example.com
I'm going off script a little from the example in the documentation. Note the extra .conf
extension on the template file - this is not a typo. In the docs for the nginx image it is suggested to name the file, for example, default.conf.template
. Upon startup, a script will take that file, substitute the environment variables, and then output the file to /etc/nginx/conf.d/ with the original file name, dropping the .template
suffix.
By default that suffix is .template
, but this breaks syntax highlighting unless you configure your editor. Instead, I specified .conf
as the template suffix. If you only name your file default.conf
the result will be a file named /etc/nginx/conf.d/default and your site won't be served as expected.