Ich habe vor kurzem mit der Migration zu Docker 1.9 und den Netzwerkfunktionen von Docker-Compose 1.5 begonnen, um die Verwendung von Links zu ersetzen.
Bisher gab es bei Links keine Probleme mit nginx, die Verbindung zu meinem php5-fpm fastcgi-Server auf einem anderen Server in einer Gruppe über Docker-Compose herzustellen. Wenn ich jedoch docker-compose --x-networking up
laufe, werden meine PHP-fpm-, mongo- und nginx-Container hochgefahren, nginx wird jedoch sofort mit [emerg] 1#1: Host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16
beendet.
Wenn ich jedoch den Docker-Compose-Befehl erneut ausführen, während die PHP- und Mongo-Container ausgeführt werden (Nginx wurde beendet), wird Nginx gestartet und funktioniert von da an einwandfrei.
Dies ist meine docker-compose.yml
-Datei:
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
Dies ist mein default.conf
für 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;
}
}
Wie kann ich erreichen, dass Nginx nur mit einem einzigen Docker-Compose-Aufruf funktioniert?
Es besteht die Möglichkeit, "volume_from" als Problemumgehung zu verwenden, bis die Funktion "_hunt_on" (siehe unten) eingeführt wird. Sie müssen lediglich Ihre Docker-Compose-Datei wie folgt ändern:
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
Ein großer Nachteil bei dem obigen Ansatz ist, dass die Volumina von php Nginx ausgesetzt sind, was nicht erwünscht ist. Im Moment ist dies jedoch eine Docker-spezifische Problemumgehung, die verwendet werden könnte.
depend_on feature Dies wäre wahrscheinlich eine futuristische Antwort. Weil die Funktionalität noch nicht in Docker implementiert ist (Stand 1.9)
Es gibt einen Vorschlag zur Einführung von "depend_on" in die von Docker eingeführte neue Netzwerkfunktion. Es gibt jedoch eine lange laufende Debatte über das gleiche @ https://github.com/docker/compose/issues/374 . Sobald das Feature implementiert ist, kann es daher dazu verwendet werden, den Container zu starten , aber im Moment müssten Sie eine der folgenden Möglichkeiten ergreifen:
Dies kann mit der erwähnten depends_on
-Direktive seit ihrer Implementierung (2016) gelöst werden:
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
Erfolgreich getestet mit:
$ docker-compose version
docker-compose version 1.8.0, build f3628c7
Weitere Details finden Sie in der Dokumentation .
Es gibt auch einen sehr interessanten Artikel zu diesem Thema: Startreihenfolge in Compose steuern
Sie können die Direktiven max_fails und fail_timeout von nginx festlegen, um anzugeben, dass der nginx die x-Anzahl der Verbindungsanforderungen an den Container erneut versuchen soll, bevor er auf der Nichtverfügbarkeit des Upstream-Servers fehlschlägt.
Sie können diese beiden Zahlen entsprechend Ihrer Infrastruktur und der Geschwindigkeit anpassen, mit der die gesamte Einrichtung gestartet wird. Weitere Informationen zum Abschnitt "Gesundheitschecks" der folgenden URL finden Sie hier: http://nginx.org/de/docs/http/load_balancing.html
Es folgt der Auszug aus http://nginx.org/de/docs/http/ngx_http_upstream_module.html#servermax_fails=number
legt die Anzahl der fehlgeschlagenen Versuche fest, mit dem .__ zu kommunizieren. Server, der in der durch fail_timeout festgelegten Dauer erfolgen soll Parameter, der den Server als nicht verfügbar für eine festgelegte Dauer betrachtet durch den Parameter fail_timeout. Standardmäßig die Anzahl der nicht erfolgreichen Versuche ist auf 1 gesetzt. Der Nullwert deaktiviert die Abrechnung von Versuche. Was als ein erfolgloser Versuch angesehen wird, wird durch die .__ definiert. proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream- und memcached_next_upstream-Direktiven.
fail_timeout=time
legt die Zeit fest, in der die angegebene Anzahl von nicht erfolgreichen Versuche, mit dem Server zu kommunizieren, sollten die .__ berücksichtigen. Server nicht verfügbar; und der Zeitraum, auf dem sich der Server befindet als nicht verfügbar betrachtet. Der Parameter ist standardmäßig auf 10 eingestellt Sekunden.
Um genau zu sein, sollte Ihre modifizierte Nginx-Konfigurationsdatei wie folgt aussehen (dieses Skript geht davon aus, dass alle Container mindestens 25 Sekunden lang aktiv sind. Andernfalls ändern Sie im folgenden Upstream-Abschnitt den Parameter fail_timeout oder max_fails): Hinweis: I Ich habe das Skript nicht selbst getestet, also könnte man es ausprobieren!
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;
}
}
Gemäß der folgenden Anmerkung vom Docker ( https://github.com/docker/compose/blob/master/docs/networking.md ) ist es auch offensichtlich, dass die Wiederholungslogik zur Überprüfung des Zustands der Andere Container liegen nicht in der Verantwortung des Dockers, vielmehr sollten die Container die Gesundheitsprüfung selbst durchführen.
Aktualisieren von Containern
Wenn Sie eine Konfigurationsänderung an einem Dienst vornehmen und docker-compose .__ ausführen. Zum Aktualisieren wird der alte Container entfernt und der neue verbindet sich unter einer anderen IP-Adresse, aber mit demselben Namen . Laufende Container können diesen Namen nachschlagen und sich mit .__ verbinden. die neue Adresse, aber die alte Adresse funktioniert nicht mehr.
Wenn Container mit dem alten Container verbunden sind, werden sie wird geschlossen. Es liegt in der Verantwortung eines Containers, dies zu erkennen Bedingung, suchen Sie den Namen erneut und verbinden Sie sich erneut.
Ich glaube, dass Nginx das Konto Docker Resolver (127.0.0.11) nicht berücksichtigt.
resolver 127.0.0.11
in deiner Nginx-Konfigurationsdatei?
Wenn Sie so verloren sind, lesen Sie den letzten Kommentar. Ich habe eine andere Lösung gefunden.
Das Hauptproblem ist die Art und Weise, wie Sie die Servicenamen benannt haben.
In diesem Fall müssen Sie, wenn in Ihrem docker-compose.yml
der Dienst für php "api" oder so ähnlich heißt, sicherstellen, dass in der Datei nginx.conf
die Zeile, die mit fastcgi_pass
beginnt, denselben Namen wie der php-Dienst hat. das heißt fastcgi_pass api:9000;
habe das gleiche problem bis es in einem docker-compose.yml zwei netzwerke gab: backend und frontend. Wenn alle Container in demselben Standardnetzwerk ausgeführt werden, funktioniert alles einwandfrei.
Hatte das gleiche Problem und löste es. Fügen Sie dem Abschnitt docker-compose.yml nginx die folgende Zeile hinzu:
links:
- php:waapi_php_1
Der Host in nginx config fastcgi_pass sollte in der docker-compose.yml nginx-Konfiguration verlinkt sein.
Mein Workaround (nach vielem Ausprobieren):
Um dieses Problem zu umgehen, musste ich den vollständigen Namen des Docker-Containers "upstream" abrufen, der durch Ausführen von docker network inspect my-special-docker-network
und der vollständigen name
-Eigenschaft des Upstream-Containers als solches ermittelt wurde:
"Containers": {
"39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
"Name": "my_upstream_container_name_1_2478f2b3aca0",
Dann wurde dies in der NGINX my-network.local.conf
-Datei im location
-Block der proxy_pass
-Eigenschaft verwendet: (Beachten Sie das Hinzufügen von GUID zum Containernamen):
location / {
proxy_pass http://my_upsteam_container_name_1_2478f2b3aca0:3000;
Im Gegensatz zu den vorher funktionierenden, aber jetzt kaputt:
location / {
proxy_pass http://my_upstream_container_name_1:3000
Die wahrscheinlichste Ursache ist eine kürzlich vorgenommene Änderung von Docker Compose in ihrem Standardnamensschema für Container, die in der Liste hier aufgeführt ist.
Dies scheint für mich und mein Team bei der Arbeit zu geschehen, mit den neuesten Versionen des Docker nginx
-Bildes:
(neu bei nginx) In meinem Fall war es ein falscher Ordnername
Für die Konfig
upstream serv {
server ex2_app_1:3000;
}
stellen Sie sicher, dass sich der App-Ordner im Ordner ex2 befindet:
ex2/app/...
Bei Links wird eine Reihenfolge beim Starten des Containers erzwungen. Ohne Verknüpfungen können die Container in beliebiger Reihenfolge (oder eigentlich alle gleichzeitig) gestartet werden.
Ich denke, das alte Setup hätte das gleiche Problem treffen können, wenn der waapi_php_1
-Container langsam gestartet wurde.
Damit das funktioniert, können Sie ein Nginx-Entypoint-Skript erstellen, das abfragt und darauf wartet, dass der PHP-Container gestartet und fertig ist.
Ich bin nicht sicher, ob Nginx die Verbindung zum Upstream automatisch wiederherstellen kann, aber wenn dies der Fall ist, wäre dies eine bessere Option.
Die beste Wahl, um Probleme mit der Verknüpfung von Containern zu vermeiden, sind die docker network -Funktionen
Damit dies funktioniert, erstellt das Andockfenster Einträge in / etc/hosts für jeden Container aus den zugewiesenen Namen für jeden Container.
mit docker-compose --x-networking -up ist so etwas wie [docker_compose_folder] - [service] - [incremental_number]
Um nicht von unerwarteten Änderungen in diesen Namen abhängig zu sein, sollten Sie den Parameter verwenden
container_name
in Ihrem docker-compose.yml wie folgt:
php:
container_name: waapi_php_1
build: config/docker/php
ports:
- "42022:22"
volumes:
- .:/var/www/html
env_file: config/docker/php/.env.development
Stellen Sie sicher, dass es sich um denselben Namen handelt, der diesem Dienst in Ihrer Konfigurationsdatei zugewiesen wurde. Ich bin mir ziemlich sicher, dass es bessere Wege gibt, dies zu tun, aber es ist ein guter Ansatz, um anzufangen.
Zwei Dinge, die es zu erwähnen gilt:
links
können Sie Hosts resol hinzufügenMein Beispiel:
version: '3'
services:
mysql:
image: mysql:5.7
restart: always
container_name: mysql
volumes:
- ./mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: [email protected]
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
Wenn Sie keine spezielle Netzwerkbrücke angeben, wird für alle dieselbe Standardbrücke verwendet.
Sie müssen etwas wie Docker-Gen verwenden, um die Nginx-Konfiguration dynamisch zu aktualisieren, wenn Ihr Backend aktiv ist.
Sehen:
Ich glaube, Nginx + (Premium-Version) enthält auch einen Auflösungsparameter ( http://nginx.org/de/docs/http/ngx_http_upstream_module.html#upstream )