docker中nginx的动态default.conf

Den*_*boy 4 nginx docker

这是我在Dockerfile中使用以下内容default.conf 替换原始default.conf文件.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到的错误是

2017/06/26 21:08:15 [emerg] 1#1: unknown "servername" variable
nginx: [emerg] unknown "servername" variable
Run Code Online (Sandbox Code Playgroud)

当我$servername用192.168.xx.xx(我的服务器的真实IP)替换时,一切正常.但我希望它是动态的.

如何定义$ servername的值,以便我的docker将它接收并且它将由nginx使用?

或者我可以用另一种方式编写我的default.conf来使其动态化吗?

min*_*oyo 10

用于envsubst在nginx配置中动态嵌入环境变量.envsubst是一个轻量级的模板引擎,它也包含在官方nginx:alpine图像中.

要将envsubst安装到自定义映像:

高山:

$ apk --no-cache add gettext
Run Code Online (Sandbox Code Playgroud)

Debian的:

$ apt-get install gettext-base
Run Code Online (Sandbox Code Playgroud)

以下是如何使用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
Run Code Online (Sandbox Code Playgroud)

请注意,如果要$在配置文件中使用符号,如nginx.conf,则需要指定要嵌入的环境变量的名称.

SERVER_NAME在nginx.conf 中动态嵌入环境变量的示例如下:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

参数有点复杂,所以这里以docker-compose.yml格式显示:

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"
Run Code Online (Sandbox Code Playgroud)

  • 嗨,谢谢你!我想知道如何做同样的事情但使用多个模板文件?例如,我有一个 `ssl.conf` 文件,我想将其包含在多个服务器块中,因此我稍微清理了代码。我怎样才能在那个文件中使用环境变量?我认为需要一个额外的 `envsubst` 调用,对吗?将所有内容移动到 `entrypoint.sh` 文件以稍微清理命令怎么样?提前致谢 (2认同)