Если я использую переменную среды в конфигурации 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. Например:
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.