Контейнеризация Apache, MySQL и PHP с помощью Docker

Я искал в Интернете и читал руководства, и я просто не могу понять, что не так с моей установкой Docker.

Цель

К контейнерам-азимуты Apache, PHP и MySQL позволяют настраивать их для каждого проекта. Единственная зависимость для развертывания стека должна быть докерером. Все другие зависимости/действия должны быть способны быть построены/запущены через Dockerfile.

Доказательство концепции

Из моего docker-compose.yml Apache + MySQL + PHP через файл docker-compose.yml - я бы хотел настроить таргетинг на страницу index.php чтобы успешно выполнить Hello Docker! наряду со списком всех доступных баз данных.

Проблема

Когда я посещаю docker.dev/index.php в своем браузере, а не работает PHP-код, я могу только просмотреть исходный код PHP. Вот что я вижу:

<!--?php
/** * This file: * Has not been tested * Does not use prepared statements * Is for Proof of Concept only! */
$host = '127.0.0.1';
$user = 'root';
$pass = 'docker';
$conn = new mysqli($host, $user, $pass);
$sql = 'show databases';
$results = $conn--->query($sql);
?>
<h2>Hello Docker!</h2>
<ul> <!--?php while ($row = $results--->fetch_assoc()) : ?> <!--?php endwhile ?-->
</ul>

Мое понимание (которое может быть ошибочно) заключается в том, что Apache правильно обрабатывает виртуальный хост, но не знает, как загрузить файл PHP через Apache PHP Module.

Я настроил Apache на depends_on PHP, и я связал их через network (вместе с MySQL), но, очевидно, я что-то пропустил, иначе все будет работать так, как я хочу).

Я создал репо на github, которое должно позволить вам проверить мою установку несколькими простыми командами:

git clone https://github.com/dambrogia/docker-testing.git
cd docker-testing
docker-compose up -d

Вам также придется отредактировать add docker.dev до 127.0.0.1 в вашем файле hosts на вашем хост-компьютере!

Как я могу визуализировать PHP, а не читать его источник, когда я посещаю docker.dev/index.php?

Я не хочу использовать комбинированное изображение PHP и Apache, если это вообще возможно. Я хотел бы иметь три отдельных контейнера - PHP, Apache, MySQL.

3 ответа

Я решил этот вопрос и создал репо для всех, кому интересно более подробное объяснение или доказательство концепции.

См. Мой репо: https://github.com/dambrogia/docker-testing

TL; DR

Подход, который я использовал для этого, заключался в проксировании всех запросов apache в любые .php файлы на PHP-FPM через fcgi://php:9000. Порт 9000 по умолчанию

Вы можете увидеть это Apache настройки в действии здесь.

Параметр /var/www/html/$1 определяет, где файлы отображаются в контейнере PHP.


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

Вам необходимо обеспечить общий общий том как для контейнеров Nginx, так и для PHP. В этом томе у вас будет ваш index.php. Вот грубый пример docker-compose.yml:

services: php7: image: "php:7.1.10-fpm" container_name: "prefix-php" volumes: - "./your/local/dir:/var/www/html" nginx: image: "nginx:1.13.6" container_name: "prefix-nginx" ports: - "80:80" - "443:443" links: - "php7" volumes: - "./your/local/dir:/var/www/html"

Затем вы выполните следующую команду в каталоге, где docker-compose.yml файл docker-compose.yml:

$ docker-compose -p prefix

Причиной "префикса" является то, что вы создаете группировку проектов для своих контейнеров, чтобы не столкнуться с другими именами контейнеров.

Естественно, вам понадобится конфигурация сайта nginx, которая указывает на /var/www/html. У вас не будет никаких требований к конфигурации для контейнера php-fpm.

Замечание относительно конфигурации nginx. Вышеупомянутый файл docker-compose.yml является неполным без ссылки на php-контейнер в конфигурации nginx. Это будет выглядеть так (грубо говоря):

server { listen 80 default_server; # ...more config, like root, index, server_name, etc location ~* \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass prefix-php:9000; # Note the container name here. fastcgi_index index.php; fastcgi_hide_header X-Powered-By; fastcgi_read_timeout 300s; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location / { try_files $uri $uri/ /index.php?$query_string; } # ...more rules
}

Вы заметите, что я назвал контейнер "php7", вы могли бы добавить еще один контейнер "php5" в этот docker-compose.yml а затем это позволит вам определить сайты nginx, которые используют разные версии PHP, все запущенные на одном и том же докере, составить настройку.

Я понимаю, что это не отвечает на ваш вопрос напрямую, так как он не решает проблему с помощью apache, но это альтернатива для рассмотрения.

Надеюсь, это по крайней мере дает вам идеи, помогающие решить вашу установку.


Вы столкнулись с мемом о том, что "контейнеры должны делать одно", что хорошо, но это не значит, что вы должны разбить его так далеко. Контейнер LAMP совершенно нормален в Docker-land, и я не знаю, какие усилия были предприняты для разделения Apache и PHP - я подозреваю, что это трата инженерных усилий.

Как вы говорите, вы хотите иметь возможность запускать разные версии PHP. Это абсолютно нормально, и вы должны настроить это в своем Dockerfile. Если вы намерены построить набор контейнеров, которые могут наследовать ваши сервисы, тогда вы можете просто создать базовый контейнер Apache, на котором вы добавите PHP в наследование Dockerfile.

Я запускаю набор микросервисов, которые используют комбинацию 5.6 и 7.0. Все они наследуются из очень простой alpine (разной версии: 3.5, 3.6 и последней, что станет 3.7). Это займет около 15 минут, чтобы скопировать и вставить мои требования к Dockerfile сверху, плюс немного настройки контейнера, которые я, вероятно, сделаю в любом случае. Итак, если ваша цель - готовый к запуску набор контейнеров, я не уверен, сколько времени вы будете экономить на практике.

Все сказанное, если вы действительно хотите это сделать, вы можете изучить механизм, который использует Пивик. Я не знаком с этим, но контейнер PHP обслуживает FastCGI, и его необходимо проксировать через веб-сервер в другом контейнере.

licensed under cc by-sa 3.0 with attribution.