Ich versuche 2 separate Container zu verbinden:
Das Problem ist, dass PHP-Skripte nicht funktionieren. Möglicherweise ist die PHP-FPM-Konfiguration falsch. Hier ist der Quellcode, der sich in meinem Repository befindet. Hier ist die Datei docker-compose.yml
:
nginx:
build: .
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www/test/
links:
- fpm
fpm:
image: php:fpm
ports:
- "9000:9000"
und Dockerfile
, mit dem ich ein benutzerdefiniertes Image basierend auf dem Nginx-Image erstellt habe:
FROM nginx
# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/
Zuletzt ist hier meine benutzerdefinierte Konfiguration für den virtuellen Nginx-Host:
server {
listen 80;
server_name localhost;
root /var/www/test;
error_log /var/log/nginx/localhost.error.log;
access_log /var/log/nginx/localhost.access.log;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
fastcgi_pass 192.168.59.103:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS off;
}
}
Könnte mir jemand helfen, diese Container richtig zu konfigurieren, um PHP-Skripte auszuführen?
P.S Ich führe Container über Docker-Composer wie folgt aus:
docker-compose up
aus dem Projektstammverzeichnis.
Codieren Sie die IP-Adresse von Containern in nginx config nicht fest, docker link fügt den Hostnamen des verknüpften Rechners zur Hostdatei des Containers hinzu und Sie sollten in der Lage sein, nach Hostnamen zu pingen.
BEARBEITEN: Für Docker 1.9-Netzwerke müssen Sie keine Container mehr verknüpfen. Wenn mehrere Container mit demselben Netzwerk verbunden sind, wird ihre Hostdatei aktualisiert, sodass sie sich gegenseitig über den Hostnamen erreichen können.
Jedes Mal, wenn sich ein Docker-Container aus einem Image dreht (selbst wenn ein vorhandener Container angehalten oder gestartet wird), werden den Containern vom Docker-Host neue IP-Adressen zugewiesen. Diese IP-Adressen befinden sich nicht im selben Subnetz wie Ihre tatsächlichen Computer.
Siehe Docker-Verknüpfungsdokumente (Dies wird von Compose im Hintergrund verwendet.)
aber genauer erklärt in den docker-compose
- Dokumenten zu links & expose
links
links: - db - db:database - redis
Ein Eintrag mit dem Aliasnamen wird in/etc/hosts in Containern für diesen Service erstellt, z.
172.17.2.186 db 172.17.2.186 database 172.17.2.187 redis
aussetzen
Stellen Sie Ports bereit ohne sie auf dem Host-Computer zu veröffentlichen - Sie sind nur für verknüpfte Dienste zugänglich. Es kann nur der interne Port angegeben werden.
und wenn Sie Ihr Projekt so einrichten, dass die Ports + andere Anmeldeinformationen über Umgebungsvariablen abgerufen werden, Links setzen automatisch eine Reihe von Systemvariablen :
Führen Sie
docker-compose run SERVICE env
Aus, um zu sehen, welche Umgebungsvariablen für einen Service verfügbar sind.
name_PORT
Vollständige URL, z. DB_PORT = tcp: //172.17.0.5: 5432
name_PORT_num_protocol
Vollständige URL, z.
DB_PORT_5432_TCP=tcp://172.17.0.5:5432
name_PORT_num_protocol_ADDR
Die IP-Adresse des Containers, z.
DB_PORT_5432_TCP_ADDR=172.17.0.5
name_PORT_num_protocol_PORT
Exposed-Port-Nummer, z.
DB_PORT_5432_TCP_PORT=5432
name_PORT_num_protocol_PROTO
Protokoll (tcp oder udp), z.
DB_PORT_5432_TCP_PROTO=tcp
name_NAME
Vollständig qualifizierter Containername, z.
DB_1_NAME=/myapp_web_1/myapp_db_1
Ich weiß, dass es ein alter Beitrag ist, aber ich hatte das gleiche Problem und konnte nicht verstehen, warum Ihr Code nicht funktioniert hat. Nach vielen Tests habe ich herausgefunden, warum.
docker-compose.yml
nginx:
build: .
ports:
- "80:80"
links:
- fpm
fpm:
image: php:fpm
ports:
- ":9000"
# seems like fpm receives the full path from nginx
# and tries to find the files in this dock, so it must
# be the same as nginx.root
volumes:
- ./:/complex/path/to/files/
/etc/nginx/conf.d/default.conf
server {
listen 80;
# this path MUST be exactly as docker-compose.fpm.volumes,
# even if it doesn't exist in this dock.
root /complex/path/to/files;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/.+\.php(/|$) {
fastcgi_pass fpm:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Dockerfile
FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/
Wie bereits erwähnt, bestand das Problem darin, dass die Dateien vom fpm-Container nicht angezeigt wurden. Um jedoch Daten zwischen Containern auszutauschen, wird empfohlen, Nur-Daten-Container zu verwenden (wie in diesem Artikel ).
Kurz gesagt: Erstellen Sie einen Container, der nur Ihre Daten enthält, geben Sie diese für ein Volume frei und verknüpfen Sie dieses Volume in Ihren Apps mit volumes_from
.
Mit compose (1.6.2 auf meinem Computer) kann docker-compose.yml
Datei würde lesen:
version: "2"
services:
nginx:
build:
context: .
dockerfile: nginx/Dockerfile
ports:
- "80:80"
links:
- fpm
volumes_from:
- data
fpm:
image: php:fpm
volumes_from:
- data
data:
build:
context: .
dockerfile: data/Dockerfile
volumes:
- /var/www/html
Beachten Sie, dass data
ein Volume veröffentlicht, das mit den Diensten nginx
und fpm
verknüpft ist. Dann den Dockerfile
für den data Dienst, der Ihren Quellcode enthält:
FROM busybox
# content
ADD path/to/source /var/www/html
Und das Dockerfile
für nginx, das nur die Standardkonfiguration ersetzt:
FROM nginx
# config
ADD config/default.conf /etc/nginx/conf.d
Zur Vervollständigung ist hier die Konfigurationsdatei, die für das Funktionieren des Beispiels erforderlich ist:
server {
listen 0.0.0.0:80;
root /var/www/html;
location / {
index index.php index.html;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
}
dies weist nginx lediglich an, das gemeinsam genutzte Volume als Dokumentstamm zu verwenden, und legt die richtige Konfiguration für nginx fest, um mit dem fpm-Container kommunizieren zu können (d. h. das richtige Host:PORT
, welches ist fpm:9000
dank der von compose definierten Hostnamen und dem SCRIPT_FILENAME
).
Docker Compose wurde aktualisiert. Sie haben jetzt ein Version 2-Dateiformat .
Dateien der Version 2 werden von Compose 1.6.0+ unterstützt und erfordern eine Docker Engine der Version 1.10.0+.
Sie unterstützen jetzt die Netzwerkfunktion von Docker, mit der beim Ausführen ein Standardnetzwerk namens myapp_default eingerichtet wird.
Von deren Dokumentation würde Ihre Datei ungefähr so aussehen:
version: '2'
services:
web:
build: .
ports:
- "8000:8000"
fpm:
image: phpfpm
nginx
image: nginx
Da diese Container automatisch zum Standardnetzwerk myapp_default hinzugefügt werden, können sie miteinander kommunizieren. Du hättest dann in der Nginx-Konfiguration:
fastcgi_pass fpm:9000;
Denken Sie auch daran, wie von @treeface in den Kommentaren erwähnt, sicherzustellen, dass PHP-FPM Port 9000 überwacht. Bearbeiten Sie hierzu /etc/php5/fpm/pool.d/www.conf
, Wo Sie listen = 9000
Benötigen.
Ich habe das Folgende hier für diejenigen, die ältere Docker-Versionen verwenden, zusammengestellt und möchte die Informationen.
Ich bin immer wieder auf diese Frage auf Google gestoßen, als ich nach einer Antwort auf diese Frage gesucht habe, aber es war nicht ganz das, wonach ich gesucht habe, da der Q/A-Schwerpunkt auf Docker-Compose liegt (was zum Zeitpunkt des Schreibens nur experimentelle Unterstützung hat) Docker-Netzwerkfunktionen). Hier ist meine Sicht auf das, was ich gelernt habe.
Docker hat kürzlich die veraltete Verknüpfung -Funktion zugunsten der Netzwerkfunktion
Daher können Sie mithilfe der Docker Networks-Funktion Container verknüpfen, indem Sie die folgenden Schritte ausführen. Ausführliche Erläuterungen zu den Optionen finden Sie in den zuvor verlinkten Dokumenten.
Erstellen Sie zuerst Ihr Netzwerk
docker network create --driver bridge mynetwork
Führen Sie als Nächstes Ihren PHP-FPM-Container aus, und stellen Sie sicher, dass Sie Port 9000 öffnen und Ihrem neuen Netzwerk zuweisen (mynetwork
).
docker run -d -p 9000 --net mynetwork --name php-fpm php:fpm
Das wichtige Bit hier ist der --name php-fpm
Am Ende des Befehls, der der Name ist, den wir später benötigen werden.
Führen Sie anschließend Ihren Nginx-Container erneut aus und weisen Sie ihn dem von Ihnen erstellten Netzwerk zu.
docker run --net mynetwork --name nginx -d -p 80:80 nginx:latest
Für die Container PHP und Nginx können Sie bei Bedarf auch die Befehle --volumes-from
Usw. hinzufügen.
Nun kommt die Nginx-Konfiguration. Welches sollte ungefähr so aussehen:
server {
listen 80;
server_name localhost;
root /path/to/my/webroot;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
include fastcgi_params;
}
}
Beachten Sie das fastcgi_pass php-fpm:9000;
Im Ortsblock. Das heißt Kontaktcontainer php-fpm
Auf Port 9000
. Wenn Sie Container zu einem Docker Bridge-Netzwerk hinzufügen, erhalten alle automatisch eine Aktualisierung der Hosts-Datei, bei der der Containername mit der IP-Adresse verglichen wird. Wenn Nginx erkennt, dass es weiß, dass es den PHP-FPM-Container kontaktiert, den Sie zuvor php-fpm
Genannt und Ihrem Docker-Netzwerk mynetwork
zugewiesen haben.
Sie können diese Nginx-Konfiguration entweder während des Erstellungsprozesses Ihres Docker-Containers oder danach ganz nach Ihren Wünschen hinzufügen.
Wie frühere Antworten gelöst haben, sollte aber sehr explizit angegeben werden: Der PHP-Code muss im PHP-FPM-Container leben, während die statischen Dateien im Nginx-Container leben müssen. Der Einfachheit halber haben die meisten Leute den gesamten Code an beide angehängt, wie ich es auch weiter unten getan habe. In Zukunft werde ich diese verschiedenen Teile des Codes wahrscheinlich in meinen eigenen Projekten trennen, um zu minimieren, welche Container auf welche Teile zugreifen können.
Aktualisierte meine Beispieldateien unten mit dieser neuesten Offenbarung (danke @alkaline)
Dies scheint das minimale Setup für Docker 2.0 vorwärts zu sein (weil die Dinge in Docker 2.0 viel einfacher wurden)
docker-compose.yml:
version: '2'
services:
php:
container_name: test-php
image: php:fpm
volumes:
- ./code:/var/www/html/site
nginx:
container_name: test-nginx
image: nginx:latest
volumes:
- ./code:/var/www/html/site
- ./site.conf:/etc/nginx/conf.d/site.conf:ro
ports:
- 80:80
(PDATED the docker-compose.yml above: Für Sites mit CSS, Javascript, statischen Dateien usw. benötigen Sie diese Dateien, auf die der Nginx-Container zugreifen kann Da mein Basiscode eine chaotische Mischung aus CSS, JS und PHP ist, wird in diesem Beispiel nur der gesamte Code an beide Container angehängt.
Im selben Ordner:
site.conf:
server
{
listen 80;
server_name site.local.[YOUR URL].com;
root /var/www/html/site;
index index.php;
location /
{
try_files $uri =404;
}
location ~ \.php$ {
fastcgi_pass test-php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Im Ordnercode:
./code/index.php:
<?php
phpinfo();
und vergessen Sie nicht, Ihre hosts-Datei zu aktualisieren:
127.0.0.1 site.local.[YOUR URL].com
und starten Sie Ihren Docker-Compose
$docker-compose up -d
und probieren Sie die URL von Ihrem bevorzugten Browser
site.local.[YOUR URL].com/index.php
Ich denke, wir müssen dem fpm-Container auch das Volumen geben, nicht wahr? Also =>
fpm:
image: php:fpm
volumes:
- ./:/var/www/test/
Wenn ich dies nicht tue, stoße ich beim Auslösen einer Anfrage auf diese Ausnahme, da fpm die angeforderte Datei nicht finden kann:
[Fehler] 6 # 6: * 4 FastCGI gesendet in stderr: "Primäres Skript unbekannt" beim Lesen des Antwortheaders vom Upstream, Client: 172.17.42.1, Server: localhost, Anforderung: "GET/HTTP/1.1", Upstream: "fastcgi : //172.17.0.81: 9000 ", Host:" localhost "
Für alle anderen immer
Nginx 403-Fehler: Verzeichnisindex von [Ordner] ist verboten
beim Benutzen index.php
während index.html
funktioniert perfekt und mit index.php
im Index im Serverblock ihrer Site-Konfiguration in sites-enabled
server {
listen 80;
# this path MUST be exactly as docker-compose php volumes
root /usr/share/nginx/html;
index index.php
...
}
Stellen Sie sicher, dass Ihre nginx.conf-Datei unter /etc/nginx/nginx.conf
lädt Ihre Site-Konfiguration tatsächlich in den http
-Block ...
http {
...
include /etc/nginx/conf.d/*.conf;
# Load our websites config
include /etc/nginx/sites-enabled/*;
}