Докер: докеры Nginx и php5-fpm не разговаривают

Я хотел бы сделать полностью докерированную установку Drupal. Мой первый шаг - запустить контейнеры с Nginx и php5-fpm, основанными на Debian. Я использую альфа-канал CoreOS (использую Digital Ocean).

Мои Dockerfiles следующие:

Nginx:

FROM debian
MAINTAINER fvhemert
RUN apt-get update && apt-get install -y nginx && echo "\ndaemon off;" >> /etc/nginx/nginx.conf
CMD ["nginx"]
EXPOSE 80

Этот контейнер построен и отлично работает. Я вижу страницу Nginx по умолчанию на моем IP-адресе сервера.

Php5-fpm:

FROM debian
MAINTAINER fvhemert
RUN apt-get update && apt-get install -y \
            php5-fpm \
            && sed 's/;daemonize = yes/daemonize = no/' -i /etc/php5/fpm/php-fpm.conf
CMD ["php5-fpm"]
EXPOSE 9000

Этот контейнер также собирается без проблем и продолжает работать при запуске.

Сначала я запускаю контейнер php5-fpm с:

docker run -d --name php5-fpm freek/php5-fpm:1

Затем я запускаю Nginx, связанный с php5-fpm:

docker run -d -p 80:80 --link php5-fpm:phpserver --name nginx freek/nginx-php:1

Связь вроде работает, в / etc / hosts есть запись с именем phpserver. Оба докера запускают:

core@dockertest ~ $ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
fd1a9ae0f1dd        freek/nginx-php:4   "nginx"             38 minutes ago      Up 38 minutes       0.0.0.0:80->80/tcp   nginx
3bd12b3761b9        freek/php5-fpm:2    "php5-fpm"          38 minutes ago      Up 38 minutes       9000/tcp             php5-fpm

Я скорректировал некоторые файлы конфигурации. Для контейнера Nginx я отредактировал / etc / nginx / sites-enabled / default и изменил:

server {
        #listen   80; ## listen for ipv4; this line is default and implied
        #listen   [::]:80 default_server ipv6only=on; ## listen for ipv6

        root /usr/share/nginx/www;
        index index.html index.htm index.php;

(Я добавил index.php)

И далее:

location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
        #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        #
        #       # With php5-cgi alone:
                fastcgi_pass phpserver:9000;
        #       # With php5-fpm:
        #       fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }

В докере php5-fpm я изменил /etc/php5/fpm/php.ini:

cgi.fix_pathinfo=0

php5-fpm запускает:

[21-Nov-2014 06:15:29] NOTICE: fpm is running, pid 1
[21-Nov-2014 06:15:29] NOTICE: ready to handle connections

Я также изменил index.html на index.php, это выглядит так (/usr/share/nginx/www/index.php):

<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!</h1></center>

<?php
phpinfo();
?>

</body>
</html>

Я просканировал порт 9000 из докера Nginx, он кажется закрытым. Конечно, плохой знак:

root@fd1a9ae0f1dd:/# nmap -p 9000 phpserver

Starting Nmap 6.00 ( http://nmap.org ) at 2014-11-21 06:49 UTC
Nmap scan report for phpserver (172.17.0.94)
Host is up (0.00022s latency).
PORT     STATE  SERVICE
9000/tcp closed cslistener
MAC Address: 02:42:AC:11:00:5E (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds

Журналы Nginx:

root@fd1a9ae0f1dd:/# vim /var/log/nginx/error.log
2014/11/20 14:43:46 [error] 13#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 194.171.252.110, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "128.199.60.95"
2014/11/21 06:15:51 [error] 9#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 145.15.244.119, server: localhost, request: "GET / HTTP/1.0", upstream: "fastcgi://172.17.0.94:9000", host: "128.199.60.95"

Да, все идет не так, и я продолжаю получать ошибку 502 неверного шлюза при просмотре моего экземпляра Nginx.

Мой вопрос: что именно идет не так? Я предполагаю, что мне не хватает какой-то настройки в файлах конфигурации php.

ИЗМЕНИТЬ ДЛЯ БОЛЕЕ ПОДРОБНОЙ ИНФОРМАЦИИ: Это результат (изнутри контейнера php5-fpm, после apt-get install net-tools):

root @ 3bd12b3761b9: / # netstat -tapen
Активные интернет-соединения
(серверы и установленные) Proto Recv-Q Send-Q Локальный адрес
Состояние внешнего адреса Inode пользователя PID / Имя программы

Изнутри контейнера Nginx:

root @ fd1a9ae0f1dd: / # netstat -tapen
Активные интернет-соединения
(серверы и установлены) Proto Recv-Q Send-Q Локальный адрес Внешний адрес Состояние Inode пользователя PID / Имя программы tcp 0 0 0.0.0.0:80 0.0 .0.0: *
СЛУШАТЬ 0 1875387 -

EDIT2: Прогресс!

В контейнере php5-fpm в файле:

/etc/php5/fpm/pool.d/www.conf

Я изменил аргумент прослушивания с некоторого имени сокета на:

listen = 9000

Теперь, когда я перехожу на свою веб-страницу, я получаю сообщение об ошибке: «Не указан входной файл».

Наверное, у меня где-то пропадал / не прав. Я разберусь с этим повнимательнее!

РЕДАКТИРОВАТЬ3:

Итак, я восстановил докеры с вышеупомянутыми изменениями, и кажется, что они говорят. Однако моя веб-страница сообщает мне: «файл не найден». Я уверен, что это связано с документом, который nginx отправляет на php-fpm, но я понятия не имею, как он должен выглядеть. Я использовал значения по умолчанию при использовании метода сокета, который всегда работал. Теперь это больше не работает. Что должно быть в / etc / nginx / sites-enabled / default по адресу ~ .php $ {?


person Freek    schedule 21.11.2014    source источник
comment
У вас сработало с разделением объемного контейнера?   -  person bdart    schedule 07.10.2015


Ответы (3)


Причина, по которой это не работает, заключается в том, что, как вы сами обнаружили, nginx отправляет в PHP-FPM только путь к файлу PHP, а не сам файл (что было бы довольно неэффективно). Решение состоит в том, чтобы использовать третий контейнер VOLUME, предназначенный только для данных, для размещения файлов, а затем смонтировать его на обоих экземплярах докеров.

FROM debian
VOLUME /var/www
CMD ['true']

Создайте указанный выше Dockerfile и создайте экземпляр (назовите его, например, storage-www), затем запустите контейнеры nginx и PHP-FPM с опцией:

--volumes-from storage-www

Это сработает, если вы запустите оба контейнера на одном физическом сервере. Но вы все равно можете использовать разные серверы, если поместите этот контейнер только для данных в сетевую файловую систему, такую ​​как GlusterFS, которая довольно эффективна и может быть распределена по крупномасштабной сети.

Надеюсь, это поможет.

Обновление:

По состоянию на 2015 год лучшим способом создания постоянных связей между контейнерами является использование docker-compose.

person niieani    schedule 09.02.2015
comment
контейнер nginx сообщает мне, что доступ /var/www запрещен, нужно ли мне что-то предоставлять? - person bdart; 08.10.2015
comment
@bdart вам необходимо сопоставить / var / www с другим каталогом на хосте докеров при создании контейнера storage-www - person niieani; 08.10.2015
comment
Я это сделал. Я понял, что мой nginx.conf использует / var / www в собственном контейнере вместо / var / www, который связан через том. Может моя root /var/www; проблема? - person bdart; 08.10.2015
comment
Кажется, теперь он работает, по крайней мере, с html. Но для .hh вместо .php он возвращает 404 connect() failed (111: Connection refused) из журнала - person bdart; 08.10.2015

Итак, я протестировал все настройки, и ни один из них не работал между докерами, хотя они работали с одинаковыми настройками на 1 сервере (или, возможно, также в одном докере). Затем я узнал, что php-fpm не берет файлы php из nginx, он получает путь, если он не может найти тот же файл в своем собственном контейнере, он генерирует «файл не найден». Дополнительную информацию см. Здесь: https://code.google.com/p/sna/wiki/NginxWithPHPFPM К сожалению, это решает вопрос, но не проблему. Это довольно раздражает людей, которые хотят выполнить балансировку нагрузки с несколькими серверами php-fpm, им придется выполнить rsync все или что-то в этом роде. Надеюсь, что когда-нибудь найду лучшее решение. Спасибо за ответы.

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

person Freek    schedule 22.11.2014
comment
Добавление еще одного контейнера в стек подтолкнуло это решение до уровня слишком сложного для того, что я хочу, и я только начал использовать полные серверы (капли цифрового океана). Я хотел запустить множество серверов Drupal, и я обнаружил, что Drush также удовлетворяет все мои потребности в автоматической настройке. - person Freek; 12.10.2015

Когда вы находитесь в своем контейнере как

root @ fd1a9ae0f1dd: / #, проверьте порты, используемые с

netstat -tapen | grep ": 9000"

or

netstat -lntpu | grep ": 9000"

или те же команды без grep

person user2915097    schedule 21.11.2014
comment
Это результат (из контейнера php5-fpm, после того, как apt-get isntall net-tools): (Извините, почему это так плохо отформатировано и как я могу это изменить?) root@3bd12b3761b9:/# netstat -tapen Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp 0 0 172.17.0.94:58181 46.4.205.44:80 TIME_WAIT 0 0 - tcp 0 0 172.17.0.94:44741 140.112.8.139:80 TIME_WAIT 0 0 - - person Freek; 21.11.2014
comment
Это похоже на контейнер с командой EXPOSE 80, а не на контейнер с EXPOSE 9000. Можете ли вы проверить порты, используемые в обоих контейнерах? - person user2915097; 21.11.2014
comment
Подробности смотрите в исходном посте, спасибо! - person Freek; 21.11.2014
comment
Таким образом, у контейнера php5-fm нет активного сетевого подключения. Ясно, что что-то пошло не так при запуске ваших вещей. Находясь внутри этого контейнера, попробуйте запустить php5-fpm Я думаю, вы получите сообщение об ошибке. - person user2915097; 21.11.2014
comment
Странно, там вроде ничего нет? Есть ли настройка PHP, которая должна заставить его слушать там, а не через сокет, как я думаю по умолчанию? - person Freek; 21.11.2014
comment
Действительно: root @ 3bd12b3761b9: / # php5-fpm [21 ноября 2014 г., 09:05:30] ОШИБКА: другой экземпляр FPM, похоже, уже прослушивает /var/run/php5-fpm.sock [21 ноября 2014 г. 09:05:30] ОШИБКА: сбой инициализации FPM root @ 3bd12b3761b9: / # Он прослушивает через сокет .. как это изменить ... - person Freek; 21.11.2014
comment
См. Основной вопрос внизу, прогресс есть, я нашел настройку для перехода с сокета на прослушивание порта. - person Freek; 21.11.2014
comment
говорить докер во множественном числе не совсем правильно. у вас есть докеры, а не докеры. Дело не в штанах :) - person programmerq; 30.01.2017