Heroku (Docker) PORT environment variable in nginx Heroku (Docker) PORT environment variable in nginx nginx nginx

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