我可以在Nginx服务的静态文件中使用Nginx环境变量吗?


10

如果我在nginx配置中使用环境变量,并且nginx配置为仅提供静态文件(html,js,css-例如AngularJs应用程序),我有什么方法可以在nginx服务的JS文件中使用环境变量?或者是运行非静态服务器(例如io.js,php等)的唯一方法。


顺便说一句,您不能在nginx的配置中本地使用环境变量。

当我在Nginx配置中谈论环境变量时,我的意思是像这篇文章一样:如何在Nginx.conf使用环境变量env APP_WEB_1_PORT_5000_TCP_ADDR;$ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};


确切说明您的用例

我的特定用例是,我在Docker容器中有一个由nginx驱动的AngularJS应用。该应用程序是一个“单页应用程序”,它完全消耗了在另一个系统上运行的API。目前,我在生产和登台之间运行一个不同的Docker容器,因为该应用程序具有一些不同的配置,例如Google-Analtyics代码。此特定于环境的数据保存在config.js文件中,并且当前值已进行硬编码,mastergit中分支的一个值和分支的其他值staging。我想更改设计,以便可以在生产和暂存中使用相同的容器。我想通过一个ENV VAR到当我运行它(容器docker run -e GACODE=UA-12345-6 ...),并有使用nginx的ENV VAR(通过env GACODE;$ENV{"GACODE"}这样的config.js文件可以使用传入的GoogleAnaltyics代码,而不是对其进行硬编码)。我不知道这是否可行(因此提出问题;)。仅使用nginx可使我的容器成为一个单进程,而如果必须使用io.js,则需要多个链接的容器,并且需要移动的部件会更加复杂。


什么 ?!准确解释您的用例,因为它似乎是您从错误的角度看待它。顺便说一句,您不能在nginx的配置中本地使用环境变量。
哈维尔·卢卡斯

感谢@XavierLucas-我更新了问题以尝试解释更多。
汤姆(Tom)

Answers:


4

sub_filter

如果要简单的字符串替换,可以使用sub_filter。例如:

server {
    sub_filter "REPLACE_THIS" "with this";
    sub_filter_once off; # Don't stop at the first match, replace all of them
    sub_filter_types "text/javascript" "application/json"; # Apply to these mime types in addition to text/html 

    # Everything else
}

但是,无法 nginx config中读取环境变量-您当然可以通过脚本来编写Nginx配置文件,而您需要/想要生成有效的配置文件,然后重新加载nginx。


4

我尝试使用sub_filter和nginx环境变量,但得出结论认为这是不可能的

例如,这说明我的实验和使用ENVS节目传递给nginx的就不是一个内工作server块:

env TOMTEST1; # OK - makes $ENV{"TOMTEST1"} available but NOT in server block.

http {

    server {

        # set $TOMTEST1 $ENV{"TOMTEST1"};    # KO - DOES NOT WORK - NGINX WONT START
        set $TOMTEST2   'tomtest2 Var';      # OK - THIS DOES WORK OK

        sub_filter 'TOM_TEST2' $TOMTEST2;       # OK - but not useful to me.
        sub_filter 'TOM_TEST3' 'tomtest3 Var';  # OK - but not useful to me.
        sub_filter_once off;                    # Don't stop at the first match, replace all of them
        sub_filter_types "text/javascript" "application/json"; # Apply to these mime types in addition to text/html

        # Serve static files
        location / {
           try_files $uri /index.html =404;
        }
        ...

我提供的静态config.json文件具有各种测试字符串,如下所示:

{
    "environment": "local",
    "test1": "$ENV{"TOMTEST1"}",
    "test3": "TOM_TEST2",
    "test4": "TOM_TEST3",
}

正如@ AD7six提到的那样,继续的方法是在nginx开始从占位符生成有效的配置文件之前运行一个脚本。但这引出了一个问题,如果脚本要在nginx启动之前运行,我也可以config.json在该脚本中设置文件的内容,而不用担心sub_filter


2
如果是用于一个静态文件,则最好不要通过nginx config来执行此操作,我认为您的用例要比那宽一些。对于信息/对比度,我sub_filter "example.com" "example.dev";在开发设置中用于将对生产域的任何和所有引用替换为本地环境,因为这些引用来自第三方api响应/应用代码/ js / db dumps / etc。-即对于nginx,它可以在任何html / js / json响应中的任何位置。+1
AD7six 2015年

3

我一直在寻找解决与OP相同的问题,并且此帖子出现在Google搜索中,因此我想添加一个潜在的解决方案。

这篇文章概述了如何在nginx配置中公开环境变量:https : //blog.doismellburning.co.uk/environment-variables-in-nginx-config/

而且您可以在文件系统中没有文件的情况下返回内容:从Nginx配置中以200答复而不提供文件

将这两件事放在一起,我们得出以下结果:

env MY_ENV_VAR;

# Snip

http {
    # Snip

    server {
        # Snip

        location ~ ^/config.js$ {
            add_header Content-Type text/javascript;
            set_by_lua $env_var 'return os.getenv("MY_ENV_VAR")';
            return 200 'const MY_ENV_VAR = \'$env_var\'';
        }
    }
}

这在测试环境中对我有用。这有点麻烦(不确定它比在Docker启动时自动生成包含所需var的文件要好)。

希望能有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.