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


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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.