web-dev-qa-db-ja.com

php-fpmとNginx Dockerコンテナを正しくリンクするにはどうすればいいですか?

私は2つの別々のコンテナをリンクしようとしています:

問題は、PHPスクリプトが機能しないことです。おそらくphp-fpmの設定が間違っています。これが私の repository にあるソースコードです。これがdocker-compose.ymlファイルです。

nginx:
    build: .
    ports:
        - "80:80"
        - "443:443"
    volumes:
        - ./:/var/www/test/
    links:
        - fpm
fpm:
    image: php:fpm
    ports:
        - "9000:9000"

nginxイメージに基づいてカスタムイメージを作成するために使用したDockerfile

FROM nginx

# Change Nginx config here...
RUN rm /etc/nginx/conf.d/default.conf
ADD ./default.conf /etc/nginx/conf.d/

最後に、これが私のカスタムNginx仮想ホスト設定です。

server {
    listen  80;

    server_name localhost;
    root /var/www/test;

    error_log /var/log/nginx/localhost.error.log;
    access_log /var/log/nginx/localhost.access.log;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+\.php(/|$) {
        fastcgi_pass 192.168.59.103:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
    }
}

Phpスクリプトを実行するためにこれらのコンテナを正しく設定する手助けができる人はいますか

P.S。docker-composerでコンテナを動かしています。

docker-compose up

プロジェクトのルートディレクトリから。

81

Nginx設定でコンテナのipをハードコードしないでください。docker linkはリンクされたマシンのホスト名をコンテナのhostsファイルに追加するので、ホスト名でpingできるはずです。

編集:Docker 1.9ネットワークでは、コンテナをリンクする必要がなくなりました。複数のコンテナが同じネットワークに接続されている場合、それらのホストファイルは更新され、ホスト名で互いにアクセスできるようになります。

Dockerコンテナがイメージからスピンアップするたびに(既存のコンテナを停止/開始する場合でも)、コンテナはdocker Hostによって割り当てられた新しいipを取得します。これらのIPは実際のマシンと同じサブネットにはありません。

Docker link docsを参照 (これは、composeがバックグラウンドで使用するものです)

ただし、リンクと公開に関するdocker-composeのドキュメントでより明確に説明されています

links

links:
 - db
 - db:database
 - redis

エイリアス名を持つエントリが、このサービスのコンテナ内の/ etc/hostsに作成されます。

172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis

公開

ホストマシンに公開せずにポートを公開してください - リンクされたサービスにアクセスできるのはのみになります。指定できるのは内部ポートだけです。

そして、あなたがプロジェクトを設定して、環境変数を通してports +他の資格情報を取得するなら、 リンクは自動的にたくさんのシステム変数を設定します

どの環境変数がサービスで利用可能かを確認するには、docker-compose run SERVICE envを実行します。

name_PORT

完全なURL、 DB_PORT = tcp://172.17.0.5:5432

name_PORT_num_protocol

完全なURL、 DB_PORT_5432_TCP=tcp://172.17.0.5:5432

name_PORT_num_protocol_ADDR

コンテナのIPアドレス、例えばDB_PORT_5432_TCP_ADDR=172.17.0.5

name_PORT_num_protocol_PORT

公開されているポート番号、例えばDB_PORT_5432_TCP_PORT=5432

name_PORT_num_protocol_PROTO

プロトコル(tcpまたはudp)、 DB_PORT_5432_TCP_PROTO=tcp

name_NAME

完全修飾コンテナー名、例えばDB_1_NAME=/myapp_web_1/myapp_db_1

29
Vincent De Smet

私はそれが一種の古い投稿であることを知っています、しかし私は同じ問題を抱えていて、そしてなぜあなたのコードがうまくいかなかったか理解することができませんでした。たくさんのテストの後、私はその理由を見つけました。

docker-compose.yml

nginx:
    build: .
    ports:
        - "80:80"
    links:
        - fpm
fpm:
    image: php:fpm
    ports:
        - ":9000"

    # seems like fpm receives the full path from nginx
    # and tries to find the files in this dock, so it must
    # be the same as nginx.root
    volumes:
        - ./:/complex/path/to/files/

/etc/nginx/conf.d/default.conf

server {
    listen  80;

    # this path MUST be exactly as docker-compose.fpm.volumes,
    # even if it doesn't exist in this dock.
    root /complex/path/to/files;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+\.php(/|$) {
        fastcgi_pass fpm:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Dockerfile

FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/
74
Rafael Quintela

前に指摘したように、問題はファイルがfpmコンテナから見えないことでした。ただし、コンテナ間でデータを共有するには、推奨パターンはdata-only containerを使用しています( この記事 で説明)。

簡単に言えば、データを保持するコンテナーを作成し、それをボリュームと共有し、アプリのこのボリュームをvolumes_fromとリンクします。

Compose(私のマシンでは1.6.2)を使用すると、docker-compose.ymlファイルは次のようになります。

version: "2"
services:
  nginx:
    build:
      context: .
      dockerfile: nginx/Dockerfile
    ports:
      - "80:80"
    links:
      - fpm
    volumes_from:
      - data
  fpm:
    image: php:fpm
    volumes_from:
      - data
  data:
    build:
      context: .
      dockerfile: data/Dockerfile
    volumes:
      - /var/www/html

dataは、nginxおよびfpmサービスにリンクされたボリュームを公開します。次に、ソースコードを含むdataサービスのDockerfileを指定します。

FROM busybox

# content
ADD path/to/source /var/www/html

そして、デフォルトの設定を置き換えるnginxのDockerfile

FROM nginx

# config
ADD config/default.conf /etc/nginx/conf.d

完了のために、この例が機能するために必要な構成ファイルを以下に示します。

server {
    listen 0.0.0.0:80;

    root /var/www/html;

    location / {
        index index.php index.html;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass fpm:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    }
}

これは、ドキュメントボリュームとして共有ボリュームを使用するようにnginxに指示し、nginxがfpmコンテナと通信できるように適切な構成を設定します(つまり:Host:PORT、つまりfpm:9000はcomposeによって定義されたホスト名、およびSCRIPT_FILENAME)。

22
iKanor

新しい答え

Docker Composeが更新されました。彼らは今 バージョン2ファイルフォーマット を持っています。

バージョン2ファイルはCompose 1.6.0以降でサポートされており、バージョン1.10.0以降のDockerエンジンが必要です。

実行時にmyapp_defaultというデフォルトネットワークを設定するDockerのネットワーク機能をサポートするようになりました。

彼らのドキュメント からあなたのファイルは以下のようになります。

version: '2'

services:
  web:
    build: .
    ports:
      - "8000:8000"
  fpm:
    image: phpfpm
  nginx
    image: nginx

これらのコンテナは自動的にデフォルトのmyapp_defaultネットワークに追加されるので、お互いに通信できます。あなたはそれからNginx configにあるでしょう:

fastcgi_pass fpm:9000;

@treefaceがコメントで述べたように、PHP-FPMがポート9000をリッスンしていることを忘れないでください。これは/etc/php5/fpm/pool.d/www.confを必要とするところでlisten = 9000を編集することによって行うことができます。

古い答え

古いバージョンのDocker/Docker composeを使用している人のために、以下をここに保管しておき、情報を希望します。

この質問に対する答えを見つけようとしたとき、私はグーグルでこの質問に悩まされ続けましたが、これは私が探していたものではありませんでした。 dockerネットワーキング機能)。それで、ここで私が学んだことを理解します。

Dockerは最近 ネットワーク機能 を支持して そのリンクを廃止予定 機能を採用しました

したがって、Docker Networks機能を使用すると、以下の手順に従ってコンテナーをリンクできます。オプションに関する詳細な説明については、以前にリンクされたドキュメントを参照してください。

最初にあなたのネットワークを作成する

docker network create --driver bridge mynetwork

次にPHP-FPMコンテナを実行して、ポート9000を確実に開き、新しいネットワーク(mynetwork)に割り当てます。

docker run -d -p 9000 --net mynetwork --name php-fpm php:fpm

ここで重要なのは、コマンドの最後にある--name php-fpmという名前です。これは後で必要になります。

次にNginxコンテナを実行して、作成したネットワークに再度割り当てます。

docker run --net mynetwork --name nginx -d -p 80:80 nginx:latest

PHPおよびNginxコンテナの場合は、必要に応じて--volumes-fromコマンドなどを追加することもできます。

今Nginxの設定が来ます。これは次のようになります。

server {
    listen 80;
    server_name localhost;

    root /path/to/my/webroot;

    index index.html index.htm index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000; 
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

ロケーションブロックのfastcgi_pass php-fpm:9000;に注目してください。ポートphp-fpmのコンテナ9000に連絡してください。 Dockerブリッジネットワークにコンテナを追加すると、それらはすべて自動的にhostsファイルの更新を取得します。これにより、コンテナのIPアドレスに対するコンテナ名が更新されます。 Nginxがあなたがphp-fpmという名前を付けてあなたのmynetwork Dockerネットワークに割り当てたPHP-FPMコンテナに連絡することを知っていることに気づいたとき。

あなたはあなたのDockerコンテナのビルドプロセスの間に、あるいはその後あなたにそれのどちらかでそのNginx設定を追加することができます。

14
DavidT

以前の答えは解決しましたが、非常に明確に述べる必要があります。phpコードはphp-fpmコンテナに存在する必要がありますが、静的ファイルはnginxコンテナに存在する必要があります。簡単にするために、私も以下で行ったように、ほとんどの人は両方のコードにすべてのコードを添付しただけです。将来的には、どのコンテナがどの部分にアクセスできるかを最小限に抑えるために、私は自分のプロジェクトでこれらのコードのさまざまな部分を切り離すことになるでしょう。

以下の私のサンプルファイルをこの最新の啓示で更新しました(ありがとう@アルカリ)

これはdocker 2.0以降のための最小セットアップであるように思われます(docker 2.0では物事がずっと楽になったため)

docker-compose.yml:

version: '2'
services:
  php:
    container_name: test-php
    image: php:fpm
    volumes:
      - ./code:/var/www/html/site
  nginx:
    container_name: test-nginx
    image: nginx:latest
    volumes:
      - ./code:/var/www/html/site
      - ./site.conf:/etc/nginx/conf.d/site.conf:ro
    ports:
      - 80:80

上記のdocker-compose.ymlを更新:css、javascript、静的ファイルなどがあるサイトでは、nginxコンテナがこれらのファイルにアクセスできる必要があります。 fpmコンテナ繰り返しますが、私の基本コードはcss、js、およびphpが混乱しているため、この例ではすべてのコードを両方のコンテナに添付しています。

同じフォルダ内:

site.conf:

server
{
    listen   80;
    server_name site.local.[YOUR URL].com;

    root /var/www/html/site;
    index index.php;

    location /
    {
        try_files $uri =404;
    }

    location ~ \.php$ {
        fastcgi_pass   test-php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

フォルダコード内:

./code/index.php:

<?php
phpinfo();

そして、あなたのhostsファイルを更新することを忘れないでください:

127.0.0.1 site.local.[YOUR URL].com

そしてdocker-compose upを実行してください

$docker-compose up -d

お気に入りのブラウザからURLを試す

site.local.[YOUR URL].com/index.php
8
Phillip

私たちはfpmコンテナにボリュームを与える必要があると思います、私たちはいけませんか?だから=>

fpm:
    image: php:fpm
    volumes:
        - ./:/var/www/test/

Fpmが要求されたファイルを見つけることができないので、私がこれをしないならば、私は要求を発するとき私はこの例外に出くわす:

[エラー] 6#6:* 4 FastCGIがstderrで送信しました:アップストリームからのレスポンスヘッダの読み取り中に "primary script unknown"、クライアント:172.17.42.1、サーバー:localhost、要求: "GET/HTTP/1.1"、アップストリーム: "fastcgi ://172.17.0.81:90​​00 "、ホスト:" localhost "

6
leberknecht

他の誰にとっても

Nginx 403エラー:[フォルダ]のディレクトリインデックスは禁止されています

index.phpを完璧に動作させ、index.htmlのサイト設定のサーバーブロック内のインデックスにindex.phpを含めて、sites-enabledを使用する場合

server {
    listen 80;

    # this path MUST be exactly as docker-compose php volumes
    root /usr/share/nginx/html;

    index index.php

    ...
}

/etc/nginx/nginx.confにあるnginx.confファイルが実際にあなたのサイト設定をhttpブロックにロードしていることを確認してください...

http {

    ...

    include /etc/nginx/conf.d/*.conf;

    # Load our websites config 
    include /etc/nginx/sites-enabled/*;
}
0
myol