Long title, right? π
We have a need to pass in environment variables into a Docker Container and use them to do some string replacement (substitution) within the application code. This allows for greater reuse of the container between environments.
This is a test to see how this can be done.
The NGINX Docker Image provides the ability to do string substitution using envsubst
. They have wired it up so that a special template directory
with .template
files that will automap to environmental variables used within the file.
NOTE: The scope of this integration with the
template directory
is limited to NGINX config files.
In this example TEST_ENV="exists"
gets passed into the container.
# NGINX Config
...
location /env {
add_header Content-Type application/json;
return 200 '{
"TEST_ENV": "${TEST_ENV}"
}';
}
...
# NGINX Config
...
location /env {
add_header Content-Type application/json;
return 200 '{
"TEST_ENV": "exists"
}';
}
...
To make this work, we have added references to the environment variables in our nginx.conf
file. When the Dockerfile
is built, it copies the nginx.conf
file into the templates directory
specified for the container and appends .template
to the file name per requirements.
Due to envsubst
returning an empty string on environmental variables not found, and our need for template literals within the same that use the same format as environmental variables, we need a way to specify variables that are allowed to be process.
To do this we leveraged a feature within envsubst
that allows specifiying a list of environmental variables to use. In doing so, it will ignore the rest.
To get this to run, we wrote a bash script (05-set-env.sh) that is called when the container boots up. This is leveraging a feature also built in to the NGINX Container. If you add a script to the /docker-entrypoint.d/
director and make it executable (done in the Dockerfile
), it will run on container boot. In this case allowing us to pass in environmental variables to Docker and then using them in this script to process some files.
# From 05-set-env.sh
# Note: The first argument is a comma-delimited list.
envsubst '$TEST_ENV' < /frontend/index.html > /tmp/index.html.temp && cp -f /tmp/index.html.temp /frontend/index.html
In this example TEST_ENV="exists"
gets passed into the container.
<!-- Sample from ./dist/index.html -->
<p>Replace Env Var: ${TEST_ENV}</p>
<p>Do Not Replace Template Literal: ${TEMPLATE_LITERAL}</p
<!-- Sample from ./dist/index.html -->
<p>Replace Env Var: exists</p>
<p>Do Not Replace Template Literal: ${TEMPLATE_LITERAL}</p
To run the project, clone the repository, and make sure Docker is running.
From your terminal, navigate to the project directory and run the following commands.
docker build -t nginx-envsubst .
docker run -it -p 8080:80 -e TEST_ENV="exists" nginx-envsubst
If all goes well, you should be able to see the string substitution working at the following URL's.