docker + nginx + php-fpm을 사용하여 정적 컨텐츠 제공


10

Docker를 사용하여 PHP 웹 응용 프로그램을 구성하려고합니다. 아이디어는 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
Docker를 사용하여 nginx를 PHP 응용 프로그램에서 격리하면서 nginx가 PHP 응용 프로그램의 파일에 액세스해야합니까?
Stefan Schmiedl 2016 년

귀하의 의견을 잘 모르겠습니다. 도커를 사용하여 인프라를 관리하고 있습니다. 그러나 nginxPHP 응용 프로그램 내에서 요청 파일을 만들지 않고 프록시를 사용하기 fpm위해 nginx정적 비 PHP 파일에 액세스 해야 합니다.
ThisIsErico 2016

파일은 "다른 컨테이너에 상주합니다", 즉 nginx가 볼 수있는 곳이 아닙니다.
Stefan Schmiedl 2016 년

@Stefan이 맞습니다. webapp컨테이너가 아닌 컨테이너에 볼륨으로 마운트됩니다 nginx.
ThisIsErico 2016

답변:


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 2016

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 ( /styles.css 대신 https : //cdnwebsite/asdsadasda/styles.css 또는 /static/styles.css)

두 번째 옵션은 주로 성능과 관련하여 다른 옵션보다 몇 가지 장점이 있습니다. CDN은 더 빨리 서비스를 제공 하고 브라우저가 각 FQDN에 대해 할 수 있는 동시 연결 제한을 해결하기 위해 사이트를로드하는 데 더 많은 동시 연결이 사용되어 페이지가 더 빨리로드 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.