问题:
我有一个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镜像建议使用envsubst
,envsubst
可以作为参数替换变量的名称。
entrypoint脚本也是验证参数和设置默认值的好地方。
下面是一个Nginx容器示例,它采用API_HOST
和API_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;"]