Подтвердить что ты не робот

Как правильно связать контейнеры 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 one:

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-compose up

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

4b9b3361

Ответ 1

Не печатайте ip-адрес контейнеров в конфигурации nginx, ссылка docker добавляет имя хоста связанного компьютера в файл hosts контейнера, и вы должны иметь возможность ping по имени хоста.

EDIT: Docker 1.9 Networking больше не требует связывания контейнеров, когда несколько контейнеров подключены к одной и той же сети, их файл hosts будет обновлен, чтобы они могли достигать друг друга по имени хоста.

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

см. docker linking docs (это то, что составляют использование в фоновом режиме)

но более четко объяснено в 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 порта, например 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 имя контейнера, например DB_1_NAME=/myapp_web_1/myapp_db_1

Ответ 2

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

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

Ответ 3

Как указывалось ранее, проблема заключалась в том, что файлы не были видны контейнером 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 (то есть: right HOST:PORT, который является fpm:9000, благодаря именам хостов определяемый составом, и SCRIPT_FILENAME).

Ответ 4

Новый ответ

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, и хотел бы получить информацию.

Я продолжал споткнуться на этот вопрос в Google, пытаясь найти ответ на этот вопрос, но это было не совсем то, что я искал из-за акцента Q/A на docker-compose (который на момент написания экспериментальная поддержка сетевых функций докеров). Итак, вот мой взгляд на то, что я узнал.

Недавно 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; в блоке местоположения. Thats говорит контактный контейнер php-fpm на порту 9000. Когда вы добавляете контейнеры в сеть моста Docker, все они автоматически получают обновление файла hosts, которое помещает их имя контейнера в соответствие с их IP-адресом. Поэтому, когда Nginx видит, что он будет знать, что он свяжется с контейнером PHP-FPM, вы назвали php-fpm ранее и назначены вашей сети mynetwork Docker.

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

Ответ 5

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

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

Это, по-видимому, минимальная настройка для docker 2.0 forward (потому что в докере 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

( ОБНОВЛЕНО 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;
    }
}

В коде папки:

./код/​​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

Ответ 6

Думаю, нам также нужно предоставить объем fpm контейнеру, не так ли? So = >

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

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

[ошибка] 6 # 6: * 4 FastCGI, отправленный в stderr: "Первичный script неизвестный" при чтении заголовка ответа вверх, клиент: 172.17.42.1, server: localhost, request: "GET/HTTP/1.1", upstream: "fastcgi://172.17.0.81: 9000", хост: "localhost"

Ответ 7

Для кого-то другого

Ошибка 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/*;
}