web-dev-qa-db-ja.com

nginxが提供する静的ファイル内でnginx環境変数を使用できますか?

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を完全に使用する「単一ページアプリケーション」です。アプリには、Google-Analtyicsコードなどの異なる設定があるため、現在、本番とステージング間で異なるDockerコンテナーを実行しています。この環境固有のデータはconfig.jsファイルに保持され、値は現在ハードコードされています。gitのmasterブランチの1つの値とstagingブランチの異なる値です。生産とステージングの両方に同じコンテナを使用できるようにデザインを変更したいと思います。実行時にENV変数をコンテナーに渡し(docker run -e GACODE=UA-12345-6 ...)、nginxにENV変数を(env GACODE;および$ENV{"GACODE"}を介して)使用して、config.jsファイルでハードコーディングするのではなく、渡されたGoogleAnaltyicsコードを使用します)。これが可能かどうかはわかりません(したがって、質問;))。 nginxのみを使用すると、コンテナーが単一プロセスになりますが、io.jsを使用する必要がある場合は、複数のリンクされたコンテナーが必要になり、可動部分がより複雑になります)。

10
Tom

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
}

ただし環境変数innginx configを読み取ることはできません-もちろんスクリプトを書くことができます有効な構成ファイルを作成し、nginxをリロードするために必要な方法でnginx構成ファイルを作成します。

4
AD7six

sub_filter とnginx環境変数を使用して実験しましたが、それは不可能であると結論しました

たとえば、これは私の実験を示しており、nginxに渡されたENVの使用はserver内でnot動作しますブロック:

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をまったく気にしないこともできます。

4
Tom

私はOPと同じ問題の解決を検討しており、この投稿がGoogle検索で出てきたので、潜在的な解決策を追加したいと思いました。

この投稿では、nginx config内で環境変数を公開する方法の概要を説明します。 https://blog.doismellburning.co.uk/environment-variables-in-nginx-config/

また、ファイルシステムにファイルがなくてもコンテンツを返すことができます。 ファイルを提供せずにNginx構成から200で返信

これら2つをまとめると、次のようになります。

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の起動時に、必要な変数を含むファイルを自動生成するよりも優れているとは限りません)。

お役に立てば幸いです。

3
Grant