Search code examples
amazon-ecsaws-fargatedocker-run

How can one prevent variable substitution/expension in AWS Fargate container definition command


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...


Solution

  • 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.