wake-up-neo.com

Wie werden PHP-FPM- und Nginx Docker-Container korrekt verknüpft?

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.

84

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

30
Vincent De Smet

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/
75
Rafael Quintela

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).

22
iKanor

Neue Antwort

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.

Alte Antwort

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.

14
DavidT

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
8
Phillip

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 "

6
leberknecht

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/*;
}
0
myol