在nginx.conf中,如何使用环境变量

分享于 

6分钟阅读

互联网

  繁體

问题:

我有一个Docker容器运行Nginx,它链接到另一个Docker容器,希望nginx.conf使用这些值例如,


upstream gunicorn {


 server $APP_HOST_NAME:$APP_HOST_PORT;


}



在启动时,如何使环境变量进入Nginx配置?

下面是完整文件:


env APP_WEB_1_PORT_5000_TCP_ADDR;


# Nginx host configuration for django_app



# Django app is served by Gunicorn, running under port 5000 (via Foreman)


upstream gunicorn {


 server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;


}



server {


 listen 80;



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


 error_log /var/log/nginx/error.log;



 location /static/ {


 alias /app/static/;


 }


 location /media/ {


 alias /app/media/;


 }


 location / {


 proxy_pass http://gunicorn;


 }


}



重新加载Nginx,然后出现错误:


$ nginx -s reload


nginx: [emerg] unknown directive "env" in /etc/nginx/sites-enabled/default:1



当前环境变量


root@87ede56e0b11:/# env | grep APP_WEB_1


APP_WEB_1_NAME=/furious_turing/app_web_1


APP_WEB_1_PORT=tcp://172.17.0.63:5000


APP_WEB_1_PORT_5000_TCP=tcp://172.17.0.63:5000


APP_WEB_1_PORT_5000_TCP_PROTO=tcp


APP_WEB_1_PORT_5000_TCP_PORT=5000


APP_WEB_1_PORT_5000_TCP_ADDR=172.17.0.63



root nginx.conf:


root@87ede56e0b11:/# head /etc/nginx/nginx.conf


user www-data;


worker_processes 4;


pid /var/run/nginx.pid;


env APP_WEB_1_PORT_5000_TCP_ADDR;



站点Nginx配置:


root@87ede56e0b11:/# head /etc/nginx/sites-available/default


# Django app is served by Gunicorn, running under port 5000 (via Foreman)


upstream gunicorn {


 server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;


}



server {


 listen 80;



重新加载Nginx配置:


root@87ede56e0b11:/# nginx -s reload


nginx: [emerg] directive "server" is not terminated by ";" in /etc/nginx/sites-enabled/default:3




答案1:

来自官方Nginx Docker文件:

使用环境变量在Nginx配置中:

Nginx开箱即用,不支持在大多数配置块内部使用环境变量。

但是,如果需要在envsubst之前动态生成Nginx配置,则可以使用。

下面是使用docker-compose.yml的例子:


image: nginx


volumes:


 - ./mysite.template:/etc/nginx/conf.d/mysite.template


ports:


 -"8080:80"


environment:


 - NGINX_HOST=foobar.com


 - NGINX_PORT=80


command: /bin/bash -c"envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" 



然后,mysite.template文件可以包含如下所示的变量引用:


listen ${NGINX_PORT};



更新:

但是你知道这导致了它的Nginx变量,如下所示:


proxy_set_header X-Forwarded-Host $host;




proxy_set_header X-Forwarded-Host ;



为了防止这种情况,我使用下面的技巧:

我有一个运行Nginx的脚本,在名为docker-compose的服务器上使用它作为命令选项


#!/usr/bin/env bash


export DOLLAR='$'


envsubst < nginx.conf.template > /etc/nginx/nginx.conf


nginx -g"daemon off;"



由于在run_nginx.sh脚本上定义了新的DOLLAR变量,现在nginx.conf.template文件的内容对于Nginx本身变量如下所示:


proxy_set_header X-Forwarded-Host ${DOLLAR}host;



对于定义变量,如下所示:


server_name ${WEB_DOMAIN} www.${WEB_DOMAIN};



例子


答案2:

官方的Nginx镜像建议使用envsubstenvsubst可以作为参数替换变量的名称

entrypoint脚本也是验证参数和设置默认值的好地方。

下面是一个Nginx容器示例,它采用API_HOSTAPI_PORT参数作为环境变量。

nginx-default.conf.template


resolver 127.0.0.11 valid=10s; # recover from the backend's IP changing



server {


 listen 80;



 location / {


 root /usr/share/nginx/html;


 }



 location /api {


 proxy_pass http://${API_HOST}:${API_PORT};


 proxy_set_header Host $http_host;


 }


}



docker-entrypoint.sh


#!/usr/bin/env sh


set -eu



envsubst '${API_HOST} ${API_PORT}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf



exec"$@"



Dockerfile文件


FROM nginx:1.15-alpine



COPY nginx-default.conf.template /etc/nginx/conf.d/default.conf.template



COPY docker-entrypoint.sh /


ENTRYPOINT ["/docker-entrypoint.sh"]


CMD ["nginx","-g","daemon off;"]