Как правильно связать контейнеры php-fpm и Nginx Docker?

Я пытаюсь связать 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?

Постскриптум
Я запускаю контейнеры через docker-composer следующим образом:

docker-compose up

из корневого каталога проекта.

73

Решение

Не указывайте ip контейнеров в конфиге nginx, ссылка Docker добавляет имя хоста связанной машины в файл хоста контейнера, и вы сможете пропинговать по имени хоста.

РЕДАКТИРОВАТЬ: Docker 1.9 Сеть больше не требует, чтобы вы связывали контейнеры, когда несколько контейнеров подключены к одной сети, их файл хостов будет обновлен, чтобы они могли связываться друг с другом по имени хоста.

Каждый раз, когда докер-контейнер раскручивается из образа (даже останавливает / запускает существующий контейнер), контейнеры получают новые ip, назначенные хостом докера. Эти ip не находятся в той же подсети, что и ваши настоящие машины.

см докер, связывающий документы (это то, что 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 = ТСР: //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

28

Другие решения

Я знаю, что это старый пост, но у меня была та же проблема, и я не мог понять, почему ваш код не работает.
После МНОГО испытаний я узнал почему.

докер-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/
68

Как указывалось ранее, проблема заключалась в том, что файлы не были видны контейнером 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 публикует том, связанный с nginx а также fpm Сервисы. Тогда Dockerfile для данные сервис, который содержит ваш исходный код:

FROM busybox

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

И Dockerfile для nginx это просто заменяет конфигурацию по умолчанию:

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).

20

Новый ответ

Docker Compose обновлен. Теперь у них есть формат файла версии 2.

Файлы версии 2 поддерживаются Compose 1.6.0+ и требуют Docker Engine версии 1.10.0+.

Теперь они поддерживают сетевую функцию 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 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, который вы назвали php-fpm ранее и назначен на ваш mynetwork Докерская сеть.

Вы можете добавить эту конфигурацию Nginx либо во время процесса сборки вашего контейнера Docker, либо после этого до вас.

14

Как и в предыдущих ответах, для, но должны быть указаны очень явно: код php должен находиться в контейнере php-fpm, а статические файлы должны находиться в контейнере nginx. Для простоты большинство людей просто прикрепили весь код к обоим, как я также сделал ниже. В будущем я, скорее всего, выделю эти разные части кода в своих собственных проектах, чтобы свести к минимуму доступ к каким частям для контейнеров.

Обновил мои примеры файлов ниже с этим последним откровением (спасибо @alkaline)

Кажется, это минимальная настройка для Docker 2.0 вперед
(потому что в Docker 2.0 все стало намного проще)

докер-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

(ОБНОВЛЕНО докер-compose.yml выше: Для сайтов, которые имеют css, javascript, статические файлы и т. Д., Вам понадобятся эти файлы, доступные для контейнера nginx. В то же время все php-код доступен для контейнера 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 -d

и попробуйте URL из вашего любимого браузера

site.local.[YOUR URL].com/index.php
7

Я думаю, что мы также должны дать контейнеру fpm объем, не так ли? Итак =>

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

Если я не делаю этого, я запускаю это исключение при запуске запроса, так как fpm не может найти запрошенный файл:

[ошибка] 6 # 6: * 4 FastCGI, отправленный в stderr: «Основной сценарий неизвестен» при чтении заголовка ответа из восходящего потока, клиент: 172.17.42.1, сервер: localhost, запрос: «GET / HTTP / 1.1», восходящий поток: «fastcgi» : //172.17.0.81: 9000 «, хост:» localhost «

6

Для всех, кто получает

Ошибка 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

...
}

Убедитесь, что ваш файл nginx.conf в /etc/nginx/nginx.conf фактически загружает конфигурацию вашего сайта в http блок …

http {

...

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

# Load our websites config
include /etc/nginx/sites-enabled/*;
}
0
По вопросам рекламы [email protected]