私は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
プロジェクトのルートディレクトリから。
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
私はそれが一種の古い投稿であることを知っています、しかし私は同じ問題を抱えていて、そしてなぜあなたのコードがうまくいかなかったか理解することができませんでした。たくさんのテストの後、私はその理由を見つけました。
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/
前に指摘したように、問題はファイルが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
)。
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設定を追加することができます。
以前の答えは解決しましたが、非常に明確に述べる必要があります。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
私たちは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:9000 "、ホスト:" localhost "
他の誰にとっても
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/*;
}