แสดงเนื้อหาแบบคงที่โดยใช้นักเทียบท่า + nginx + php-fpm


10

ฉันพยายามกำหนดค่า php webapp โดยใช้ docker แนวคิดคือการเรียกใช้แอปที่ใช้php-fpmในคอนเทนเนอร์แบบสแตนด์อโลนและมีคอนเทนเนอร์อื่นที่จะเรียกใช้ nginx แนวคิดสำหรับการตั้งค่านี้คือการใช้คอนเทนเนอร์ nginx เดียวกันกับคำขอพร็อกซีไปยัง webapps อื่น ๆ ที่ทำงานบนเครื่องเดียวกันอยู่แล้ว ปัญหาคือฉันไม่สามารถ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 หรือไม่
Stefan Schmiedl

ฉันไม่แน่ใจว่าฉันเข้าใจความคิดเห็นของคุณ ... ฉันใช้นักเทียบท่าเพื่อจัดการโครงสร้างพื้นฐานของฉัน อย่างไรก็ตามฉันไม่ได้ทำการnginxร้องขอไฟล์ภายในแอปพลิเคชัน php ฉันกำลังfpmจะทำเช่นนั้นและฉันจำเป็นต้องnginxเข้าถึงไฟล์ที่ไม่ใช่ php คงที่
ThisIsErico

ไฟล์ "อยู่ในที่เก็บอื่น" ไม่ใช่ที่ที่ nginx สามารถเห็นได้ใช่ไหม
Stefan Schmiedl

ใช่แล้ว @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 ลงในตู้คอนเทนเนอร์ที่แตกต่างกันฉันไม่คิดอย่างนั้น คุณต้องการข้อมูลในสองสถานที่แตกต่างกันคุณต้องให้ข้อมูลสองครั้ง ฉันอยากรู้อยากเห็นมากเช่นกันถ้าใครบางคนมาพร้อมกับความคิดที่ดีกว่า
Stefan Schmiedl

0

บางทีนี่อาจทำได้โดยใช้NFS

หนึ่งนักเทียบท่าที่ใช้งาน NFS สามารถสร้างขึ้นได้โดยที่รหัสนั้นอยู่ซึ่งสามารถเชื่อมโยงไปยังภาชนะที่ใช้งาน nginx และ php ไฟล์จะถูกเก็บไว้ในที่เดียวเท่านั้น นี่อาจเป็นการแยกอีกชั้นหนึ่งเช่นกัน


0

ฉันมีสองตัวเลือกที่แนะนำ: สิ่งแรกคือการใส่สินทรัพย์แบบคงที่ของคุณเช่น / แบบคงที่และสั่งให้ 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 ดังนั้นหน้าของคุณอาจโหลดเร็วขึ้นเนื่องจากการเชื่อมต่อพร้อมกันมากขึ้นเพื่อใช้ในการโหลดเว็บไซต์ของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.