[ Rédigé à la baisse et édité à partir de https://stackoverflow.com/questions/21933955 car il a été jugé trop sysadmin-like pour StackOverflow.]
J'ai un conteneur Docker sous Nginx, qui est lié à un autre conteneur Docker. Le nom d'hôte et l'adresse IP du deuxième conteneur sont chargés dans le conteneur Nginx en tant que variables d'environnement au démarrage, mais ils ne sont pas connus auparavant (dynamique). Je veux que nginx.conf
j'utilise ces valeurs - par exemple
upstream gunicorn {
server $APP_HOST_NAME:$APP_HOST_PORT;
}
Comment obtenir des variables d'environnement dans la configuration de Nginx au démarrage?
EDIT 1
Ceci est le fichier entier, après la réponse suggérée ci-dessous:
env APP_WEB_1_PORT_5000_TCP_ADDR;
# Nginx host configuration for django_app
# Django app is served by Gunicorn, running under port 5000 (via Foreman)
upstream gunicorn {
server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;
}
server {
listen 80;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location /static/ {
alias /app/static/;
}
location /media/ {
alias /app/media/;
}
location / {
proxy_pass http://gunicorn;
}
}
Le rechargement de nginx alors des erreurs:
$ nginx -s reload
nginx: [emerg] unknown directive "env" in /etc/nginx/sites-enabled/default:1
EDIT 2: plus de détails
Variables d'environnement actuelles
root@87ede56e0b11:/# env | grep APP_WEB_1
APP_WEB_1_NAME=/furious_turing/app_web_1
APP_WEB_1_PORT=tcp://172.17.0.63:5000
APP_WEB_1_PORT_5000_TCP=tcp://172.17.0.63:5000
APP_WEB_1_PORT_5000_TCP_PROTO=tcp
APP_WEB_1_PORT_5000_TCP_PORT=5000
APP_WEB_1_PORT_5000_TCP_ADDR=172.17.0.63
Racine nginx.conf:
root@87ede56e0b11:/# head /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
env APP_WEB_1_PORT_5000_TCP_ADDR;
Configuration du site nginx:
root@87ede56e0b11:/# head /etc/nginx/sites-available/default
# Django app is served by Gunicorn, running under port 5000 (via Foreman)
upstream gunicorn {
server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;
}
server {
listen 80;
Rechargez la configuration de nginx:
root@87ede56e0b11:/# nginx -s reload
nginx: [emerg] directive "server" is not terminated by ";" in /etc/nginx/sites-enabled/default:3
server $ENV{"APP_WEB_1_PORT_5000_TCP_ADDR"}:5000;
parserver app_web_1:5000;
app_web_1
, une nouvelle adresse IP sera obtenue. Vous devrez donc également redémarrer votre conteneur nginx. Docker le relancerait avec une mise à jour/etc/hosts
afin que vous n'ayez pas besoin de modifier le (s) fichier (s) de configuration de nginx.Réponses:
À partir du fichier officiel de docker Nginx:
Mise à jour:
Mais vous savez que cela a causé à ses variables Nginx comme ceci:
endommagé à:
Donc, pour éviter cela, j'utilise cette astuce:
J'ai un script pour exécuter Nginx, utilisé sur le
docker-compose
fichier en tant qu'option de commande pour le serveur Nginx, je l'ai nommérun_nginx.sh
:Et à cause de la nouvelle
DOLLAR
variable définie dans lerun_nginx.sh
script, le contenu de monnginx.conf.template
fichier pour la variable elle-même est comme ceci:Et pour ma variable définie, c'est comme ça:
Aussi ici , il y a mon cas d'utilisation réel pour cela.
la source
proxy_set_header Host $http_host;
command: /bin/bash -c "envsubst '$VAR1 $VAR2' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
fonctionne pour moi car je sais comment ils s'appellent ...$
, devrait êtrecommand: /bin/bash -c "envsubst '\$VAR1 \$VAR2' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
CMD ["/bin/sh","-c", "if [ -n \"${SOME_ENV}\" ]; then echo envsubst '${SOME_ENV}' with ${SOME_ENV} && envsubst '${SOME_ENV}' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf; fi ; nginx -g 'daemon off;'"]
Faire cela avec Lua est nettement plus facile qu'il n'y paraît:
J'ai trouvé ça ici:
https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html
Modifier:
Apparemment, cela nécessite l'installation du module lua: https://github.com/openresty/lua-nginx-module
Edit 2:
Notez qu'avec cette approche, vous devez définir une
env
variable dans Nginx:Vous devez le faire dans un contexte de niveau supérieur
nginx.conf
ou cela ne fonctionnera pas! Pas dans le bloc serveur ou dans la configuration de certains sites/etc/nginx/sites-available
, car il est inclusnginx.conf
dans lehttp
contexte (qui n'est pas le contexte de niveau supérieur).Notez également qu'avec cette approche, si vous essayez de faire une redirection, par exemple:
ça ne marchera pas aussi bien:
Et si vous lui attribuez un nom de variable distinct:
Nginx ne l'interprète pas et vous redirigera vers
https://%24server_name_from_env/
.la source
env NGINX_SERVERNAME
quelque part dans votre nginx.conf.set_by_lua
la variable dans le fichier de configuration inclus, alors que laenv MY_VAR
déclaration était dans le fichier principal nginx.conf, comme suggéré. Quel dommage, cela aurait été la solution la plus propre!envsubst
? Je suppose que le pro est que vous n’avez pas besoin d’exécuter laenvsubstr
commande avant de démarrer le serveur et que vous avez besoin d’installer le module Lua? Je me demande s'il y a des implications pour la sécurité de l'une ou l'autre approche?envsubst
et qui sontJ'ai écrit quelque chose qui peut ou peut ne pas être utile: https://github.com/yawn/envplate
Il édite en ligne les fichiers de configuration avec des références $ {clé} aux variables d’environnement, en créant éventuellement des sauvegardes / journaux. Il est écrit en Go et le binaire statique résultant peut être simplement téléchargé à partir de l'onglet de publication pour Linux et MacOS.
Il peut également exécuter des processus exec (), remplacer les valeurs par défaut, les journaux et présenter une sémantique des échecs sensible.
la source
L'image officielle de nginx recommande l'utilisation
envsubst
, mais comme l'ont souligné d'autres personnes, elle remplacera également d'$host
autres variables, ce qui n'est pas souhaitable. Mais heureusement,envsubst
on peut prendre comme paramètre les noms des variables à remplacer .Pour éviter un paramètre de commande très complexe sur le conteneur (comme dans l'exemple lié), vous pouvez écrire un script de point d'entrée Docker qui remplira les variables d'environnement avant d'exécuter la commande. Le script entrypoint est également un bon endroit pour valider les paramètres et définir les valeurs par défaut.
Voici un exemple de conteneur nginx qui inclut des paramètres
API_HOST
etAPI_PORT
des variables d’environnement.nginx-default.conf.template
docker-entrypoint.sh
Dockerfile
la source
Ce que j'ai fait était d'utiliser le erb !
--Après l'utilisation de erb
Ceci est utilisé dans le cloudfoundry staticfile-buildpack
Exemple de configuration de nginx: https://github.com/cloudfoundry/staticfile-buildpack/blob/master/conf/nginx.conf
Dans ton cas
devenir
la source
En vous référant à la réponse sur l'utilisation de erb, cela peut être fait comme ci-dessous.
Ecrivez le fichier de configuration NGINX en tant que fichier erb contenant la variable d’environnement et évaluez-le à l’aide de la commande erb dans un fichier de configuration normal.
Dans le bloc serveur du fichier nginx.conf.erb, il pourrait y avoir
la source
erb
peut-on effectuer une substitution de variable ... après le démarrage du conteneur, n'est-ce pas?) -erb
ce truc en Ruby est-il correct: stuartellis.name/articles/erbJe sais que c'est une vieille question, mais juste au cas où quelqu'un tomberait (comme je l'ai maintenant), il y a une bien meilleure façon de le faire. Comme docker insère l’alias du conteneur lié dans / etc / hosts, vous pouvez simplement le faire.
en supposant que votre commande docker est quelque chose comme
docker run --link othercontainer:docker_link_alias nginx_container
.la source
Une autre option ... Je viens de trouver cet outil aujourd'hui: https://github.com/kreuzwerker/envplate ... Écrit en Go, il peut être installé très facilement. Son utilisation est assez simple. Bien que vous deviez placer des variables de modèle dans votre nginx.conf.
Par exemple,
${SOME_ENV_VAR}
sera remplacé lorsque laep
commande de envplate est appelée sur le fichier. Donc, si votre fichier Docker ne parvient pas à obtenir ce fichier binaire ou s’il ne s’exécute pas pour une raison quelconque, votre configuration serait invalide. Juste une petite note comparée à d’autres solutions comme l’utilisation d’extensions perl ou lua.J'aime beaucoup la façon dont vous pouvez définir les valeurs par défaut lorsque la variable d'environnement n'est pas définie. Ex.
${SOME_ENV_VAR:default-value}
(et vous pouvez échapper aux valeurs). Encore une fois, envplate doit toujours être exécuté avec succès.L'un des avantages de cette approche est que vous ne vous retrouvez pas avec une image Docker plus grande que nécessaire, car vous avez commencé à installer toutes sortes de modules supplémentaires dont vous n'auriez pas besoin autrement. Cela peut aussi être plus facile que d’utiliser sed si la situation commence à devenir complexe et si elle contient la fonctionnalité de valeur par défaut
la source
Je réalise cela en utilisant un script shell.
Voici le modèle nginx:
Et le script pour remplacer les variables d'environnement est ici:
la source
Une autre possibilité consiste à utiliser la commande 'sed' avec des expressions régulières pour ne pas avoir à manipuler vos fichiers de configuration du tout! De cette façon, vous pouvez utiliser vos fichiers de configuration normalement, mais lorsque vous exécutez docker, les valeurs sont échangées avec les variables env. Rien de tout cela "ajoute une chaîne de texte à vos fichiers de configuration que vous recherchez et remplacez par".
Vous pouvez créer un fichier run.sh avec des valeurs de remplacement à l'aide de vos variables d'environnement.
Pour changer les "7" sur cette ligne:
Commande Sed utilisant client_body_timeout comme ligne de recherche et $ client_body_timeout comme variable env. De remplacement:
Copiez / collez cette ligne pour chaque paramètre que vous souhaitez définir et modifiez le paramètre client_body_timeout avec l’option config et $ client_body_timeout avec la variable env à laquelle il est associé. Utilisez le fichier de configuration existant et cela fonctionnera simplement.
la source
Voici un exemple d'utilisation de l'
sed
approche, pas nécessairement meilleure, mais elle peut être utile à certains. Tout d’abord, ajoutez un mot-clé personnalisé à remplacer dans le fichier conf. En second lieu , créer une dockerfile qui déclare uneENV
variable, puis unCMD
qui utilisesed
pour modifier la configuration avant d' exécuter nginx explicitement.Supposons donc que votre default.conf contient ceci avec le mot clé
docker_host
:Et écrivez votre Dockerfile similaire à:
Construisez ensuite l'image et exécutez le conteneur à l'aide de
la source
Manière correcte de faire ceci avec lua, puisque la réponse ci-dessus est périmée:
la source
Vous devriez pouvoir faire ce que vous voulez avec les modèles de Dockerize .
la source