web-dev-qa-db-ja.com

docker + nginx + php-fpmを使用して静的コンテンツを提供する

Dockerを使用してphp webappを構成しようとしています。スタンドアローンコンテナーでphp-fpmを使用してアプリを実行し、nginxを実行する別のコンテナーを用意するというアイデアです。このセットアップのアイデアは、同じnginxコンテナを使用して、同じマシンですでに動作している他のウェブアプリにリクエストをプロキシすることです。問題は、静的ファイル(js、cssなど)を適切に処理するためにnginxを取得できないことです。これらの要求は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を構成する方法はありますか?

9
ThisIsErico

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

ただし、同じボリュームを2回共有するよりも、もっと良い方法があるかどうか知りたいのですが。どうもありがとう!

1
ThisIsErico

私は2つの提案されたオプションがあります:最初のものはあなたの静的な資産を例えばに置くことです。/staticおよびnginxにそれらのために別のバックエンドサービスを呼び出すように指示します。手順:

1)静的アセットの/ static/*を指すようにWebサイトを更新します。 /styles.cssは/static/styles.cssになります

2)アセットを別のnginxなどが提供する別のコンテナーに配置します(コンテナーを複数のサイトで再利用できます)

3)nginx.confを編集して、/ static/*へのすべてのリクエストを新しいコンテナに送信します。

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

2番目のオプションは、静的アセットをCDNに移動するだけです。そのため、Webサイトを更新して、各静的アセットを外部URLからロードする必要があります( https://cdnwebsite/asdsadasda/styles.css /styles.cssまたは/static/styles.cssの代わり)

2番目のオプションには、主にパフォーマンスに関して、他のオプションよりもいくつかの利点があります。 CDNはそれらをより速く提供し、ブラウザは各FQDNに対して行うことができる 同時接続制限 にも対処しているため、より多くの同時接続がサイトのロードに使用されるため、ページのロードが速くなる可能性があります。

0
Pedro Perez

多分これは [〜#〜] nfs [〜#〜] を使用して達成できます

NFSを実行する1つのDockerコンテナーを、コードが常駐する場所に作成できます。これは、nginxおよびphpを実行するコンテナーにリンクできます。ファイルは1つのコンテナーにのみ格納されます。これにより、別の分離層も提供されます。

0
Magarusu