Phục vụ nội dung tĩnh bằng docker + nginx + php-fpm


10

Tôi đang cố gắng cấu hình một ứng dụng web php bằng docker. Ý tưởng là để chạy ứng dụng bằng cách sử dụng php-fpmtrong một container độc lập và có một container khác sẽ chạy nginx. Ý tưởng cho thiết lập này là sử dụng cùng một thùng chứa nginx cho các yêu cầu proxy đến các ứng dụng web khác đang hoạt động trên cùng một máy. Vấn đề là tôi không thể nginxxử lý đúng các tệp tĩnh (js, css, v.v.), như các yêu cầu cho những người tiếp tục fpm.

Đây là những gì hệ thống tập tin trông giống như:

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

Tôi đang chạy toàn bộ bằng cách sử dụng một Makefilecái trông như thế này (không quan tâm đến docker-composecái này):

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

Đây là những gì tôi config/webapp.conftrông giống như.

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

Bất cứ hành động nào cần được xử lý bằng index.phptệp đó sẽ hoạt động. Tuy nhiên, các tệp tĩnh sẽ không được cung cấp, dẫn đến các 404lỗi khó chịu (vì ứng dụng web php không thực sự có các tuyến được định cấu hình cho các tệp đó). Tôi tin rằng nginx cố tải những thứ đó từ hệ thống tập tin chứa của chính nó, khi chúng thực sự nằm trong webappcontainer, không quay trở lại @webapp.

Có cách nào tôi có thể định cấu hình nginxđể phục vụ các tệp nằm trong vùng chứa khác không?


3
Bạn có đang sử dụng docker để tách nginx khỏi các ứng dụng php trong khi yêu cầu nginx có quyền truy cập vào các tệp trong ứng dụng php không?
Stefan Schmiedl

Tôi không chắc là tôi hiểu nhận xét của bạn ... Tôi đang sử dụng docker để quản lý cơ sở hạ tầng của mình. Tuy nhiên, tôi không tạo nginxcác tệp yêu cầu trong ứng dụng php, tôi ủy quyền fpmđể làm như vậy và tôi cần nginxphải truy cập các tệp không phải là php tĩnh.
ThisIsErico

Các tập tin "nằm trong một container khác", tức là không phải nơi nginx có thể nhìn thấy chúng, phải không?
Stefan Schmiedl

Đúng vậy @Stefan, chúng chỉ được gắn dưới dạng khối lượng trong webappcontainer chứ không phải trong nginxmột khối.
ThisIsErico

Câu trả lời:


1

Tôi quản lý để giải quyết vấn đề bằng cách gắn webappâm lượng trong nginxcontainer. Đây là những gì run-nginxcông việc hiện tại:

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

Và đây là webapp.conftệp, sẽ cố tải các tệp tĩnh từ vùng chứa và, nếu không thể, sẽ ủy quyền yêu cầu cho fpmnhân viên:

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

Tuy nhiên, tôi muốn biết liệu có cách nào tốt hơn để làm như vậy thay vì chia sẻ cùng một âm lượng hai lần. Cảm ơn rất nhiều!


4
Do sự phân tách nginx và php của bạn vào các thùng chứa khác nhau, tôi không nghĩ vậy. Bạn cần dữ liệu ở hai địa điểm khác nhau, bạn phải cung cấp hai lần. Tôi cũng rất tò mò, nếu ai đó nghĩ ra một ý tưởng tốt hơn.
Stefan Schmiedl

0

Có lẽ điều này có thể đạt được bằng cách sử dụng NFS

Một container docker chạy NFS có thể được tạo ở nơi mã nằm, có thể được liên kết với các container chạy nginx và php. Các tập tin sẽ chỉ được lưu trữ trong một container. Điều này có thể cung cấp một lớp cô lập khác là tốt.


0

Tôi có hai tùy chọn được đề xuất: Cách đầu tiên là đặt tài sản tĩnh của bạn vào ví dụ / static và hướng dẫn nginx gọi một dịch vụ phụ trợ khác cho những dịch vụ này. Các bước:

1) Cập nhật trang web của bạn để trỏ đến / static / * cho bất kỳ tài sản tĩnh nào, ví dụ: /styles.css trở thành /static/styles.css

2) Đặt tài sản của bạn vào một thùng chứa riêng được phục vụ bởi một nginx khác (để bạn có thể sử dụng lại container cho một số trang web)

3) Chỉnh sửa nginx.conf để gửi tất cả các yêu cầu tới / static / * đến vùng chứa mới:

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

Tùy chọn thứ hai là chỉ cần di chuyển tài sản tĩnh của bạn sang CDN, vì vậy bạn chỉ cần cập nhật trang web của mình để tải từng tài sản tĩnh từ một URL bên ngoài ( https: //cdnwebsite/asdsadasda/styles.css thay vì /ststyle.css hoặc /static/styles.css)

Tùy chọn thứ hai có một số lợi thế so với các tùy chọn khác, chủ yếu xoay quanh hiệu suất. CDN sẽ phục vụ những người đó nhanh hơn và bạn cũng đang làm việc xung quanh giới hạn kết nối đồng thời mà trình duyệt có thể thực hiện cho mỗi FQDN, do đó trang của bạn có thể tải nhanh hơn do sử dụng nhiều kết nối đồng thời hơn để tải trang web của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.