Подавайте статичний вміст за допомогою docker + nginx + php-fpm


10

Я намагаюся налаштувати php webapp за допомогою docker. Ідея полягає у тому, щоб запустити додаток за php-fpmдопомогою окремого контейнера та мати інший контейнер, який запускатиме nginx. Ідея цієї установки полягає в тому, щоб використовувати той самий контейнер nginx для проксі-запитів інших веб-сайтів, які вже працюють на тій же машині. Проблема полягає в тому, що я не можу отримати nginxналежну обробку статичних файлів (js, css тощо), як і запити до них fpm.

Ось як виглядає файлова система:

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

Я запускаю цілу річ, використовуючи такий, Makefileякий виглядає приблизно так (не зацікавлений у 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

Ось так config/webapp.confвиглядає мій .

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

Будь-яка дія, яку потрібно обробити за допомогою цього index.phpфайлу, буде працювати. Однак статичні файли не подаватимуться, що призводить до неприємних 404помилок (оскільки у php webapp насправді не налаштовані маршрути для них). Я вважаю, що nginx намагається завантажити ті з власної файлової системи контейнерів, коли вони фактично знаходяться в webappконтейнері, не виходячи з ладу @webapp.

Чи є спосіб, який я можу налаштувати nginxна обслуговування тих файлів, які знаходяться в іншому контейнері?


3
Чи використовуєте ви докер для ізоляції nginx від програм php, вимагаючи, щоб nginx мав доступ до файлів у програмах php?
Стефан Шмідль

Я не впевнений, що я розумію ваш коментар ... Я використовую докер для управління моєю інфраструктурою. Однак я не створюю nginxфайли запитів у програмі php, я готую fpmце зробити, і мені потрібно nginxотримати доступ до статичних файлів, які не є php.
ThisIsErico

Файли "перебувають в іншому контейнері", тобто не там, де nginx може їх бачити, правда?
Штефан Шмідль

Це правильно @Stefan, вони встановлюються лише як об'єми в webappконтейнері, а не в nginxодному.
ThisIsErico

Відповіді:


1

Мені вдалося вирішити проблему, встановивши webappгучність у nginxконтейнері. Ось як run-nginxвиглядає робота зараз:

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

І це webapp.confфайл, який спробує завантажити статичні файли з контейнера, і, якщо це неможливо, проксі-сервер запитує fpmпрацівника:

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

Однак я хотів би знати, чи є кращий спосіб зробити це замість того, щоб ділитися одним і тим же томом двічі. Дуже дякую!


4
Зважаючи на ваше розділення nginx та php на різні контейнери, я не думаю. Дані вам потрібні у двох різних місцях, їх потрібно надати двічі. Я теж дуже цікавий, якщо хтось придумає кращу ідею.
Штефан Шмідль

0

Можливо, цього вдасться досягти за допомогою NFS

Один контейнер докера, що працює з NFS, може бути зроблений там, де знаходиться код, який може бути пов'язаний з контейнерами, що працюють nginx і php. Файли зберігатимуться лише в одному контейнері. Це може забезпечити ще один шар ізоляції.


0

У мене є два запропоновані варіанти: Перший - помістити свої статичні активи в напр. / Static та доручити nginx викликати іншу сервісну службу для них. Кроки:

1) Оновіть свої веб-сайти так, щоб вони вказували на / static / * для будь-яких статичних активів, наприклад, /styles.css стає /static/styles.css

2) Покладіть свої активи або в окремий контейнер, який обслуговується, можливо, іншим nginx (щоб ви могли повторно використовувати контейнер для кількох сайтів)

3) Редагуйте nginx.conf, щоб надіслати всі запити до / static / * до нового контейнера:

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

Другий варіант - просто перемістити статичні активи на CDN, тому вам просто потрібно оновити веб-сайт, щоб завантажити кожен статичний актив із зовнішньої URL-адреси ( https: //cdnwebsite/asdsadasda/styles.css замість /styles.css або /static/styles.css)

Другий варіант має ряд переваг перед іншими, в основному навколо продуктивності. CDN слугуватиме тим швидше, і ви також працюєте над обмеженням одночасного підключення, який браузер може зробити для кожного FQDN, тому ваша сторінка може завантажуватися швидше за рахунок більше одночасних з'єднань, які використовуються для завантаження вашого сайту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.