Search code examples
bashdockeramazon-ecsaws-fargatedocker-run

ECS/Fargate container definition command arguments


We are trying to start a fargate container on AWS ECS. In the container definition we have

"command": [
        "/bin/bash",
        "-c",
        "\"envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'\""
      ]

I also tried:

"command": [
        "/bin/bash",
        "-c",
        "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
      ]

Using docker run, we would successfully use:

docker run -p 8000:80 -e "VAR1=somevalue" -d nginx-sample:latest /bin/bash -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

And in kubernetes world (which also works):

 containers:
      env:
      - name: VAR1
        value: "somevalue"
      command: ["/bin/bash"]
      args: ["-c", "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"]

We cannot get this to work so far in AWS Fargate. It's not clear to me how we should pass the arguments in a valid way. The containers appear to exit before being able to start but there are no obvious log messages, so it's not entirely clear why. I think it's something I'm doing wrong with the syntax in the way the command arguments to /bin/bash -c are being passed.


Solution

  • In the end the right syntax (well at least one that worked well for us) was:

    "command": [
            "/bin/bash",
            "-c",
            "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
          ],
    

    Our real issue actually turned out to be that we had defined a container health check along the lines of:

    "healthCheck": {
            "retries": 5,
            "command": [
              "CMD-SHELL",
              "curl --fail http://localhost/health || exit 1"
            ],
            "timeout": 10,
            "interval": 30,
            "startPeriod": 30
          },
    

    And we forgot to verify that curl was actually installed inside the container. We took it for granted that it'd be there, but in the nginx:latest image, it is not - I presume rightly so for smaller size and smaller attack surface as an exploit vector. We ended up just installing curl in our Dockerfile, after that all was well.