Podaj zawartość statyczną za pomocą okna dokowanego + nginx + php-fpm

10

Próbuję skonfigurować aplikację internetową php przy użyciu okna dokowanego. Chodzi o to, aby uruchomić aplikację php-fpmw oddzielnym kontenerze i mieć inny kontener, który będzie działał nginx. Ideą tego ustawienia jest użycie tego samego kontenera nginx do przesyłania żądań proxy do innych aplikacji internetowych, które już działają na tym samym komputerze. Problem polega na tym, że nie mogę nginxpoprawnie przetworzyć plików statycznych (js, css itp.), Ponieważ żądania do nich wciąż się pojawiają fpm.

Tak wygląda system plików:

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

Korzystam z Makefiletego, który wygląda tak (nie jestem tym zainteresowany 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

Tak config/webapp.confwygląda mój .

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;
    }
}

Działa dowolne działanie, które musi zostać przetworzone przy użyciu tego index.phppliku. Jednak pliki statyczne nie będą obsługiwane, co spowoduje nieprzyjemne 404błędy (ponieważ aplikacja sieci web php tak naprawdę nie ma skonfigurowanych tras dla nich). Wierzę, że nginx próbuje załadować te pliki ze swojego własnego systemu plików kontenera, gdy faktycznie znajdują się w webappkontenerze, ale nie powracają do @webapp.

Czy istnieje sposób, w jaki mogę skonfigurować nginxobsługę plików znajdujących się w innym kontenerze?

ThisIsErico
źródło
3
Czy używasz dokera do izolowania nginx od aplikacji php, jednocześnie wymagając, aby nginx miał dostęp do plików w aplikacjach php?
Stefan Schmiedl
Nie jestem pewien, czy rozumiem twój komentarz ... Używam dokera do zarządzania moją infrastrukturą. Jednak nie tworzę nginxplików żądań w aplikacji php, jestem fpmdo tego proxy i muszę nginxuzyskać dostęp do statycznych plików innych niż php.
ThisIsErico
Pliki „znajdują się w innym kontenerze”, tzn. Nie tam, gdzie nginx je widzi, prawda?
Stefan Schmiedl,
Zgadza się @Stefan, są montowane tylko jako woluminy w webappkontenerze, a nie w nginxjednym.
ThisIsErico

Odpowiedzi:

1

Udało mi się rozwiązać problem, montując webappwolumin w nginxpojemniku. Tak run-nginxteraz wygląda praca:

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

A to jest webapp.confplik, który spróbuje załadować pliki statyczne z kontenera, a jeśli nie będzie to możliwe, przekaże żądanie do fpmpracownika:

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;
    }
}

Chciałbym jednak wiedzieć, czy jest na to lepszy sposób, zamiast dwa razy udostępniać ten sam wolumin. Wielkie dzięki!

ThisIsErico
źródło
4
Biorąc pod uwagę rozdzielenie nginx i php na różne pojemniki, nie sądzę. Potrzebujesz danych w dwóch różnych lokalizacjach, musisz podać je dwukrotnie. Jestem też bardzo ciekawy, jeśli ktoś wpadnie na lepszy pomysł.
Stefan Schmiedl
0

Być może można to osiągnąć za pomocą NFS

Można utworzyć jeden kontener dokerów z systemem NFS, w którym znajduje się kod, który można połączyć z kontenerami z nginx i php. Pliki byłyby przechowywane tylko w jednym kontenerze. Mogłoby to również zapewnić kolejną warstwę izolacji.

Magarusu
źródło
0

Mam dwie sugerowane opcje: Pierwsza polega na umieszczeniu zasobów statycznych w np. / Static i poinstruowaniu nginx, aby wywoływał dla nich inną usługę zaplecza. Kroki:

1) Zaktualizuj swoje witryny, aby wskazywały / static / * dla dowolnych zasobów statycznych, więc np. /Styles.css zmieni się na /static/styles.css

2) Umieść swoje aktywa w osobnym pojemniku obsługiwanym przez może inny nginx (abyś mógł ponownie użyć kontenera dla kilku witryn)

3) Edytuj plik nginx.conf, aby wysłać wszystkie żądania do / static / * do nowego kontenera:

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

Drugą opcją jest po prostu przeniesienie zasobów statycznych do CDN, więc wystarczy zaktualizować witrynę, aby załadować każdy zasób statyczny z zewnętrznego adresu URL ( https: //cdnwebsite/asdsadasda/styles.css zamiast /styles.css lub /static/styles.css)

Druga opcja ma kilka zalet w stosunku do innych, głównie w zakresie wydajności. CDN będzie obsługiwał je szybciej, a ty pracujesz także nad ograniczeniem równoczesnego ograniczenia połączenia, które przeglądarka może wprowadzić do każdej nazwy FQDN, dzięki czemu Twoja strona może ładować się szybciej, ponieważ do załadowania Twojej witryny używasz większej liczby równoczesnych połączeń.

Pedro Perez
źródło