Stellen Sie statische Inhalte mit Docker + Nginx + PHP-Fpm bereit

9

Ich versuche, eine PHP-Webanwendung mit Docker zu konfigurieren. Die Idee ist, die App php-fpmin einem eigenständigen Container auszuführen und einen anderen Container zu haben, in dem Nginx ausgeführt wird. Die Idee für dieses Setup ist, denselben Nginx-Container zu verwenden, um Anforderungen an andere Webanwendungen zu senden, die bereits auf demselben Computer arbeiten. Das Problem ist, dass ich nginxstatische Dateien (js, css usw.) nicht richtig verarbeiten kann , da die Anforderungen an diese weiterhin bestehen fpm.

So sieht das Dateisystem aus:

/
├── Makefile
├── config
│   └── webapp.config
└── webapp
    └── web
        ├── index.php
        └── static.js

Ich führe die ganze Sache mit einem aus Makefile, der so aussieht (nicht daran interessiert docker-compose):

PWD:=$(shell pwd)
CONFIG:='/config'
WEBAPP:='/webapp'

run: | run-network run-webapp run-nginx

run-network:
    docker network create internal-net

run-webapp:
    docker run --rm \
    --name=webapp \
    --net=internal-net \
    --volume=$(PWD)$(WEBAPP):/var/www/webapp:ro \
    -p 9000:9000 \
    php:5.6.22-fpm-alpine

run-nginx:
    docker run --rm \
    --name=nginx \
    --net=internal-net \
    --volume=$(PWD)$(CONFIG)/webapp.conf:/etc/nginx/conf.d/webapp.domain.com.conf:ro \
    -p 80:80 \
    nginx:1.11.0-alpine

So config/webapp.confsieht mein Aussehen aus.

server {
    listen 80;
    server_name webapp.domain.com;

    # This is where the index.php file is located in the webapp container
    # This folder will contain an index.php file and some static files that should be accessed directly
    root /var/www/webapp/web;

    location / {
        try_files $uri $uri/ @webapp;
    }

    location @webapp {
        rewrite ^(.*)$ /index.php$1 last;
    }

    location ~ ^/index\.php(/|$) {
        include fastcgi_params;

        fastcgi_pass webapp:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

Welche Aktion auch immer benötigt wird, um mit dieser index.phpDatei verarbeitet zu werden, funktioniert. Statische Dateien werden jedoch nicht 404bereitgestellt , was zu bösen Fehlern führt (da für die PHP-Webanwendung keine Routen konfiguriert sind). Ich glaube, nginx versucht, diese aus seinem eigenen Container-Dateisystem zu laden, wenn sie sich tatsächlich im webappContainer befinden @webapp.

Gibt es eine Möglichkeit, die ich konfigurieren kann nginx, um die Dateien bereitzustellen, die sich in einem anderen Container befinden?

ThisIsErico
quelle
3
Verwenden Sie Docker, um Nginx von PHP-Anwendungen zu isolieren, während Nginx Zugriff auf Dateien in den PHP-Anwendungen haben muss?
Stefan Schmiedl
Ich bin nicht sicher, ob ich Ihren Kommentar verstehe ... Ich verwende Docker, um meine Infrastruktur zu verwalten. Ich mache jedoch keine nginxAnforderungsdateien innerhalb der PHP-Anwendung, ich bin ein Proxy fpmdafür und ich muss nginxauf statische Nicht-PHP-Dateien zugreifen.
ThisIsErico
Die Dateien "befinden sich in einem anderen Container", dh nicht dort, wo Nginx sie sehen kann, oder?
Stefan Schmiedl
Das stimmt @Stefan, sie werden nur als Volumes im webappContainer bereitgestellt , nicht in dem nginxeinen.
ThisIsErico

Antworten:

1

Ich habe es geschafft, das Problem zu lösen, indem ich das webappVolume in den nginxContainer eingebunden habe. So run-nginxsieht der Job jetzt aus:

run-nginx:
    docker run --rm \
    --name=nginx \
    --net=internal-net \
    --volume=$(PWD)$(CONFIG)/webapp.conf:/etc/nginx/conf.d/webapp.domain.com.conf:ro \
    --volume=$(PWD)$(WEBAPP)/web:/var/www/webapp/web:ro \
    -p 80:80 \
    nginx:1.11.0-alpine

Und dies ist die webapp.confDatei, die versucht, die statischen Dateien aus dem Container zu laden, und wenn dies nicht möglich ist, die Anfrage an den fpmWorker weiterleitet:

server {
    listen 80;
    server_name webapp.domain.com;

    root /var/www/webapp/web;

    location ~ \.(js|css|png) {
        try_files $uri $uri/;
    }

    location / {
        rewrite ^(.*)$ /index.php$1 last;
    }

    location ~ ^/index\.php(/|$) {
        include fastcgi_params;

        fastcgi_pass webapp:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

Ich würde jedoch gerne wissen, ob es einen besseren Weg gibt, als dasselbe Volume zweimal zu teilen. Vielen Dank!

ThisIsErico
quelle
4
Angesichts Ihrer Trennung von Nginx und PHP in verschiedene Container glaube ich nicht. Sie benötigen die Daten an zwei verschiedenen Orten, Sie müssen sie zweimal bereitstellen. Ich bin auch sehr neugierig, ob jemand eine bessere Idee hat.
Stefan Schmiedl
0

Vielleicht könnte dies mit NFS erreicht werden

Ein Docker-Container mit NFS könnte dort erstellt werden, wo sich der Code befindet, der mit den Containern verknüpft werden könnte, auf denen nginx und php ausgeführt werden. Die Dateien würden nur in einem Container gespeichert. Dies könnte auch eine weitere Isolationsschicht bereitstellen.

Magarusu
quelle
0

Ich habe zwei vorgeschlagene Optionen: Die erste besteht darin, Ihre statischen Assets in eg / static abzulegen und nginx anzuweisen, einen anderen Backend-Service für diese aufzurufen. Schritte:

1) Aktualisieren Sie Ihre Websites so, dass sie für statische Assets auf / static / * verweisen, sodass z. B. /styles.css zu /static/styles.css wird

2) Legen Sie Ihr Vermögen entweder in einen separaten Container, der möglicherweise von einem anderen Nginx bereitgestellt wird (damit Sie den Container für mehrere Standorte wiederverwenden können).

3) Bearbeiten Sie die Datei nginx.conf, um alle Anforderungen an / static / * an den neuen Container zu senden:

location /static/ {
   proxy_pass http://static-container;
}

Die zweite Option besteht darin, Ihre statischen Assets einfach auf ein CDN zu verschieben. Sie müssen also nur Ihre Website aktualisieren, um jedes statische Asset von einer externen URL ( https: //cdnwebsite/asdsadasda/styles.css anstelle von /styles.css oder) zu laden /static/styles.css)

Die zweite Option hat gegenüber den anderen mehrere Vorteile, hauptsächlich in Bezug auf die Leistung. Ein CDN wird diese schneller bedienen und Sie arbeiten auch an der Beschränkung der gleichzeitigen Verbindung, die ein Browser für jeden FQDN festlegen kann, sodass Ihre Seite möglicherweise schneller geladen wird, da mehr simultane Verbindungen zum Laden Ihrer Site verwendet werden.

Pedro Perez
quelle