从 docker-compose 替换 NGINX 配置中的环境变量 [英] Substitute environment variables in NGINX config from docker-compose

查看:68
本文介绍了从 docker-compose 替换 NGINX 配置中的环境变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在通过 docker-compose 配置的 docker 容器中启动 NGINX 服务器.然而,问题是我想替换 http 部分内的环境变量,特别是在上游"块内.

I am trying to start an NGINX server within a docker container configured through docker-compose. The catch is, however, that I would like to substitute an environment variable inside of the http section, specifically within the "upstream" block.

让这个工作真是太棒了,因为我还有其他几个容器都是通过环境变量配置的,而且我有大约 5 个环境需要在任何给定时间运行.我曾尝试使用envsubst"(如官方 NGINX 文档所建议的)、perl_set 和 set_by_lua,但它们似乎都不起作用.

It would be awesome to have this working, because I have several other containers that are all configured through environment variables, and I have about 5 environments that need to be running at any given time. I have tried using "envsubst" (as suggested by the official NGINX docs), perl_set, and set_by_lua, however none of them appear to be working.

下面是 NGINX 配置,因为它是在我最近的试用之后

Below is the NGINX config, as it is after my most recent trial

user  nginx;
worker_processes  1;
env NGINXPROXY;

load_module modules/ngx_http_perl_module.so;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    perl_set $nginxproxy 'sub { return $ENV{"NGINXPROXY"}; }';

    upstream api-upstream {
        server ${nginxproxy};
    }

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

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

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

下面是NGINX dockerfile

Below is the NGINX dockerfile

# build stage
FROM node:latest
WORKDIR /app
COPY ./ /app
RUN npm install
RUN npm run build

# production stage
FROM nginx:1.17.0-perl
COPY --from=0 /app/dist /usr/share/nginx/html
RUN apt-get update && apt-get install -y gettext-base
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx
RUN mkdir /certs
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

以下是 NGINX 服务器的 docker-compose.yml 部分(名称和 IP 已更改).envsubst 命令在我的故障排除中被有意注释掉.

Below is the section of the docker-compose.yml for the NGINX server (with names and IPs changed). The envsubst command is intentionally commented out at this point in my troubleshooting.

front-end:
        environment:
            - NGINXPROXY=172.31.67.100:9300
        build: http://gitaccount:password@gitserver.com/group/front-end.git#develop
        container_name: qa_front_end
        image: qa-front-end
        restart: always
        networks:
            qa_network:
                ipv4_address: 172.28.0.215
        ports:
            - "9080:80"
        # command: /bin/bash -c "envsubst '$$NGINXPROXY' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"

似乎发生的事情是,当我在上游块中引用 $nginxproxy 变量时(就在服务器"之后),我得到的输出使它看起来像是在引用字符串文字$nginxproxy"而不是替换值的变量.

What appears to be happening is when I reference the $nginxproxy variable in the upstream block (right after "server"), I get output that makes it look like it's referencing the string literal "$nginxproxy" rather than substituting the value of the variable.

qa3_front_end       | 2019/06/18 12:35:36 [emerg] 1#1: host not found in upstream "${nginx_upstream}" in /etc/nginx/nginx.conf:19
qa3_front_end       | nginx: [emerg] host not found in upstream "${nginx_upstream}" in /etc/nginx/nginx.conf:19
qa3_front_end exited with code 1

当我尝试使用 envsubst 时,我收到一个错误,听起来像是命令与 nginx.conf 文件的格式混淆

When I attempt to use envsubst, I get an error that makes it sound like the command messed with the format of the nginx.conf file

qa3_front_end       | 2019/06/18 12:49:02 [emerg] 1#1: no "events" section in configuration
qa3_front_end       | nginx: [emerg] no "events" section in configuration
qa3_front_end exited with code 1

我很困惑,所以提前感谢您的帮助.

I'm pretty stuck, so thanks in advance for your help.

推荐答案

因此,在解决了这个问题之后,我设法使其与 bellackn 提供的答案类似.我将在这里发布我的确切解决方案,以防其他人需要参考完整的解决方案.

So after some wrestling with this issue, I managed to get it working similarly to the answer provided by bellackn. I am going to post my exact solution here, in case anybody else needs to reference a complete solution.

步骤 1:按照通常的方式编写 nginx.conf 或 default.conf.将文件另存为nginx.conf.template"或default.conf.template",具体取决于您尝试将变量替换为哪个.

Step1: Write your nginx.conf or default.conf how you would normally write it. Save the file as "nginx.conf.template", or "default.conf.template" depending on which you are trying to substitute variables into.

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    upstream api-upstream {
        server 192.168.25.254;
    }

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

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

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

第 2 步:将 ${VARNAME} 格式的变量替换为您想用环境变量替换的任何值:

Step2: Substitute a variable in the format ${VARNAME} for whatever value(s) you want to replace with an environment variable:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    upstream api-upstream {
        server ${SERVER_NAME};
    }

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

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

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

第 3 步:在您的 docker 文件中,将您的 nginx 配置文件(您的 nginx.conf.template 或 default.conf.template)复制到您的容器中的适当位置:

Step 3: In your docker-file, copy your nginx configuration files (your nginx.conf.template or default.conf.template) into your container at the appropriate location:

# build stage
FROM node:latest
WORKDIR /app
COPY ./ /app
RUN npm install
RUN npm run build

# production stage
FROM nginx:1.17.0-perl
COPY --from=0 /app/dist /usr/share/nginx/html
RUN apt-get update && apt-get install -y gettext-base
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
#-----------------------------------#
|COPY default.conf /etc/nginx/conf.d|
|COPY nginx.conf.template /etc/nginx|
#-----------------------------------#
RUN mkdir /certs
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

第 4 步:使用环境"部分标签在 docker-compos.yml 文件中设置环境变量.确保您的环境变量名称与您在 nginx 配置文件中选择的任何变量名称相匹配.使用 docker 容器中的envsubt"命令将变量值替换为 nginx.conf.template 中的变量,并将输出写入正确位置的名为 nginx.conf 的文件.这可以通过使用命令"部分标签在 docker-compose.yml 文件中完成:

Step 4: Set your environment variable in your docker-compos.yml file using the "environment" section label. Make sure your environment variable name matches whatever variable name you chose within your nginx config file. Use the "envsubt" command within your docker container to substitute your variable values in for your variables within your nginx.conf.template, and write the output to a file named nginx.conf in the correct location. This can be done within the docker-compose.yml file by using the "command" section label:

version: '2.0'
services:
    front-end:
        environment:
            - SERVER_NAME=172.31.67.100:9100
        build: http://git-account:git-password@git-server.com/project-group/repository-name.git#branch-ame
        container_name: qa_front_end
        image: qa-front-end-vue
        restart: always
        networks:
            qa_network:
                ipv4_address: 172.28.0.215
        ports:
            - "9080:80"
        command: >
            /bin/sh -c
            "envsubst '
            $${SERVER_NAME}
            '< /etc/nginx/nginx.conf.template
            > /etc/nginx/nginx.conf
            && nginx -g 'daemon off;'"

第 5 步:使用 docker-compose up 运行您的堆栈(使用您需要的任何其他开关),您的 nginx 服务器现在应该以您在 docker-compose.yml 的环境"部分中提供的任何值开始

Step 5: Run your stack with docker-compose up (with whatever additional switches you need) and your nginx server should now start with whatever value you supplied in the "environment" section of your docker-compose.yml

正如上面的解决方案中提到的,您也可以定义自己的入口点,但是这个解决方案也被证明非常有效,并且将所有内容都包含在一个配置文件中,使我能够运行一堆服务直接从 git 中,只需要一个 docker-compose.yml 文件.

As mentioned in the solution above, you can also define your own entry point, however this solution has also proven to work pretty well, and keeps everything contained into a single configuration file, giving me the ability to run a stack of services directly from git with nothing but a docker-compose.yml file.

非常感谢所有花时间准备完成这件事的人,非常感谢您花时间帮助我解决问题.

A big thank you to everybody who took the time to ready through this, and bellackn for taking the time to help me solve the issue.

这篇关于从 docker-compose 替换 NGINX 配置中的环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆