Я пытаюсь связать 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
из корневого каталога проекта.
Не указывайте 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
Я знаю, что это старый пост, но у меня была та же проблема, и я не мог понять, почему ваш код не работает.
После МНОГО испытаний я узнал почему.
докер-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. Однако для обмена данными между контейнерами используется рекомендуемый шаблон. контейнеры только для данных (как объяснено в Эта статья).
Короче говоря: создайте контейнер, который просто хранит ваши данные, поделитесь им с томом и свяжите этот том в своих приложениях с 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
).
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, либо после этого до вас.
Как и в предыдущих ответах, для, но должны быть указаны очень явно: код 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
Я думаю, что мы также должны дать контейнеру 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 «
Для всех, кто получает
Ошибка 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/*;
}