J'ai récemment commencé à migrer vers Docker 1.9 et les fonctionnalités réseau de Docker-Compose 1.5 pour remplacer les liens.
Jusqu'à présent, avec des liens, il n'y avait aucun problème avec la connexion de nginx à mon serveur fastcgi php5-fpm situé sur un serveur différent dans un groupe via docker-compose. Récemment, lorsque j’exécute docker-compose --x-networking up
, mes conteneurs php-fpm, mongo et nginx s’amorcent, mais nginx se ferme immédiatement avec [emerg] 1#1: Host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16
.
Cependant, si j'exécute à nouveau la commande docker-compose pendant que les conteneurs php et mongo sont en cours d'exécution (nginx a quitté), nginx démarre et fonctionne correctement à partir de ce moment.
Ceci est mon fichier docker-compose.yml
:
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
php:
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
mongo:
image: mongo
ports:
- "42017:27017"
volumes:
- /var/mongodata/wa-api:/data/db
command: --smallfiles
Ceci est mon default.conf
pour nginx:
server {
listen 80;
root /var/www/test;
error_log /dev/stdout debug;
access_log /dev/stdout;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
# Referencing the php service Host (Docker)
fastcgi_pass waapi_php_1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# We must reference the document_root of the external server ourselves here.
fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
Comment faire en sorte que nginx fonctionne avec un seul appel composé par un menu fixe?
Il est possible d'utiliser "volumes_from" comme solution de contournement jusqu'à l'introduction de la fonction de dépendance (expliquée ci-dessous). Tout ce que vous avez à faire est de changer votre fichier docker-compose comme ci-dessous:
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
volumes_from:
- php
php:
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
mongo:
image: mongo
ports:
- "42017:27017"
volumes:
- /var/mongodata/wa-api:/data/db
command: --smallfiles
Une grande mise en garde dans l'approche ci-dessus est que les volumes de php sont exposés à nginx, ce qui n'est pas souhaité. Mais pour le moment, cette solution de contournement spécifique au docker pourrait être utilisée.
includes_on feature Ce serait probablement une réponse futuriste. Parce que la fonctionnalité n'est pas encore implémentée dans Docker (à partir de la version 1.9)
Il est proposé d'introduire "depend_on" dans la nouvelle fonctionnalité de mise en réseau introduite par Docker. Mais il y a un long débat autour du même @ (https://github.com/docker/compose/issues/374 Par conséquent, une fois implémentée, la fonction depend_on pourrait être utilisée pour commander le début du conteneur. -up, mais pour le moment, vous devrez recourir à l'un des éléments suivants:
Ceci peut être résolu avec la directive depends_on
mentionnée depuis sa mise en œuvre maintenant (2016):
version: '2'
services:
nginx:
image: nginx
ports:
- "42080:80"
volumes:
- ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- php
php:
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
depends_on:
- mongo
mongo:
image: mongo
ports:
- "42017:27017"
volumes:
- /var/mongodata/wa-api:/data/db
command: --smallfiles
Testé avec succès avec:
$ docker-compose version
docker-compose version 1.8.0, build f3628c7
Trouvez plus de détails dans la documentation .
Un article très intéressant est également consacré à ce sujet: Contrôle de l’ordre de démarrage dans Compose
Vous pouvez définir les directives max_fails et fail_timeout de nginx pour indiquer que nginx doit réessayer le nombre x de demandes de connexion au conteneur avant l'échec de l'indisponibilité du serveur en amont.
Vous pouvez régler ces deux chiffres en fonction de votre infrastructure et de la vitesse à laquelle toute la configuration est imminente. Vous pouvez lire plus de détails sur la section des contrôles de santé de l'URL ci-dessous: http://nginx.org/en/docs/http/load_balancing.html
Voici l'extrait de http://nginx.org/en/docs/http/ngx_http_upstream_module.html#servermax_fails=number
définit le nombre de tentatives infructueuses de communication avec le serveur qui doit se produire pendant la durée définie par fail_timeout paramètre à considérer le serveur indisponible pour une durée également défini par le paramètre fail_timeout. Par défaut, le nombre d'échecs tentatives est défini sur 1. La valeur zéro désactive la comptabilisation de tentatives. Ce qui est considéré comme une tentative infructueuse est défini par le proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream et les directives memcached_next_upstream.
fail_timeout=time
définit le temps pendant lequel le nombre spécifié d'échecs les tentatives de communication avec le serveur doivent arriver à considérer le serveur indisponible; et la période pendant laquelle le serveur sera considéré comme indisponible. Par défaut, le paramètre est défini sur 10 secondes.
Pour être précis, votre fichier de configuration nginx modifié devrait être le suivant (ce script suppose que tous les conteneurs sont actifs au moins 25 secondes. Sinon, veuillez modifier le paramètre fail_timeout ou max_fails dans la section en amont ci-dessous): Remarque: I Je n'ai pas testé le script moi-même, vous pouvez donc l'essayer!
upstream phpupstream {
waapi_php_1:9000 fail_timeout=5s max_fails=5;
}
server {
listen 80;
root /var/www/test;
error_log /dev/stdout debug;
access_log /dev/stdout;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
# Referencing the php service Host (Docker)
fastcgi_pass phpupstream;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# We must reference the document_root of the external server ourselves here.
fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
En outre, comme indiqué dans la note suivante de docker ( - https://github.com/docker/compose/blob/master/docs/networking.md ), il est évident que la logique de nouvelle tentative permettant de vérifier l'intégrité du les autres conteneurs ne sont pas de la responsabilité du docker et ces derniers doivent effectuer le bilan de santé eux-mêmes
Mise à jour des conteneurs
Si vous modifiez la configuration d'un service et exécutez docker-compose pour le mettre à jour, l'ancien conteneur sera supprimé et le nouveau rejoindra le réseau sous une adresse IP différente mais sous le même nom . Les conteneurs en cours pourront rechercher ce nom et se connecter à la nouvelle adresse, mais l'ancienne adresse cessera de fonctionner.
Si des conteneurs ont des connexions ouvertes sur l'ancien conteneur, ils sera fermé. C'est la responsabilité du conteneur de détecter ceci condition, recherchez à nouveau le nom et reconnectez-vous.
Je crois que Nginx ne prend pas en compte le résolveur de Docker (127.0.0.11), alors veuillez essayer d’ajouter:
resolver 127.0.0.11
dans votre fichier de configuration nginx?
Si vous êtes si perdu pour lire le dernier commentaire. J'ai atteint une autre solution.
Le problème principal est la façon dont vous avez nommé les noms de services.
Dans ce cas, si dans votre docker-compose.yml
, le service pour php s'appelle "api" ou quelque chose du genre, vous devez vous assurer que dans le fichier nginx.conf
la ligne commençant par fastcgi_pass
porte le même nom que le service php. i.e fastcgi_pass api:9000;
avoir le même problème jusqu'à ce qu'il y avait dans un docker-compose.yml deux réseaux définis: backend et frontend. Lorsque tous les conteneurs sont exécutés sur le même réseau par défaut, tout fonctionne correctement.
Avait le même problème et résolu. Veuillez ajouter la ligne suivante à la section nginx de docker-compose.yml:
links:
- php:waapi_php_1
L'hôte dans la section fastcgi_pass de nginx config doit être lié à la configuration de docker-compose.yml nginx.
Ma solution de contournement (après de nombreux essais et erreurs):
Afin de résoudre ce problème, je devais obtenir le nom complet du conteneur Docker 'en amont', trouvé en exécutant docker network inspect my-special-docker-network
et en obtenant la propriété complète name
du conteneur en amont en tant que telle:
"Containers": {
"39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
"Name": "my_upstream_container_name_1_2478f2b3aca0",
Ensuite, cela utilisé dans le fichier NGINX my-network.local.conf
du bloc location
de la propriété proxy_pass
: (Notez l'ajout du GUID au nom du conteneur):
location / {
proxy_pass http://my_upsteam_container_name_1_2478f2b3aca0:3000;
Contrairement à l'ancien, mais maintenant cassé:
location / {
proxy_pass http://my_upstream_container_name_1:3000
La cause la plus probable est une modification récente de Docker Compose, dans leur schéma de nommage par défaut pour les conteneurs, comme indiqué dans la liste ici .
Cela semble se produire pour moi et mon équipe au travail, avec les dernières versions de l'image Docker nginx
:
(nouveau sur nginx) Dans mon cas, le nom de dossier était incorrect
Pour config
upstream serv {
server ex2_app_1:3000;
}
assurez-vous que le dossier de l'application est dans le dossier ex2:
ex2/app/...
Avec les liens, un ordre de démarrage du conteneur est appliqué. Sans liens, les conteneurs peuvent commencer dans n'importe quel ordre (ou vraiment tous en même temps).
Je pense que l'ancienne configuration aurait pu rencontrer le même problème si le conteneur waapi_php_1
était lent à démarrer.
Je pense que pour que cela fonctionne, vous pouvez créer un script nginx entrypoint qui interroge et attend que le conteneur php soit démarré et prêt.
Je ne suis pas sûr que nginx puisse réessayer automatiquement la connexion en amont, mais si c'est le cas, ce serait une meilleure option.
Peut-être que le meilleur choix pour éviter les problèmes de liaison de conteneurs est le fonctionnalités de docker
Mais pour que cela fonctionne, docker crée des entrées dans le répertoire/etc/hosts pour chaque conteneur à partir des noms attribués à chaque conteneur.
avec docker-compose --x-networking-up ressemble à peu près à [docker_compose_folder] - [service] - [numéro incrémental]
Pour ne pas dépendre de changements inattendus dans ces noms, vous devez utiliser le paramètre
nom_conteneur
dans votre docker-compose.yml comme suit:
php:
container_name: waapi_php_1
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
Assurez-vous qu'il s'agit du même nom que celui attribué dans votre fichier de configuration pour ce service. Je suis à peu près sûr qu'il existe de meilleures façons de le faire, mais c'est une bonne approche pour commencer.
Deux choses à noter:
links
pour ajouter la résolution des hôtesMon exemple:
version: '3'
services:
mysql:
image: mysql:5.7
restart: always
container_name: mysql
volumes:
- ./mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: tima@123
network_mode: bridge
ghost:
image: ghost:2
restart: always
container_name: ghost
depends_on:
- mysql
links:
- mysql
environment:
database__client: mysql
database__connection__Host: mysql
database__connection__user: root
database__connection__password: xxxxxxxxx
database__connection__database: ghost
url: https://www.itsfun.tk
volumes:
- ./ghost-data:/var/lib/ghost/content
network_mode: bridge
nginx:
image: nginx
restart: always
container_name: nginx
depends_on:
- ghost
links:
- ghost
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/letsencrypt:/etc/letsencrypt
network_mode: bridge
Si vous ne spécifiez pas de pont réseau spécial, ils utiliseront tous le même pont par défaut.
Vous devez utiliser quelque chose comme docker-gen pour mettre à jour dynamiquement la configuration de nginx lorsque votre backend est en place.
Voir:
Je pense que Nginx + (version premium) contient également un paramètre de résolution ( http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream )