docs: NGINX environment variables via envsubst break things like $http_host

When trying to use this as stated in the README

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

it also replaces stuff like this

proxy_set_header Host $http_host;

to look like this

proxy_set_header Host ;

any way to fix this? work around it?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 11
  • Comments: 18

Most upvoted comments

For anyone else who Googles there way here with a similar problem, I found that with docker-compose I needed to escape the variables like this:

command: /bin/bash -c "envsubst '$$VAR1 $$VAR2' < ...

ok, found a workaround. one can tell envsubst which vars to replace … so if you know the name of the variables you want to replace you can do it like this:

command: /bin/bash -c "envsubst '\$VAR1 \$VAR2' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

and only $VAR1 and $VAR2 will be replaced.

This work even onnginx:1-alpine

Why double “$$” see doc

environment:
      ENV_FOO: ENV_FOO
      ENV_BAR: ENV_BAR
command: sh -c "envsubst \"`env | awk -F = '{printf \" $$%s\", $$1}'`\" < /etc/nginx/conf.d/web.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

If you want to only replace variables that have been defined (and not just blindly remove anything else that looks like a variable), this seems to work: envsubst "`printf '${%s} ' $(bash -c "compgen -A variable")`" < /tmp/nginx.conf > /etc/nginx/conf.d/default.conf

In case it helps someone, based on the @michalgm answer, this is the command I use inside my docker-compose.yml file:

command: >
    /bin/bash -c "envsubst \"`for v in $$(compgen -v);do printf '$${%s} ' $$v;done`'\"
    < /etc/nginx/conf.d/mysite.template
    > /etc/nginx/conf.d/default.conf
    && nginx -g 'daemon off;'"

For Dockerfile users:

Using multistage builds and dockerize, it’s possible to do this with cleaner looking syntax and no need for installing gettext on alpine.

FROM jwilder/dockerize as config
COPY ./env/your_env_file_here /ENVFILE
COPY ./path/to/some/nginx.conf /MY_TEMPLATE
RUN sh -c "export $(cat /ENVFILE | xargs) && dockerize -template /MY_TEMPLATE > /FINAL.CONF"

# .... later, in your real container:

COPY --from=config /FINAL.CONF /etc/nginx/nginx.conf

I have problem with docker nginx config setup with envsubst:

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

return for me:

envsubst: error while reading "standard input": Is a directory

Can someone help to figure out what is wrong?

@milhomem the example is pretty simple: I have a nginx config template with variables and to prevent the replacement of $http_host and so on I have to use the awk based workaround. I also want to use default variable substitution so that one is able to run

PORT=9090 docker-compose up

so set a custom port when staring the container. If the variable is omitted it should use the port that is specified in the docker-compose.yml (8080 in the example above). This works just fine if one is using the version '3' statement in the first line of the config file.

envsubst: error while reading “standard input”: Is a directory

If you are having this issue your volume path is most likely wrong. Make sure you if you are using relative paths that you have ./ in front and double check the path exists locally.