docker中nginx的动态default.conf

时间:2017-06-28 14:12:17

标签: nginx docker

这是我default.conf 我正在用Dockerfile中的下一个替换原来的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;
    }
}

我收到的错误是

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

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

如何定义$ servername的值,以便我的docker将其拾取并且它将被nginx使用?

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

2 个答案:

答案 0 :(得分:7)

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

将envsubst安装到自定义映像:

高山:

$ apk --no-cache add gettext

的Debian:

$ apt-get install gettext-base

以下是如何使用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

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

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

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;
    }
}

参数有点复杂,所以这里以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"

答案 1 :(得分:-1)

也许你可以试试dcinja

dcinja 使用 inja 强大的库(如 jinja)作为运行时渲染模板的模板引擎。这是 envsubst 无法提供的支持条件和包含功能。

dcinja 由 c++ 编译,因此二进制文件仅 500KB ~ 600KB 依赖于平台。

模板文档

  • 变量{{ ... }}
  • 声明{% ... %}
    • for 循环 {% for key in data %} ... {% endfor %}
    • 条件{% if value >= 1 %} ... {% else if value >= 0 %} ... {% endif %}
    • 包括{% include "xxx.template" %}
    • 分配{% set name="test" %}
  • 函数
    • {{ upper("name") }}
    • 长度{{ length(data_list) }}
    • ...
  • 评论{# ... #}

示例

从标准输入输入模板,输出模板到标准输出

$ echo "TEST Name: {{ name }}" | dcinja -j '{"name": "Foo"}'
>>> TEST Name: Foo

从文件输入模板,输出模板到文件

$ dcinja -j '{"name": "Foo"}' -s input.template -d output.template

从文件输入json

$ dcinja -f param.json -s input.template -d output.template

整合

Dockerfile 示例,使用多阶段构建 dcinja 并复制到最终的 docker 镜像 /bin/ 作为命令

FROM ubuntu as dcinja-builder

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        \
        # build
        g++ \
        make \
        \
        # clone source code
        git \
        ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /code \
    && git clone https://github.com/Falldog/dcinja.git /code

WORKDIR /code
RUN make


FROM ubuntu
COPY --from=dcinja-builder /code/dist/dcinja /bin/
# ...