Locally when running docker with docker run
I pass some arguments like:
docker run -p 8080:80 -e "SERVICE_B_URL=somehost.co.uk" -d mynginx:latest /bin/sh -c "envsubst '\${SERVICE_B_URL}' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
This works fine. In my /etc/nginx/conf.d/default.conf
the string ${SERVICE_B_URL}
is replaced with somehost.co.uk
.
When running on AWS fargate with a definition like:
"environment": [
{
"name": "SERVICE_B_URL",
"value": "someotherhost.co.uk"
}
],
"command": [
"/bin/sh",
"-c",
"envsubst '\\${SERVICE_B_URL}' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
],
The \\
was to escape the \
in the JSON file.
When trying to run, the container exits with an error because NGINX is seeing the literal string ${SERVICE_B_URL}
. When I inspect the container and see the command AWS used to start the container it is:
Command ["/bin/sh","-c","envsubst '\\' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]
Notice that Fargate has attempted to expand the string '\\${SERVICE_B_URL}'
before supplying it as a command to docker run. My intention is to specify that as a literal string.
Is there a way to escape this/stop expansion. I've tried things like '\\\\${SERVICE_B_URL}'
-> '\\'
.
Footnote, if you are wondering why I specify the '\${SERVICE_B_URL}'
to envsubst
instead of just using:
docker run -p 8080:80 -e "SERVICE_B_URL=somehost.co.uk" -d mynginx:latest /bin/sh -c "envsubst < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
The reason is, that the file being substituted contains other NGINX configuration which makes use of variables with $
syntax. So to prevent these being replaced by envsubst
I explicitly name the variable I want to be replaced. Running locally with docker run, it works like a charm...
I've ended up simplifying this by making the command we would pass to docker run
part of the Dockerfile
itself using CMD
, e.g:
CMD ["/bin/sh","-c","envsubst '\\${SERVICE_B_URL}' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]
Now we can remove the command
configuration from the JSON file for Fargate.