Назад | Перейти на главную страницу

Могу ли я использовать переменные среды nginx в статических файлах, которые обслуживает nginx?

Если я использую переменную среды в конфигурации nginx, а nginx настроен для обслуживания только статических файлов (html, js, css - например, приложение AngularJs), могу ли я каким-либо образом использовать переменную среды в файле JS, который обслуживает nginx ? Или это единственный способ сделать это, чтобы запустить нестатический сервер, например. io.js, php и т. д.


Кстати, вы не можете использовать переменные среды изначально в конфигурации nginx.

Когда я говорю о переменных окружения в конфигурации nginx, я имею в виду, как в этом посте: Как я могу использовать переменные среды в Nginx.conf где они используют env APP_WEB_1_PORT_5000_TCP_ADDR; и $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};


Точно объясните свой вариант использования

Мой конкретный вариант использования заключается в том, что у меня есть приложение AngularJS на базе nginx в контейнере докеров. Приложение представляет собой «одностраничное приложение», которое полностью использует API, работающий в другой системе. В настоящее время я использую другой контейнер докеров между производством и постановкой, потому что приложение имеет другую конфигурацию, например код Google-Analtyics. Эти данные для конкретной среды хранятся в config.js файл и значения в настоящее время жестко запрограммированы, одно значение для master ветвь в git и другое значение для staging филиал. Я хочу изменить дизайн, чтобы использовать тот же самый контейнер как для производства, так и для постановки. Я хочу передать переменную ENV в контейнер при ее запуске (docker run -e GACODE=UA-12345-6 ...) и пусть nginx использует переменную ENV (через env GACODE; и $ENV{"GACODE"} так что config.js файл может использовать коды GoogleAnaltyics, которые передаются, а не жестко их кодировать). Не знаю, возможно это или нет (отсюда вопрос;)). Использование только nginx делает мой контейнер однопроцессным, тогда как если мне нужно использовать io.js, мне понадобится несколько связанных контейнеров, а больше движущихся частей будет сложнее).

Я экспериментировал с использованием sub_filter и переменные среды nginx, но пришли к выводу, что это невозможно.

Например, здесь показаны мои эксперименты и показано, что использование ENV, переданных в 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 вообще.

Я искал решение той же проблемы, что и OP, и этот пост появился в поиске Google, поэтому подумал, что добавлю потенциальное решение.

В этом посте рассказывается, как вы можете выставить переменную среды в конфигурации nginx: https://blog.doismellburning.co.uk/environment-variables-in-nginx-config/

И вы можете вернуть контент, не имея файла в файловой системе: Ответить 200 из конфигурации Nginx без обслуживания файла

Соединив эти две вещи, мы получим следующее:

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, который содержит нужные вам вары).

Надеюсь, это поможет.

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 - вы, конечно, можете написать сценарий файла конфигурации nginx любым способом, который вам нужен / хотите создать действительный файл конфигурации, а затем перезагрузить nginx.