Puis-je utiliser des variables d'environnement nginx dans des fichiers statiques desservis par nginx?

10

Si j'utilise une variable d'environnement dans la configuration nginx et que nginx est configuré pour ne servir que des fichiers statiques (html, js, css - par exemple une application AngularJs), est-il possible d'utiliser la variable d'environnement dans un fichier JS que nginx sert ? Ou est le seul moyen de le faire pour exécuter un serveur non statique, par exemple io.js, php, etc.


De plus, vous ne pouvez pas utiliser les variables d'environnement de manière native dans la configuration de nginx.

Quand je parle de vars d'environnement dans la configuration nginx, je veux dire comme dans cet article: Comment puis-je utiliser les variables d'environnement dans Nginx.conf où elles utilisent env APP_WEB_1_PORT_5000_TCP_ADDR;et$ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"};


Expliquez exactement votre cas d'utilisation

Mon cas d'utilisation spécifique est que j'ai une application AngularJS propulsée par nginx dans un conteneur Docker. L'application est une "application à page unique" qui utilise une API fonctionnant sur un autre système. Actuellement, je lance un conteneur Docker différent entre la production et la mise en scène, car l'application a une configuration différente, par exemple le code Google-Analtyics. Ces données spécifiques à l'environnement sont conservées dans un config.jsfichier et les valeurs sont actuellement codées en dur, une valeur pour la masterbranche dans git et une valeur différente pour la stagingbranche. Je souhaite modifier la conception afin de pouvoir utiliser le même conteneur pour la production et la mise en scène. Je veux passer une var ENV dans le conteneur quand je l'exécute ( docker run -e GACODE=UA-12345-6 ...) et demander à nginx d'utiliser la var ENV (via env GACODE;et $ENV{"GACODE"}donc laconfig.jsfichier peut utiliser les codes GoogleAnaltyics qui sont transmis, plutôt que de les coder en dur). Je ne sais pas si c'est possible ou pas (d'où la question;)). L'utilisation de nginx seulement fait de mon conteneur un processus unique, alors que si je dois utiliser io.js, alors j'aurai besoin de plusieurs conteneurs liés et plus de pièces mobiles sont plus complexes).

À M
la source
Quoi ?! Expliquez exactement votre cas d'utilisation car il semble que vous le regardiez du mauvais côté. De plus, vous ne pouvez pas utiliser les variables d'environnement de manière native dans la configuration de nginx.
Xavier Lucas
Merci @XavierLucas - J'ai mis à jour la question pour essayer d'expliquer plus.
Tom

Réponses:

4

sous_filtre

Si vous voulez un simple remplacement de chaîne, vous pouvez utiliser sub_filter . Par exemple:

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
}

Cependant, il n'est pas possible de lire une variable d'environnement dans nginx config - vous pouvez bien sûr écrire un script pour écrire le fichier de configuration nginx comme vous le souhaitez / pour produire un fichier de configuration valide, puis recharger nginx.

AD7six
la source
4

J'ai expérimenté l'utilisation de variables d'environnement sub_filter et nginx mais j'ai conclu que ce n'était pas possible .

Par exemple, cela montre mes expériences et montre que l'utilisation des ENV passés à nginx ne fonctionne pas dans un serverbloc:

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

où le fichier config.json statique que je sers a diverses chaînes de test comme les suivantes:

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

Comme @ AD7six l'a mentionné, la façon de procéder est d'avoir un script qui s'exécute avant que nginx ne commence à produire un fichier de configuration valide à partir des espaces réservés. Mais cela soulève la question, si un script va s'exécuter avant le démarrage de nginx, je peux aussi bien définir le contenu de mon config.jsonfichier dans ce script et ne pas m'embêter sub_filterdu tout.

À M
la source
2
Si c'est pour un fichier statique - il est certainement logique de ne pas le faire via la configuration nginx, j'ai supposé que votre cas d'utilisation était un peu plus large que cela. Pour info / contraste, j'utilise sub_filter "example.com" "example.dev";dans une configuration de développement pour remplacer toutes les références au domaine de production à l'environnement local parce que ces références proviennent de réponses api tierces / code d'application / js / db dumps / etc. - c'est-à-dire que pour nginx, il pourrait être n'importe où dans n'importe quelle réponse html / js / json. +1
AD7six
3

J'ai cherché à résoudre le même problème que l'OP et ce message est apparu dans la recherche Google, alors j'ai pensé ajouter une solution potentielle.

Cet article décrit comment vous pouvez exposer une variable d'environnement dans la configuration nginx: https://blog.doismellburning.co.uk/environment-variables-in-nginx-config/

Et vous pouvez retourner du contenu sans avoir de fichier dans le système de fichiers: Répondre avec 200 depuis la configuration Nginx sans servir de fichier

En combinant ces deux choses, nous nous retrouvons avec ce qui suit:

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

Cela a fonctionné pour moi dans un environnement de test. C'est un peu lourd (pas sûr que ce soit mieux que de générer automatiquement un fichier au lancement de Docker qui contient les variables dont vous avez besoin).

J'espère que cela pourra aider.

Subvention
la source