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


10

Se eu usar uma variável de ambiente na configuração do nginx, e o 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 em 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.


Aliás, você não pode usar variáveis ​​de ambiente nativamente na configuração do nginx.

Quando falo sobre os ambientes de variáveis ​​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"};


Explique exatamente seu caso de uso

Meu caso de uso específico é que eu tenho um aplicativo AngularJS alimentado por nginx em um contêiner de docker. O aplicativo é um "Aplicativo de página única" que consome uma API em execução em outro sistema completamente. Atualmente, eu executo um contêiner de docker diferente entre produção e armazenamento temporário, porque o aplicativo tem algumas configurações diferentes, por exemplo, o código do Google-Analtyics. Esses dados específicos do ambiente são mantidos em um config.jsarquivo e os valores atualmente são codificados, um valor para a masterramificação no git e um valor diferente para a stagingramificação. Quero alterar o design para poder usar o mesmo contêiner para produção e preparação. Quero passar uma ENV var para o contêiner quando executá-la ( docker run -e GACODE=UA-12345-6 ...) e o nginx usa a ENV var (via env GACODE;e $ENV{"GACODE"}assim oconfig.jsO arquivo pode usar os códigos do GoogleAnaltyics que são passados, em vez de codificá-los). 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, enquanto que, se eu precisar usar o io.js., precisarei de vários contêineres vinculados e mais partes móveis serão mais complexas).


O que ?! Explique exatamente o seu caso de uso, pois parece que você está olhando do lado errado. Aliás, você não pode usar variáveis ​​de ambiente nativamente na configuração do nginx.
Xavier Lucas

Obrigado @XavierLucas - atualizei a pergunta para tentar explicar mais.
19415 Tom

Respostas:


4

sub_filter

Se você deseja uma substituição simples de cadeia, 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
}

Entretanto , não é possível ler uma variável de ambiente no nginx config - você pode, naturalmente, escrever o arquivo de configuração nginx da maneira que precisar / desejar produzir um arquivo de configuração válido e recarregar o nginx.


4

Eu 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 mostra que o uso de ENVs passados ​​para o nginx não funciona em um serverbloco:

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;
        }
        ...

onde o arquivo estático config.json que estou servindo possui várias cadeias de teste como as seguintes:

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

Como o @ AD7six mencionado, o caminho a seguir é ter um script que seja executado antes do 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 nginx iniciar, é melhor definir o conteúdo do meu config.jsonarquivo nesse script e não me incomodar sub_filter.


2
Se for para um arquivo estático - certamente faz sentido não fazê-lo através da configuração do nginx, presumi que o seu caso de usuário era um pouco mais amplo que isso. Para informações / contraste, eu uso sub_filter "example.com" "example.dev";em uma configuração de desenvolvimento para substituir toda e qualquer referência ao domínio de produção no ambiente local, porque essas referências são provenientes de respostas de API de terceiros / código do aplicativo / js / db dumps / etc. - ou seja, para o nginx, pode estar em qualquer lugar em qualquer resposta html / js / json. +1
AD7six 26/03/2015

3

Eu estive procurando resolver o mesmo problema que o OP e esta postagem surgiu na pesquisa do Google, então pensei em adicionar uma solução em potencial.

Esta publicação descreve como você pode expor uma variável de ambiente na configuração do nginx: https://blog.doismellburning.co.uk/environment-variables-in-nginx-config/

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

Juntando essas duas coisas, 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 é certo que seja melhor do que gerar automaticamente um arquivo na inicialização do Docker que contenha os vários itens necessários).

Espero que ajude.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.