Heroku (Docker) PORT environment variable in nginx
I got it working for my app by following this example :
Step 1: listen to $PORT
in default.conf.template
server { listen $PORT default_server; location / { root /usr/share/nginx/html; index index.html; }}
Step 2: add this directive to your Dockerfile
COPY default.conf.template /etc/nginx/conf.d/default.conf.template
Step 3: add this at the end of your Dockerfile
CMD /bin/bash -c "envsubst '\$PORT' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf" && nginx -g 'daemon off;'
I'll show a solution which doesn't require to write a new Dockerfile, you can use the offical nginx images.
Like @Jimmy's solution we'll use the envsubst command which substitutes environment variables in shell format strings.
This command is available with the offical nginx image and also with the alpine version.
Step #1
write your nginx configuration in a template file - let's call it: site.template
:
server { listen ${PORT}; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; }}
Notice the PORT placeholder.
Step #2 - with docker compose
Mount that inside the /etc/nginx/conf.d
directory and then execute the envsubst
command to use the template as a reference for default.conf
:
web: image: nginx:alpine volumes: - ./site.template:/etc/nginx/conf.d/site.template ports: - "3000:8080" environment: - PORT=8080 command: /bin/sh -c "envsubst < /etc/nginx/conf.d/site.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
Notice that:
1. You need to execute the nginx daemon after that.
2. I used /bin/sh
and not /bin/bash
because my base image is alpine.
Step #2 (Another option) - inline docker run
If, for some reason you don't want to work with docker-compose you can use the following bash script:
#!/usr/bin/env bash##### Variables #####PORT=8080 #Or $1 if you pass it from command lineTEMPLATE_DIR=$(pwd)/site.templateTEMPLATE_REMOTE_DIR=/etc/nginx/conf.d/site.templateIMAGE_NAME=nginx:alpineecho "Starting nginx on port: $PORT ..."##### The docker command #####docker run -p 3000:$PORT -v $TEMPLATE_DIR:$TEMPLATE_REMOTE_DIR $IMAGE_NAME \/bin/sh -c "envsubst < $TEMPLATE_REMOTE_DIR > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
You need to update your nginx configuration at boot time.
See this buildpack as an example (I haven't tested that it does work).