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

10

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

Том
источник
Какая ?! Объясните точно ваш вариант использования, поскольку кажется, что вы смотрите на него не с той стороны. Кстати, вы не можете использовать переменные окружения изначально в конфигурации nginx.
Ксавье Лукас
Спасибо @XavierLucas - я обновил вопрос, чтобы попытаться объяснить больше.
Том

Ответы:

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

AD7six
источник
4

Я экспериментировал с использованием переменных окружения 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.

Том
источник
2
Если это для одного статического файла - конечно, имеет смысл не делать это через конфигурацию nginx, я предположил, что ваш сценарий использования был немного шире. Для информации / контраста я использую sub_filter "example.com" "example.dev";в настройке dev, чтобы заменить любые и все ссылки на рабочий домен на локальную среду, потому что эти ссылки приходят из сторонних api откликов / кода приложения / js / db dumps / etc. то есть для nginx это может быть где угодно в любом ответе html / js / json. +1
AD7six
3

Я пытался решить ту же проблему, что и ОП, и этот пост появился в поиске 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, который содержит нужные вам переменные).

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

Грант
источник