Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic default.conf of nginx in docker

Tags:

docker

nginx

This is my default.conf I'm replacing the original default.conf with the following one in my Dockerfile.

server {
    listen                          80;
    server_name                     $servername;
    return 301                      https://$server_name$request_uri;
}

server {

    listen 443;
    server_name $servername;

    ssl_certificate           /etc/ssl/private/server.crt;
    ssl_certificate_key       /etc/ssl/private/server.key;

    ssl on;

    access_log            /var/log/nginx/ghost.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      proxy_pass          http://xxx:2368;
      proxy_read_timeout  90;

      proxy_redirect      http://xxx:2368 https://$servername:443;
    }
}

The error I receive is

2017/06/26 21:08:15 [emerg] 1#1: unknown "servername" variable
nginx: [emerg] unknown "servername" variable

When I replace $servername with 192.168.xx.xx (the real IP of my server), than everything works fine. But I want it to be dynamic.

How can I define the value of the $servername so that my docker will pick it up and it will be used by nginx?

Or can I write my default.conf in another way to make this dynamic?

like image 346
DenCowboy Avatar asked Jun 28 '17 14:06

DenCowboy


1 Answers

Use envsubst to dynamically embed environment variables in the nginx configuration. envsubst is a lightweight template engine and it is also included in the official nginx:alpine image.

To install envsubst to your custom image:

alpine:

$ apk --no-cache add gettext

debian:

$ apt-get install gettext-base

Here is a simple example for how to use envsubst:

$ cat test.conf.template
hoge=$HOGE

$ docker run --rm \
    -v $(pwd)/test.conf.template:/tmp/test.conf.template \
    -e HOGE=aaa \
    nginx:alpine \
    /bin/sh -c "envsubst < /tmp/test.conf.template > /tmp/test.conf && cat /tmp/test.conf"
hoge=aaa

Note that if you want to use the $ symbol in the configuration file like nginx.conf, you need to specify the name of the environment variable to embed.

An example of dynamically embedding the environment variable SERVER_NAME in nginx.conf is as follows:

server {
    listen                          80;
    server_name                     ${SERVER_NAME};
    return 301                      https://${SERVER_NAME}$request_uri;
}

server {

    listen 443;
    server_name ${SERVER_NAME};

    ssl_certificate           /etc/ssl/private/server.crt;
    ssl_certificate_key       /etc/ssl/private/server.key;

    ssl on;

    access_log            /var/log/nginx/ghost.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      proxy_pass          http://xxx:2368;
      proxy_read_timeout  90;

      proxy_redirect      http://xxx:2368 https://${SERVER_NAME}:443;
    }
}

The arguments are somewhat complicated, so it is shown here in docker-compose.yml format:

version: '2'
services:
  nginx:
    image: nginx:alpine
    command: >
      /bin/sh -c
      "envsubst '
      $$SERVER_NAME
      '< /etc/nginx/nginx.conf.template
      > /etc/nginx/nginx.conf
      && nginx -g 'daemon off;'"
    volumes:
      - ./nginx.conf.template:/etc/nginx/nginx.conf.template
    ports:
      - 8080:80
    environment:
      SERVER_NAME: "test.example.com"
like image 63
minamijoyo Avatar answered Sep 28 '22 10:09

minamijoyo