121

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

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

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

そしてDockerfile、nginxのものに基づいてカスタムイメージを構築するために使用しました:

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スクリプトを実行するためにこれらのコンテナを正しく設定するのを手伝ってくれる人はいますか?

PS 私は次のようにdocker-composerを介してコンテナを実行します:

docker-compose up

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

4

7 に答える 7

116

古い投稿であることは承知していますが、同じ問題があり、コードが機能しない理由を理解できませんでした。多くのテストの後、私はその理由を見つけました。

fpm は nginx からフル パスを受け取り、fpm コンテナー内のファイルを見つけようとするように見えるためserver.root、nginx コンテナーに存在しない場合でも、nginx 構成とまったく同じである必要があります。

デモンストレーションするには:

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/
于 2015-10-07T18:35:21.857 に答える
38

nginx 構成でコンテナーの IP をハードコーディングしないでください。docker リンクは、リンクされたマシンのホスト名をコンテナーのホスト ファイルに追加し、ホスト名で ping できるはずです。

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

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

docker linking ドキュメントを参照してください(これは、compose がバックグラウンドで使用するものです)

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

リンク

links:
 - db
 - db:database
 - redis

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

172.17.2.186  db
172.17.2.186  database
172.17.2.187  redis

公開

ポートをホスト マシンに公開せずに公開します。リンクされたサービスにのみアクセスできます。内部ポートのみ指定できます。

また、環境変数を介してポートとその他の資格情報を取得するようにプロジェクトを設定すると、リンクによって一連のシステム変数が自動的に設定されます

サービスで使用できる環境変数を確認するには、 を実行します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

于 2015-04-29T06:44:08.010 に答える
26

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

簡単に言えば、データを保持するだけのコンテナーを作成し、それをボリュームと共有し、アプリでこのボリュームを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にリンクされているボリュームを発行することに注意してください。次に、ソース コードを含むデータ サービスの:nginxfpmDockerfile

FROM busybox

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

そしてDockerfilenginxの場合、デフォルトの設定を置き換えるだけです:

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 コンテナーと通信できるように適切な構成を設定します (つまり、compose によって定義されたホスト名と のおかげでHOST:PORTあるright )。fpm:9000SCRIPT_FILENAME

于 2016-03-23T20:14:19.037 に答える
17

新しい答え

Docker Compose が更新されました。バージョン 2 のファイル形式になりました。

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

Docker のネットワーク機能をサポートするようになりました。これは、実行時にmyapp_defaultと呼ばれるデフォルトのネットワークをセットアップします。

ドキュメントから、ファイルは次のようになります。

version: '2'

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

これらのコンテナはデフォルトのmyapp_defaultネットワークに自動的に追加されるため、互いに通信できるようになります。次に、Nginx構成に次のようにします。

fastcgi_pass fpm:9000;

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

古い回答

古いバージョンの Docker/Docker Compose を使用していて、情報が必要な方のために、以下をここに残しておきます。

この質問への回答を見つけようとしているときに、Google でこの質問に出くわし続けましたが、Q/A が 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 ブリッジ ネットワークに追加すると、すべてのコンテナーがホスト ファイルの更新を自動的に取得し、IP アドレスに対してコンテナー名が挿入されます。そのため、Nginx は、前に名前を付けてDocker ネットワークphp-fpmに割り当てた PHP-FPM コンテナーに接続することを認識します。mynetwork

Dockerコンテナのビルドプロセス中またはその後のいずれかで、そのNginx構成を追加できます。

于 2015-11-11T15:11:12.290 に答える
1

他の誰かが得るために

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

index.phpwhileを使用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

    ...
}

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

http {

    ...

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

    # Load our websites config 
    include /etc/nginx/sites-enabled/*;
}
于 2018-09-25T01:32:48.273 に答える