web-dev-qa-db-ja.com

nginxリバースプロキシからphp-fpmへ

Nginx構成で概念的に問題が発生しています。 nginx SSLターミネーターリバースプロキシから始めて、それぞれが仮想サービスを提供するいくつかのコンテナーでdocker-compose.ymlセットアップを使用します。これらのサービスは、単一のホスト名でサブディレクトリとして提供されます。

net --443--> nginx
             | | `--- ContainerA "https://example.com/serviceA/"
             | `----- ContainerB "https://example.com/serviceB/"
             `------- ContainerC "https://example.com/serviceC/"

プロセスリストの抜粋:

nginx:~$ ps fax
127285 ?        Ss     0:00  nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf -g daemon off;
127419 ?        S      0:00   \_ nginx: worker process
127420 ?        S      0:00   \_ nginx: worker process
127421 ?        S      0:00   \_ nginx: worker process

ContainerA:~$ ps fax
127132 ?        Ss     0:09  php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
234053 ?        S      8:27   \_ php-fpm: pool www
236952 ?        S      8:12   \_ php-fpm: pool www
259123 ?        S      6:42   \_ php-fpm: pool www

nginxの単一インスタンスを実行し、各コンテナーでphp-fpmを使用すると、効率が向上すると思いました。

thinkphp-fpmの前提は、コンテナーが独自のnginxプロセスを必要としないようなものだと思います。 nginxプロセスは、ポート9000を介して各コンテナと通信します(ネットワーク部分は機能します)。しかし実際には、私は問題を抱えているので、私の前提が正しいことを確認する必要があります。

基本的なnginxおよびphp-fpmアーキテクチャのこの仮定は正しいですか?または、適切なnginx/php-fpmインフラストラクチャは、直接協調してphp-fpmを使用することを目的としています(同じホストとファイルシステム) )またはマルチホスティング/マルチファイルシステムは合理的かつ効率的ですか?

(私は最近、いくつかの助けを借りるために連絡を取りました、そして彼らの最初の応答は「あなたは各コンテナでnginxを実行する必要があります」でした、それはphp-fpmの私の理解には意味がありませんでした。)

(ここには、この明らかに高レベルのアーキテクチャについてではなく、特定のnginx.conf質問をする質問がたくさんあります。)

2
r2evans

これは弱い答えですが、私は信じています:

はい、これは一般的に正しい哲学ですが、いくつかの注意点があります。 php-fpm.phpファイルを処理するためにありますが、すべての(php以外の)ファイルを提供するためではないと思います。そのため、正面向きのnginxプロセスは、実際のPHP処理を行わない場合でも、すべてのファイルを表示する必要があります。

Dockerを使用してこれをスマートに行うには、php-fpmコンテナー内のファイルをnginxコンテナーと明示的に共有する必要があります。 Dockerでこれを行うための推奨される方法は、名前付きボリュームを提供し、それを両方のコンテナーに使用することです。たとえば、docker-compose.ymlファイル:

version: '2'
services:
  serviceA:
    image: ... # something served with php-fpm
    volumes:
    - tmpvolA:/path/to/serviceA
  serviceB:
    image: ... # something served with php-fpm
    volumes:
    - tmpvolB:/path/to/serviceB
  nginx:
    image: ...
    volumes:
    - tmpvolA:/var/www/serviceA
    - tmpvolB:/var/www/serviceB
volumes:
  tmpvolA:
  tmpvolB:

(多くのフィールドは含まれていません...)最後にリストされている2つのボリュームは、dockerが話す「名前付きボリューム」であり、理由により空です。これらは、スクリプトの開始時に空になることを目的としており、コンテナの1つで満たされます。 (実際には、いくつかの要因に応じて、両方で満たされる場合と、どちらも満たされない場合があります。)

これの1つの副作用は、ボリュームが持続することです。

  • 不必要に再現されないという点で、効率的に「これは良い」です。
  • 仮想化サービスを使用する利点の1つは、サービスを再起動してクリーンな状態を保証できることであるため、「これは悪いことです」。永続的な名前付きボリュームでは、前のインスタンスで使用されたファイルが下位のfsレイヤーの厳格なバージョンの代わりに使用されるため、(自動的に)クリーンな状態になりません。

この「悪い」を回避する方法は、ボリュームを手動でフラッシュすることです。これは、シャットダウン時にdocker-compose down -vを使用して実行できます。

    -v, --volumes       Remove named volumes declared in the `volumes` section
                        of the Compose file and anonymous volumes
                        attached to containers.

docker volume rm <volume-id>またはdocker volume Pruneを使用して手動で実行することもできます(一時的または名前付きなど、現在使用されていないすべてのボリュームを削除します)。

0
r2evans