Nginx environment variable substitution with Docker for SaaS apps

Stefan Pöltl
2 min readNov 16, 2021

Software as a service apps should store configuration values in environment variables when you rely on the twelve-factor app Saas guide. The twelve-factor rule says you should seperate config from your code, because configuration varies across environment stages: https://12factor.net/config

Since nginx version 1.19 it’s possible to replace values in nginx config files with given environment variables. This eases the build of self designed Dockerfiles for your nginx server dramatically. Let’s take a look at a simple example with docker compose:

version: '3.9'
services:
nginx:
image: nginx:1.19-alpine
ports:
- "8080:80"
environment:
FCGI_HOST: php
volumes:
- ./:/var/www/html:ro
- ./docker/vhost.template:/etc/nginx/templates/default.conf.template
php:
image: webdevops/php:8.0-alpine
working_dir: /var/www/html

Our local vhost.template file looks like this:

server {
server_name server_name _;
listen 80 default_server;
root /var/www/html/web;
index index.php;

location / {
try_files $uri /index.php$is_args$args;
}

location ~ \.php$ {
fastcgi_pass ${FCGI_HOST}:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
}

The final result will have the Fastcgi host replaced by the value of the given environment variable and your good to go on every deployment stage.

Let’s take a look under the hood

First of all it’s important to mention that you need to use the official Nginx Docker image to have this feature supported.

Before the nginx server gets started the binary envsubst gets executed and replaces the environment variables in the config files. The command reads all files mounted to /etc/nginx/templates/*.template, tries to replace env variables in the templates and outputs the config files in /etc/nginx/conf.d/*.conf.

It’s possible to adjust the behaviour a bit with the following env variables passed to your nginx container:

  • NGINX_ENVSUBST_TEMPLATE_DIR -> Folder in the image where you mount your templates (default: /etc/nginx/templates)
  • NGINX_ENVSUBST_TEMPLATE_SUFFIX -> Your template files need to end with the right suffix (default: .template)
  • NGINX_ENVSUBST_OUTPUT_DIR -> Output directory where the processed files are written to as config files (default: /etc/nginx/conf.d)

As you can see, the official nginx image is really powerful to support professional SaaS development. Go and follow standards like the twelve-factor config rule to ease your daily development job and improve the flexibility of your applications.

--

--