Как создать основанный на докере стек LAMP с помощью docker-compose в Ubuntu 18.04 Bionic Beaver Linux
Задача
Следуя этому руководству, вы сможете создать среду LAMP с использованием технологии Docker.Требования
- Root-разрешения
- Базовые знания Docker
Условные обозначения
- # - требует, чтобы данные команды linux выполнялись с правами root либо напрямую как пользователь root, либо с помощью
sudo
команды - $ - требует, чтобы данные команды linux выполнялись как обычный непривилегированный пользователь
Другие версии этого урока
Ubuntu 20.04 (Focal Fossa)Введение

containers
. Вы можете рассматривать контейнер как своего рода «пакет», изолированную среду, которая разделяет ядро с хост-машиной и содержит все, что нужно приложению. Все контейнеры создаются с использованием
images
(центральным хранилищем изображений для них является
Dockerhub ).В этом уроке мы увидим, как создать стек LAMP на основе докеризованных компонентов: следуя философии «один сервис на контейнер», мы соберем среду, используя
docker-compose
инструмент для организации составов контейнеров.Один сервис против нескольких услуг для контейнера
Существует несколько преимуществ использования одного сервиса на контейнер вместо запуска нескольких сервисов в одном. Модульность, например (мы можем повторно использовать контейнер для различных целей), или лучшая ремонтопригодность: легче сосредоточиться на конкретном фрагменте среды, а не рассматривать все сразу. Если мы хотим соблюдать эту философию, мы должны создать контейнер для каждого компонента нашего стека LAMP: один для apache-php и один для базы данных. Различные контейнеры должны быть в состоянии общаться друг с другом: чтобы легко организовать связанные контейнеры, которые мы будем использоватьdocker-compose
.Предварительные шаги
Прежде чем продолжить, нам нужно установитьdocker
и
docker-compose
на нашу систему:# apt-get install docker docker-composeПакеты будут установлены через несколько секунд, и
docker
служба будет автоматически запущена. Теперь мы можем приступить к созданию каталога для нашего проекта и внутри него, еще одного каталога для страниц, которые будут обслуживаться Apache. DocumentRoot будет значимым именем для него; в этом случае единственная страница, которая будет обслуживаться, это index.php
:$ mkdir -p dockerized-lamp/DocumentRoot
$ echo "" > dockerized-lamp/DocumentRoot/index.php
Здесь наш код состоит просто из phpinfo
функции: ее вывод (страница с информацией о php, если вы не знаете) будет тем, что наш сервер будет отображать по умолчанию. Теперь давайте используем наш любимый редактор для создания docker-compose.yml
файла для нашего проекта.Php-апаш
Теперь мы можем начать предоставлять инструкции по сборке и подключению наших контейнеров в файл docker-compose. Это файл, который используетyaml
синтаксис. Все определения должны быть предоставлены в
services
разделе.version: '3'
services:
php-apache:
image: php:7.2.1-apache
ports:
- 80:80
volumes:
- ./DocumentRoot:/var/www/html
links:
- 'mariadb'
Давайте посмотрим на то, что мы только что сделали здесь. Первая строка, которую мы вставили в файл, version
указывает, какую синтаксическую версию docker-compose мы будем использовать, в данном случае версию 3
, последнюю доступную основную версию. Внутри services
раздела мы начали описывать наш сервис, указав его имя php-apache
(произвольное имя, вы можете использовать все, что захотите), а затем инструкции по его созданию. Ключевое слово позволяет Docker знаю , что изображение , которое мы хотим использовать для создания нашего контейнера: в этом случае я использовал , который предоставит нам PHP 7.2.1 вместе с веб - сервером Apache. Нужна другая версия PHP? Вам просто нужно выбрать из множества представленных на странице изображения на
Dockerhub . Вторая инструкция, которую мы предоставили,image
7.2.1-apache
ports
: мы говорим Docker, чтобы сопоставить порт 80
на нашем хосте с портом 80
на контейнере: этот способ будет отображаться, когда мы запускаем веб-сервер непосредственно в нашей системе.Затем мы использовали
volumes
инструкцию, чтобы указать
bind mount
. Поскольку во время разработки код меняется быстро и быстро, нет смысла помещать код непосредственно в контейнер: таким образом, мы должны перестраивать его каждый раз, когда мы вносим некоторые изменения. Вместо этого мы собираемся указать docker подключить DocumentRoot
каталог к каталогу /var/www/html
внутри контейнера. Этот каталог представляет основной VirtualHost
корень документа apache
, поэтому код, который мы поместили в него, будет сразу же доступен.Наконец, мы использовали
link
ключевое слово, указывающееmariadb
в качестве аргумента. Это ключевое слово, как может показаться, не требуется для создания соединения между двумя контейнерами: даже без его указания mariadb
служба будет доступна изнутри контейнера, созданного для apache-php
службы, используя его имя в качестве имени хоста. Ключевое слово делает две вещи: сначала давайте дополнительно укажем, что
alias
мы можем использовать для ссылки на сервис в дополнение к его названию. Так, например, написав:link:
mariadb:database-service
услуга также может быть достигнута с помощью database-service
. Второе, что link
нужно сделать, это указать зависимость: в этом случае
php-apache
сервис будет считаться зависимым от
mariadb
первого, поэтому последний будет запущен раньше первого при создании или запуске среды.Установите расширения PHP
Докер-файл php-apache по умолчанию не включает некоторые расширения php, такие как mysqli или pdo. Для их установки мы должны создать собственный докер-файл, основанный на нем. Для этого мы создаем каталог внутри нашего проекта с именем php-apache (это будет нашbuild context
) и внутри него, наш dockerfile. Вставьте и сохраните приведенный ниже код как php-apache / Dockerfile:
FROM php:7.2.1-apache
MAINTAINER egidio docile
RUN docker-php-ext-install pdo pdo_mysql mysqli
Как видите, в FROM
инструкции мы указали, что этот dockerfile должен основываться на файле по умолчанию. Затем мы включили RUN
инструкцию: используя сценарий, представленный в самом изображении
docker-php-ext-install
, мы добавили расширения, необходимые для использования pdo и mysqli. На этом этапе, если мы хотим использовать наш собственный файл dockerfile, мы должны немного изменить раздел php-apache в нашем docker-compose.yml следующим образом:version: '3'
services:
php-apache:
build:
context: ./php-apache
ports:
- 80:80
volumes:
- ./DocumentRoot:/var/www/html
links:
- 'mariadb'
Что изменилось? Вместо непосредственного указания удаленного образа для использования, мы предоставили context
инструкцию внутри build
раздела, чтобы автоматически использовался файл docker, содержащийся в каталоге, который мы создали и который здесь представлен в качестве аргумента. Каталог контекста импортируется демоном docker при построении изображения, поэтому, если мы хотим добавить дополнительные файлы, мы должны также разместить их там.Служба базы данных
База данных в неотъемлемой части среды LAMP, она используется для постоянства. В этом случае мы будем использоватьmariadb
:mariadb:
image: mariadb:10.1
volumes:
- mariadb:/var/lib/mysql
environment:
TZ: "Europe/Rome"
MYSQL_ALLOW_EMPTY_PASSWORD: "no"
MYSQL_ROOT_PASSWORD: "rootpwd"
MYSQL_USER: 'testuser'
MYSQL_PASSWORD: 'testpassword'
MYSQL_DATABASE: 'testdb'
Мы уже знаем, для чего используется image
ключевое слово. То же самое касается volumes
инструкции, за исключением того факта, что на этот раз мы не объявили a bind mount
, вместо этого мы сослались на a
named volume
, для настойчивости. Важно сосредоточиться на разнице между ними на мгновение.Как было сказано ранее, a
bind mount
- это быстрый способ монтирования каталога хоста внутри контейнера, так что файлы, содержащиеся в указанном каталоге, становятся доступными из ограниченной среды: чтобы указать монтирование bind, short syntax
is::Путь к хосту может быть относительным (к файлу docker-compose) или абсолютным, а точка монтирования внутри контейнера должна быть указана в абсолютной форме.
A
named volume
- это что-то другое: это постоянное
docker volume
использование, и его обычно предпочитают монтировать связывание, потому что оно не зависит от структуры файла хоста (одно из многих преимуществ контейнеров - это их переносимость). Синтаксис для использования named volume
внутри ссылки на определение сервиса::
named volume
Жизненный цикл не зависит от контейнера , который использует его, и должны быть объявлены в volumes
разделе Докер-Compose файл, как мы увидим в данный момент.Вернуться к определению сервиса сейчас. Последнее ключевое слово, которое мы использовали
environment
: оно позволяет нам устанавливать некоторые переменные окружения, которые будут влиять на поведение сервиса. Сначала мы TZ
указывали часовой пояс нашей базы данных: в этом случае я использовал «Европа / Рим». Имена других переменных говорят все об их назначении: используя их, мы устанавливаем важные детали в качестве имени создаваемой базы данных по умолчанию (testdb), создаваемого пользователя и его пароля. Мы также установили пароль пользователя root и решили не использовать пустые пароли.Раздел томов
В этом разделе мы должны объявитьnamed volume
ссылку, mariadb
указанную в определении сервера:volumes:
mariadb:
В конце концов, вот так будет выглядеть наш файл:version: '3'
services:
php-apache:
image: php:7.2.1-apache
ports:
- 80:80
volumes:
- ./DocumentRoot:/var/www/html:z
links:
- 'mariadb'
mariadb:
image: mariadb:10.1
volumes:
- mariadb:/var/lib/mysql
environment:
TZ: "Europe/Rome"
MYSQL_ALLOW_EMPTY_PASSWORD: "no"
MYSQL_ROOT_PASSWORD: "rootpwd"
MYSQL_USER: 'testuser'
MYSQL_PASSWORD: 'testpassword'
MYSQL_DATABASE: 'testdb'
volumes:
mariadb:
Очень важно соблюдать отступ для файла, который будет интерпретирован правильно.Давайте строить нашу среду
После того, как мы определили все инструкции для наших сервисов, мы можем использоватьdocker-compose up
команду для их построения. Команда должна быть выполнена в том же каталоге, где находится docker-compose.yml
файл:# docker-compose upНесколько минут, и мы будем готовы к работе. В конце, если все прошло хорошо, перейдя к
localhost
нашему хосту, мы увидим вывод сценария php, который мы поместили внутри DocumentRoot
:
наше окружение лампы теперь готово к использованию.
Заключительные мысли
Мы увидели, как создать базовуюLAMP
среду, используя Docker и оркестрирование контейнеров и сервисов с помощью docker-compose
. Используемая нами конфигурация ориентирована на разработку и может быть дополнительно расширена и настроена для соответствия различным потребностям: документация Docker - это очень хорошо написанный источник, к которому можно обратиться, чтобы расширить свои знания по докеру. Не стесняйтесь оставлять комментарии для любых сомнений или вопросов, которые у вас есть.