Posso usar variáveis de ambiente nginx em arquivos estáticos que o nginx atende?

8

Se eu usar uma variável de ambiente na configuração nginx, e nginx estiver configurado para servir apenas arquivos estáticos (html, js, css - por exemplo, um aplicativo AngularJs), existe alguma maneira de usar a variável de ambiente dentro de um arquivo JS? que o nginx serve? Ou é a única maneira de fazer isso para executar um servidor não estático, por exemplo, io.js, php, etc.

Btw you can't use environment variables natively in nginx's configuration.

Quando eu falo sobre ambiente vars na configuração do nginx, quero dizer, como neste post: Como posso usar variáveis de ambiente no Nginx.conf onde eles usam env APP_WEB_1_PORT_5000_TCP_ADDR; e $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};

Explain exactly your use case

Meu caso de uso específico é que eu tenho um aplicativo AngularJS alimentado por nginx em um contêiner docker. O aplicativo é um "aplicativo de página única" que consome uma API em execução em outro sistema completamente. Atualmente, executo um contêiner docker diferente entre produção e teste porque o aplicativo tem alguma configuração diferente, por exemplo, o código Google-Analtyics. Esses dados específicos do ambiente são mantidos em um arquivo config.js e os valores são atualmente codificados, um valor para a ramificação master no git e um valor diferente para a ramificação staging . Quero alterar o design para poder usar o mesmo contêiner para produção e preparo. Quero passar uma var ENV para o contêiner quando eu executá-lo ( docker run -e GACODE=UA-12345-6 ... ) e ter nginx usar a var ENV (via env GACODE; e $ENV{"GACODE"} para que o arquivo config.js possa usar os códigos GoogleAnaltyics que são passados , em vez de codificá-los). Eu não sei se isso é possível ou não (daí a questão;)). Usar apenas o nginx torna meu contêiner um processo único, ao passo que, se eu precisar usar o io.js, precisarei de vários contêineres vinculados e mais partes móveis será mais complexo).

    
por Tom 19.03.2015 / 12:16

3 respostas

3

sub_filter

Se você quiser uma simples substituição de string, use sub_filter . Por exemplo:

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
}

No entanto não é possível ler uma variável de ambiente em configuração nginx - você pode, é claro, escrever o arquivo de configuração nginx de qualquer maneira que você precisa / quer produzir um válido arquivo de configuração e, em seguida, recarregue o nginx.

    
por 19.03.2015 / 15:18
1

Experimentei usar variáveis de ambiente sub_filter e nginx, mas concluí que não é possível .

Por exemplo, isso mostra minhas experiências e shows usando ENVs passados para o nginx não funcionam dentro de um bloco 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;
        }
        ...

em que o arquivo estático config.json que estou veiculando tem várias sequências de teste, como as seguintes:

{
    "environment": "local",
    "test1": "$ENV{"TOMTEST1"}",
    "test3": "TOM_TEST2",
    "test4": "TOM_TEST3",
}

Como @ AD7six mencionou, a maneira de proceder é ter um script que é executado antes de o nginx começar a produzir um arquivo de configuração válido a partir de espaços reservados. Mas isso levanta a questão: se um script for executado antes do início do nginx, também posso definir o conteúdo do meu arquivo config.json nesse script e não me incomodar com sub_filter .

    
por 23.03.2015 / 11:20
1

Eu estou pensando em resolver o mesmo problema que o OP e este post apareceu na pesquisa do Google, então pensei em adicionar uma solução potencial.

Este post descreve como você pode expor uma variável de ambiente na configuração do nginx: link

E você pode retornar conteúdo sem ter um arquivo no sistema de arquivos: Responda com 200 da configuração do Nginx sem enviar um arquivo

Colocando essas duas coisas juntas, terminamos com o seguinte:

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\'';
        }
    }
}

Isso funcionou para mim em um ambiente de teste. É um pouco complicado (não tenho certeza se é melhor do que gerar automaticamente um arquivo no Docker que contém as versões necessárias).

Espero que ajude.

    
por 17.07.2018 / 05:32