nginx:使用环境变量

Posted

技术标签:

【中文标题】nginx:使用环境变量【英文标题】:nginx: use environment variables 【发布时间】:2014-03-18 22:57:21 【问题描述】:

我有以下场景:我定义了一个环境变量$SOME_IP,并希望在 nginx 块中使用它。参考nginx documentation,我在nginx.conf 文件中使用env 指令,如下所示:

user www-data;
worker_processes 4;
pid /run/nginx.pid;

env SOME_IP;

现在我想将变量用于proxy_pass。我尝试如下:

location / 
    proxy_pass http://$SOME_IP:8000;

但我最终得到以下错误消息:nginx: [emerg] unknown "some_ip" variable

【问题讨论】:

您也可以使用envsubst 制作一个bash 模板。这不需要 docker 或 lua+perl,如本问题所述:***.com/questions/2914220/… 【参考方案1】:

正确的用法是$SOME_IP_from_env,但从 nginx.conf 设置的环境变量不能用于服务器、位置或 http 块。

如果您使用 openresty bundle,您可以使用环境变量,其中包括 Lua。

【讨论】:

谢谢!但是是否没有选项可以在服务器块中使用nginx.conf 中定义的变量? 在服务器块中,您可以使用语法set $var "value";,然后在整个配置中引用 $var。但是你不能使用环境变量。 为人们节省一些时间(以上需要自定义构建),您可以使用模板和名为 envsubst serverfault.com/a/755541/116508 的工具为 docker 执行此操作,只需指定 env vars 或者您可以无意中清除 nginx 中的 vars eg$host 这是什么_from_env后缀??【参考方案2】:

您可以通过模块访问变量 - 我找到了使用 Lua 和 Perl 的选项。

在我公司的博客上写到:

https://web.archive.org/web/20170712003702/https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html

TL;DR:

env API_KEY;

然后:

http 
...
  server 
    location / 
      # set var using Lua
      set_by_lua $api_key 'return os.getenv("API_KEY")';

      # set var using perl
      perl_set $api_key 'sub  return $ENV"API_KEY"; ';
      ...
    
  

编辑:原始博客已死,更改链接到回程机器缓存

【讨论】:

有没有办法在通过 helm install 启动此配置时检查输出? @Kajsa 您可能希望将该评论变成一个 SO 问题(使用适当的标签,如 helm 等)。它将获得更高的知名度和更多由具有 Helm 知识的人回答的机会(我不是)。【参考方案3】:

使用 NGINX Docker 镜像

在容器启动时在配置文件的模板上应用envsubstenvsubst 包含在官方 NGINX docker 镜像中。

环境变量以$VARIABLE$VARIABLE 的形式引用。

nginx.conf.template

user  nginx;
worker_processes  1;

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

events 
    worker_connections  1024;


http 
    server 
        listen       80;
        location / 
            access_log off;
            return 200 '$MESSAGE';
            add_header Content-Type text/plain;
        
    

Dockerfile

FROM nginx:1.17.8-alpine
COPY ./nginx.conf.template /nginx.conf.template
CMD ["/bin/sh" , "-c" , "envsubst < /nginx.conf.template > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"]

构建并运行 docker:

docker build -t foo .
docker run --rm -it --name foo -p 8080:80 -e MESSAGE="Hellou World" foo

注意:如果配置模板包含不应替换的美元符号$,则列出所有使用的变量作为envsubst 的参数,以便仅替换那些。例如:

CMD ["/bin/sh" , "-c" , "envsubst '$USER_NAME $PASSWORD $KEY' < /nginx.conf.template > /etc/nginx/nginx.conf && exec nginx -g 'daemon off;'"]

Nginx Docker documentation 供参考。查找在 nginx 配置中使用环境变量

在 nginx 配置中使用环境变量

开箱即用,nginx 不支持内部环境变量 大多数配置块。但是 envsubst 可以用作解决方法,如果 你需要在 nginx 之前动态生成你的 nginx 配置 开始。

这是一个使用 docker-compose.yml 的示例:

web:
  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 && exec nginx -g 'daemon off;'"

mysite.template 文件可能包含变量引用,例如 这个:

listen $NGINX_PORT;

【讨论】:

链接似乎没有指向您可能希望它指向的位置 :)【参考方案4】:

从 nginx 1.19 开始,您现在可以通过 docker-compose 在配置中使用环境变量。我使用了以下设置:

# file: docker/nginx/templates/default.conf.conf
upstream api-upstream 
    server $API_HOST;



# file: docker-compose.yml
services:
    nginx:
        image: nginx:1.19-alpine
        environment:
            NGINX_ENVSUBST_TEMPLATE_SUFFIX: ".conf"
            API_HOST: api.example.com

我在其他帖子上找到了这个答案:https://***.com/a/62844707/4479861

【讨论】:

值得一提的是:1) 它使用模板文件 2) 模板文件应该在/etc/nginx/templates/ 内创建并定义后缀 3) 替换环境变量后它会自动在@ 内创建目标配置文件987654325@ 不带后缀(本例为conf.d/default.conf) 4)默认模板扩展名是.template 5)更多可以在原始答案中找到:) 它不是 nginx 本身的特性,而是它的官方 docker 容器,在“在 nginx 配置中使用环境变量(1.19 中的新功能)”段落中的描述在 hub.docker.com/_/nginx 我喜欢那个解决方案,但它一开始并没有奏效,尽管我遵循了@Hunter_71 的提示。这是因为 Docker 容器必须启动 docker-entrypoint.sh 脚本才能运行实际替换的 envsubst。我在我的 Dockerfile 中定义了一个 CMD 命令,这使得默认的 ENTRYPOINT 过时了。删除我的 CMD 并将其放在我复制到 /docker-entrypoint.d/ 目录的脚本中解决了这个问题。默认docker-entrypoint.sh会自动执行该目录中的脚本。【参考方案5】:

对于简单的环境变量替换,可以使用自 docker Nginx 1.19 起的envsubst 命令和模板功能。注意:envsubst 不支持回退默认值,例如:$MY_ENV:-DefaultValue

对于更高级的用法,可以考虑使用https://github.com/guyskk/envsub-njs,它是通过Nginx NJS 实现的,使用javascript 模板文字,功能强大并且在跨平台上运行良好。例如:$Env('MY_ENV', 'DefaultValue')

你也可以考虑https://github.com/kreuzwerker/envplate,它支持语法,就像shell变量替换一样。

【讨论】:

以上是关于nginx:使用环境变量的主要内容,如果未能解决你的问题,请参考以下文章

linux怎么配置nginx环境变量

如何避免使用 Django、nginx 和 uWSGI 将环境变量放到多个地方?

使用 nginx 将环境变量从 docker-compose 传递到 vue 应用程序

在 Ubuntu 上使用 nginx 和Passenger 时在哪里放置环境变量

(Nginx +gunicorn)/Apache 不读取环境变量

Vue3实践Vue3使用vite处理环境变量打包部署nginx配置