LAMP сервер для разработки (без PHP на хосте)
Содержание
В этой статье я расскажу как можно быстро поднять связку PHP + MySql используя Docker на компьютере без установки чего-либо на хост (docker, конечно, уже должен быть установлен)
Требования
- легкость в использовании
- возможность запуска нескольких сайтов
- легкость развертывания нового сайта
- общий сервер базы данных для всех сайтов
- запуск одной строкой
- доступ к исходному коду сайта
- возможность использования разных версий PHP
В результате потребуется запустить общие для всех сайтов сервисы (это можно поставить в автозапуск)
А затем каждый сайт запускать отдельно. Это для того, что бы не запускать каждый раз все имеющиеся проекты, а развернуть только необходимые
Все исходные файлы доступны на GitHub
Общие сервисы
Все общие сервисы будут лежать в отдельной директории и запускаться одним docker-compose файлом
Используемые docker сети
Создадим две сети с драйвером bridge, этот драйвер означает, что сеть будет доступна извне. В нашем случае, к ним будут подключаться сайты.
|
|
Контейнер разрабатываемого сайта должен иметь открытый 80 порт и уметь отдавать HTML страницы. Так же он должен быть добавлен в сеть proxy что бы nginx-proxy мог получить доступ к контейнеру к которому проксирует трафик.
В сеть lamp добавляем бекендовые контейнеры, в данном случае это только MySql. Однако если потребуется еще какие-либо сервисы, например Rabbit-MQ, Redis или Centrifugo то их легко добавить аналогично MySql.
Так же в сеть lamp добавляем контейнеры, которым требуется доступ к бекендовым сервисам. В данном случае это PhpMyAdmin
Proxy
Важной частью сервиса является Nginx Proxy
Он позволяет легко проксировать запросы с одного порта (в нашем случае 80) на другие контейнеры. Притом контейнеры он выбирает на основании
переменной окружения VIRTUAL_HOST
в контейнере назначения. Выполняет он это автоматические т.к. он подключается к хостовому докеру через
проброшенный сокет файл.
Так же добавим доступ к сети proxy, внутри которой он и будет проксировать.
|
|
MySql
Используем готовый образ MySql, можно выбрать необходимую версию.
Я буду использовать последнюю версию
|
|
В этой конфигурации я указал рутовый пароль базы данных используя переменную окружения MYSQL_ROOT_PASSWORD
и папку, где будут храниться сами данные.
Контейнер подключим к сети lamp т.к. это бекендовый сервис.
PhpMyAdmin
Так же используем готовый образ PhpMyAdmin
|
|
В переменной окружения VIRTUAL_HOST
указываем домен, по которому будет доступен PhpMyAdmin. Это требуется что бы nginx-proxy
перенаправил запрос к этому домену к этому контейнеру
Контейнер подключим и к сети proxy т.к. к этому контейнеру потребуется доступ из браузера и к сети lamp т.к. ему потребуется доступ к базе данных.
Базовый контейнер PHP
Во многих случаях базовый контейнер PHP может не подойти, например потому что в нем отсутствует некоторый необходимый модуль. Для этого стоит создать свой базовый образ для PHP контейнера.
Все необходимые файлы для образа поместим в папку php, в ней же создадим файл Dockerfile
с инструкциями по сборке, например такими:
|
|
Так же я создал bash скрипт для сборки образа с нужным тегом:
|
|
Это дает возможность не вспоминать необходимое имя тега а просто выполнить скрипт с говорящим названием
И сразу же соберем базовый образ выполнив этот скрипт
./build.sh
Запуск общих сервисов
Осталось настроить сети
Настройка docker-compose.yml
завершена общих сервисов завершена, можно их запускать:
docker-compose up
Эта команда может занять некоторое время пока скачивает и собирает образы и вскоре на экране отобразится отчет о создании сетей и запуске контейнеров
|
|
А так же вывод работы контейнеров, который будет выглядеть примерно так:
|
|
Посмотрим список запущенных контейнеров командой docker ps
в другом терминале
|
|
В списке должны быть все три контейнера, конечно же CONTAINER ID
у них будет другой.
Если хотя бы одного контейнера не хватает, потребуется искать в выводе команды docker-compose up
ошибки, возникшие в этом контейнере.
После исправления ошибки нужно остановить и заново запустить сбоку docker-compose up
После успешного запуска можно будет запускать эти контейнеры командой docker-compose start
которая запустит контейнеры и завершится, освободив терминал.
Остановить контейнеры можно будет командой docker-compose stop
в этой же директории.
Развертывание проекта
К этому моменту все общие контейнеры запущены и пора переходить к развертыванию проекта.
Все проекты развертываются одинаково, пример имеется в репозитории в директории example
и всего лишь выполняет подключение к базе данных.
У каждого сайта будет следующая структура директорий:
- nginx настройки nginx (как ни странно)
- php настройки php (внезапно)
- html файлы самого сайта. Именно в этой директории будет находиться корневой index.php
Снова сети
В docker-compose.yml
сайта будем использовать три сети:
frontend
сеть синоним сети proxy. Именно к включенным к этой сети контейнерам сможет проксировать nginx-proxy- в
lamp
сети находятся общие сервисы, в данном случае база данных backend
это внутренняя сеть этого сайта, используется что бы другие сайты не могли получить доступ к этому сайту, не засоряли пространство друг друга.
Nginx
Так же используем официальный образ Nginx, указываем хост в переменной окружения VIRTUAL_HOST
,
подключаем конфиг и директорию с файлами.
Так же добавляем этот контейнер к сети, в которой работает nginx-proxy и бекенд этого сайта
|
|
Согласно такой конфигурации, конфиг сайта должен находится в директории nginx
и называться default.nginx
Пункт depends_on
указывает что контейнер надо запустить после запуска указанных контейнеров. Если этого не сделать,
то при старте nginx может сразу завершить работу т.к. контейнер с php мог еще не запуститься (что случается практически всегда).
PHP
Наконец-таки занимаемся самим php
Подключим локальный php.ini
из директории php
и файлы проекта.
|
|
Автозапуск через systemd
Создаем файл сервиса:
sudo touch /etc/systemd/system/lamp.service
И выставляем ему права доступа:
sudo chmod 664 /etc/systemd/system/lamp.service
И поместим в него все необходимые настройки
sudo vim /etc/systemd/system/lamp.service
|
|
В файле сервиса указаны
- Description - название сервиса
- Type=single - systemd запустит процесс и будет считать что пока он жив, сервис запущен. Для остановки сервиса он отправит процессу сигнал завершения
- ExecStart - команда для запуска docker-compose. Используется команда
up
потому как в этом случае процесс не будет завершаться пока выполяются контейнеры - WorkingDirectory - устанавливаем директорию, где хранятся файлы общих сервисов, в моем случае это /srv/lamp. Именно в этой директории храниться
docker-compose.yml
общих сервисов
После этого требуется обновить конфигурацию systemd:
sudo systemctl deamon-reload
И уже можно запускать сервис:
sudo systemctl start lamp
То, что сервис запустился, можно проверить, посмотрев список запущеных docker-контейнеров:
docker ps
Результат этой команды будет примерно таким:
|
|
По завершению работы LAMP сервис можно остановить:
sudo systemctl stop lamp
Также можно настроить автозапуск сервиса:
sudo systemctl enable lamp
Итоги
Таким образом легко можно поднять сервер разработки
Если сайт требует особого сервера или версии базы данных, их можно подключить в docker-compose файле этой сайта - это докер, комбинировать можно почти как угодно!
Все исходные файлы доступны на GitHub
Автор Arswarog
Обновлено 17 июля 2020