Настраиваем Laravel в контейнере Docker
Сегодня я расскажу вам, как сделать своё первое приложение Laravel в контейнере Docker.
Необходимые условия
Шаг 1. Установка Laravel
Создаём приложение Laravel при помощи команды composer create-project
Переходим в каталог проекта
Прописываем разрешение на запись для папки storage, и папки cache внутри папки bootstrap.
Затем используем образ Docker composer, чтобы смонтировать каталоги, нужные для Laravel, и чтобы избежать глобальной установки Composer.
Шаг 2. Создание файла Docker Compose
Для веб-сервера я использовал порты 8080 и 844, так как у меня уже есть на компьютере установленный Apache. И я использовал порт 33061 для MySQL — уже есть установленный сервер MySQL.
Шаг 3. Сохранение данных
Я использовал тома и монтирование для хранения базы данных, файлов приложения и конфигурации.
В переменной db файла docker-compose.yml задан том под именем dbdata для хранения базы данных MySQL.
Том dbdata хранит содержимое папки var/lib/mysql внутри контейнера. Это позволяет остановливать и перезапускать службу db без потери данных.
В конце файла compose добавлено определение тома dbdata:
Добавим монтирование файлов конфигурации MySQL в службу db.
Добавим монтирование к сервису webserver. Их будет два: один для кода вашего приложения, а другой для конфигурации Nginx.
И, наконец, добавим монтирование к службе app для файлов конфигурации и кода приложения:
Служба app монтирует папку laradock, содержащую код приложения в папку /var/www в контейнере.
В итоге docker-compose.yml должен выглядеть так:
Шаг 4. Создание Dockerfile
Устанавливает базовый образ и задает необходимые команды и инструкции.
Шаг 5. Настройка PHP
Для настройки PHP создается файл local.ini.
Я добавил следующие настройки в этот файл.
Это файл, который я подмонтировал к /usr/local/etc/php/conf.d/local.ini внутри контейнера в шаге 2.
Шаг 6. Настройка NGINX
Для настройки Nginx я создал файл app.conf в папке nginx/conf.d
Шаг 7. Настройка MySQL
Для настройки MySQL был создан файл my.cnf внутри папки mysql.
Добавляем следующий код в my.cnf для того, чтобы включить логи и указать их местоположение.
Шаг 8 — Запуск контейнеров
Я определил все сервисы в файле docker-compose и создал файлы конфигурации для этих сервисов. Теперь я запускаю контейнеры командой:
Она загружает все необходимые образы Docker. После этого я просматриваю все запущенные контейнеры и их состояние, используя команду:
Шаг 9. Создание пользователя MySQL
Чтобы создать нового пользователя, запустите оболочку bash для контейнера db:
Затем создаю пользователя и даю ему все привилегии.
Сбрасываю привилегии для применения изменений.
Шаг 10. Обновление настроек окружения
Отредактируем настройки Laravel.
Обновим учетные данные базы данных и URL приложения.
Шаг 11. Перенос базы данных
Теперь у нас есть доступ к нашему приложению Laravel по адресу http://0.0.0.0:8080/
Автор: Sreejith Ezhakkad
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.
Задать вопросы по урокам можно на нашем форуме.
Установка Laravel, Nginx и MySQL с помощью Docker Compose
В последнее время Docker часто используется для развертывания приложений, поскольку он упрощает этот процесс с помощью виртуальных контейнеров. Например, если вы используете стек LEMP (который состоит из PHP, Nginx и MySQL) и Laravel, Docker может значительно ускорить процедуру настройки приложения.
Docker Compose упрощает разработку, поскольку дает разработчикам возможность определять инфраструктуру, – включая сервисы приложений, сети и тома, – в едином файле. Docker Compose легко заменяет собой сразу несколько команд, в том числе docker container create и docker container run.
В этом мануале вы научитесь создавать приложение в фреймворке Laravel, используя Nginx как веб-сервер и MySQL как БД. Все это будет помещено в контейнеры Docker. Вы напишете полную конфигурацию приложения в файле docker-compose вместе с конфигурационными файлами для PHP, MySQL и Nginx.
Требования
1: Загрузка Laravel и установка зависимостей
Для начала нужно загрузить последнюю версию Laravel и установить зависимости программы, в том числе и Composer, менеджер пакетов PHP уровня приложения. Используйте Docker, чтобы не устанавливать Composer глобально.
Перейдите в домашний каталог и клонируйте последнюю версию Laravel в laravel-app:
git clone https://github.com/laravel/laravel.git laravel-app
Затем перейдите в каталог laravel-app:
Теперь через образ composer смонтируйте каталоги проекта Laravel, чтобы избежать накладок глобальной установки Composer:
/laravel-app скопируется в контейнер, а содержимое папки vendor, которую Composer создает внутри контейнера, будет скопировано в текущий каталог.
Теперь отредактируйте привилегии каталога, все права на него нужно передать вашему пользователю sudo:
Это пригодится вам позже, когда вы будете работать с Dockerfile для образа приложения, поскольку так вы сможете работать с кодом и запускать процессы в контейнере через своего пользователя sudo.
2: Создание конфигурационного файла Docker Compose
Сборка приложений с помощью Docker Compose упрощает настройку и контроль версий в инфраструктуре. Чтобы настроить приложение Laravel, давайте создадим файл docker-compose и определим в нем сервисы веб-сервера, базы данных и приложения.
В файле docker-compose нужно определить три сервиса: app, webserver и db. Вставьте в файл такой код (только укажите свой сложный пароль root в MYSQL_ROOT_PASSWORD, переменной среды сервиса db):
В файл входят следующие сервисы:
Свойство container_name определяет имя контейнера, которое должно совпадать с именем сервиса. Если вы не определите это свойство, Docker будет присваивать контейнерам случайные имена (по умолчанию он выбирает имя исторической личности и случайное слово, разделяя их символом подчеркивания).
Для простоты взаимодействия между контейнерами сервисы подключаются к соединительной сети app-network. Соединительная сеть использует программный мост, который позволяет подключенным к этой сети контейнерам взаимодействовать друг с другом. Драйвер устанавливает правила хоста автоматически, чтобы контейнеры из разных соединительных сетей не могли взаимодействовать напрямую. Это повышает безопасность приложений, поскольку взаимодействовать в таких условиях смогут только связанные сервисы. Кроме того, так вы сможете указать разные сети и сервисы, подключающиеся к функциям: например, клиентские сервисы приложениймогут использовать сеть frontend, а серверные — сеть backend.
3: Постоянное хранение данных
Docker предоставляет удобные средства для постоянного хранения данных. Для этого в данном тестовом приложении мы будем использовать тома и монтируемые образы. Мы будем хранить файлы базы данных, приложения и конфигурации. Тома очень гибкие в резервном копировании, их легко сохранять по истечении жизненного цикла контейнера, а монтируемые образы упрощают редактирование кода во время разработки и немедленно отражают изменения файлов или каталогов хоста в контейнерах. Мы используем оба варианта.
Важно! Монтируемые образы позволяют менять файловую систему хоста через работающие в контейнерах процессы, в том числе создавать, изменять и удалять важные системные файлы и каталоги. Это может повлиять на процессы в системе хоста, не связанные с Docker. Монтируемые образы следует использовать очень осторожно.
Для постоянного сохранения базы данных MySQL определите том dbdata в файле docker-compose, в определении сервиса db:
.
#MySQL Service
db:
.
volumes:
— dbdata:/var/lib/mysql
networks:
— app-network
.
Том dbdata используется для постоянного сохранения содержимого /var/lib/mysql в контейнере. Это позволяет останавливать и перезапускать сервис db, не теряя данных.
Вставьте в конец файла определение тома dbdata:
.
#Volumes
volumes:
dbdata:
driver: local
Теперь можно использовать этот том для разных сервисов.
Затем добавьте к сервису db привязку монтируемого образа для конфигурационных файлов MySQL, которые мы создадим позже.
/laravel-app/mysql/my.cnf к каталогу /etc/mysql/my.cnf в контейнере.
А теперь добавьте монтируемые образы в сервис webserver. Образов будет два: один для кода приложения, а второй — для определения настроек Nginx.
Первый образ привязывает код приложения из каталога
/laravel-app к каталогу /var/www внутри контейнера. Конфигурационный файл, добавляемый в
/laravel-app/nginx/conf.d/, также монтируется в папку /etc/nginx/conf.d/ в контейнере, что позволяет менять содержимое каталога по мере необходимости.
Теперь добавьте следующие привязки образов в сервис app для кода приложения и конфигурационных файлов:
Сервис app привязывает монтируемый образ каталога
/laravel-app, который содержит код приложения, к /var/www. Это позволяет ускорить разработку, поскольку все изменения в локальном каталоге приложения сразу же отразятся в контейнере. Также конфигурационный файл PHP
/laravel-app/php/local.ini привязывается к файлу /usr/local/etc/php/conf.d/local.ini в контейнере. Мы создадим локальный конфигурационный файл PHP в разделе 5.
Теперь файл docker-compose имеет такой вид:
Сохраните и закройте файл.
Теперь пора создать пользовательский образ вашего приложения.
4: Создание Dockerfile
Docker позволяет настраивать среду внутри отдельных контейнеров с помощью файла Dockerfile. Файл Dockerfile создает пользовательские образы, которые затем можно использовать для установки зависимостей приложения и изменения настроек. Вы можете загружать созданные образы в Docker Hub или в частный реестр.
Файл Dockerfile должен находиться в каталоге
/laravel-app. Создайте этот файл:
Этот Dockerfile будет определять базовый образ и необходимые команды для сборки образа приложения Laravel. Добавьте в файл такие строки:
Сначала Dockerfile создает образ на основе образа php:7.2-fpm. Это образ Debian с предустановленным экземпляром PHP FastCGI PHP-FPM. Также этот файл устанавливает необходимые пакеты для Laravel: mcrypt, pdo_mysql, mbstring, imagick и composer.
Директива RUN определяет команды для обновления, установки и настройки параметров внутри контейнера, включая выделенного пользователя и группу www. Директива WORKDIR указывает рабочий каталог приложения (в данном случае это каталог /var/www ).
Используя отдельного пользователя и группу с ограниченными правами доступа, вы снижаете уязвимости при запуске контейнеров Docker (по умолчанию они запускаются с правами root). Чтобы не запускать контейнер с привилегиями root, мы создали пользователя www с правами на чтение и запись для каталога /var/www.
Это делается с помощью команды COPY и флага –chown для копирования прав каталога приложения.
Команда EXPOSE открывает в контейнере порт 9000 для сервера php-fpm. CMD определяет команду, которая будет запускаться после создания контейнера. Здесь CMD содержит команду php-fpm, которая запускает сервер.
Сохраните и закройте файл.
Теперь пора определить конфигурации PHP.
5: Настройка PHP
Итак, мы определили инфраструктуру в файле docker-compose. Теперь можно настроить сервис PHP в качестве процессора для входящих запросов Nginx.
Для настройки PHP нужно создать файл local.ini в каталоге php. Это файл, который в разделе 2 мы привязали к файлу /usr/local/etc/php/conf.d/local.ini в контейнере. Имея этот файл, вы сможете игнорировать файл по умолчанию php.ini, который PHP считывает при запуске.
Создайте каталог php:
Затем откройте файл local.ini:
Чтобы продемонстрировать настройку PHP, мы добавим следующий код для установки ограничений размера выгруженных файлов:
Директивы upload_max_filesize и post_max_size задают максимальный допустимый размер выгружаемых файлов и показывают, как задавать конфигурации php.ini из local.ini. Все параметры конфигурации PHP, которые вы хотите игнорировать, можно поместить в файл local.ini.
Сохраните и закройте файл.
Теперь пора настроить веб-сервер.
6: Настройка Nginx
Теперь можно настроить Nginx на поддержку PHP-FPM в качестве сервера FastCGI для обслуживания динамического контента. Сервер FastCGI разработан на основе двоичного протокола для взаимодействия интерактивных программ с веб-сервером.
Для Nginx нужно создать в папке
/laravel-app/nginx/conf.d/ файл app.conf с конфигурацией сервисов.
Создайте каталог nginx/conf.d/:
Затем создайте файл app.conf:
Добавьте в файл такой код, чтобы определить конфигурацию Nginx:
server <
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location
Блок server задает конфигурацию веб-сервера Nginx с помощью директив:
В блоке location для php директива fastcgi_pass указывает, что сервис app прослушивает сокет TCP по порту 9000. Благодаря этому сервер PHP-FPM прослушивает запросы через сеть, а не через сокет Unix. Сокет Unix имеет небольшое преимущество в скорости по сравнению с сокетом TCP, однако у него нет сетевого протокола и он пропускает сетевой стек. Если хосты находятся в одной системе, использование сокета Unix может иметь смысл, но если сервисы работают на разных хостах, сокет TCP гораздо лучше, поскольку позволяет подключаться к распределенным сервисам. Поскольку контейнеры app и webserver работают на разных хостах, в данной конфигурации сокет TCP будет эффективнее.
Сохраните и закройте файл.
Благодаря привязке, созданной в разделе 2, все изменения в каталоге nginx/conf.d/ прямо отразятся в контейнере webserver.
7: Настройка MySQL
Настроив PHP и Nginx, вы можете включить MySQL как базу данных для приложения.
Для MySQL нужно создать файл my.cnf в каталоге mysql. Этот файл мы привязали к файлу /etc/mysql/my.cnf внутри контейнера в разделе 2. Привязка монтируемого образа позволяет игнорировать все параметры my.cnf, когда это потребуется.
Чтобы посмотреть, как это работает, давайте добавим в файл my.cnf параметры, которые включают лог общих запросов и задают лог-файл.
Создайте каталог mysql:
Создайте файл my.cnf:
Поместите в файл следующий код, чтобы включить лог запросов и задать расположение лога:
[mysqld]
general_log = 1
general_log_file = /var/lib/mysql/general.log
Файл my.cnf включает лог, задавая параметру general_log значение 1. Параметр general_log_file указывает, где будут храниться логи.
Сохраните файл и закройте его.
Все готово, пора запускать контейнеры.
8: Запуск контейнеров и изменение настроек среды
После запуска контейнеров мы вставим в этот файл параметры.
Теперь все сервисы определены в файле docker-compose, и вам нужно просто запустить одну команду, которая запустит все контейнеры, создаст тома и настройки и подключит сети:
После завершения этого процесса используйте следующую команду, чтобы запросить список всех запущенных контейнеров:
Вы увидите следующий вывод с данными о контейнерах app, webserver и db:
CONTAINER ID NAMES IMAGE STATUS PORTS
c31b7b3251e0 db mysql:5.7.22 Up 2 seconds 0.0.0.0:3306->3306/tcp
ed5a69704580 app digitalocean.com/php Up 2 seconds 9000/tcp
5ce4ee31d7c0 webserver nginx:alpine Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
В этом выводе CONTAINER ID — это уникальный идентификатор контейнера, а NAMES перечисляет имена сервисов. Вы можете использовать оба эти идентификатора для доступа к контейнерам. IMAGE определяет имя образа каждого контейнера, а STATUS предоставляет данные о состоянии.
Откройте файл с помощью docker-compose exec, что позволяет запускать определенные команды в контейнерах. В данном случае команда откроет файл для редактирования:
Найдите блок DB_CONNECTION и определите в нем особенности настройки вашей системы. Нужно изменить следующие поля:
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laraveluser
DB_PASSWORD=your_laravel_db_password
Сохраните и закройте файл.
docker-compose exec app php artisan key:generate
Теперь для запуска приложения у вас есть все необходимые настройки среды. Чтобы кэшировать эти настройки для ускорения загрузки приложения, запустите команду:
docker-compose exec app php artisan config:cache
Конфигурации будут загружены в /var/www/bootstrap/cache/config.php в контейнере.
Теперь откройте в браузере сайт http://your_server_ip. На экране появится главная страница приложения Laravel.
Теперь можно перейти к настройке данных пользователя БД laravel в контейнере db.
9: Создание пользователя MySQL
Установка MySQL по умолчанию предоставляет только учетную запись root с неограниченными привилегиями доступа к серверу СУБД. Обычно при работе с базой данных лучше не использовать администратора, root. Вместо этого лучше создать специального пользователя для базы данных нашего приложения.
Чтобы создать его, запустите интерактивную оболочку bash в контейнере db с помощью команды docker-compose exec:
docker-compose exec db bash
Внутри контейнера войдите в MySQL как root:
Вам будет предложено ввести root пароль MySQL, заданный в файле docker-compose.
Для начала проверьте наличие базы данных laravel, которую вы определили в файле docker-compose. Запустите show databases для проверки существующих баз данных:
В выводе вы должны увидеть БД laravel:
GRANT ALL ON laravel.* TO ‘laraveluser’@’%’ IDENTIFIED BY ‘your_laravel_db_password’;
Сбросьте привилегии, чтобы сообщить серверу MySQL об изменениях:
Выйдите из контейнера:
10: Миграция данных и знакомство с консолью Tinker
Теперь приложение запущено, вы можете выполнить миграцию данных и поэкспериментировать с командой tinker, которая запускает консоль PsySH с загруженным приложением Laravel. PsySH — это консоль среды выполнения и интерактивный отладчик PHP, а Tinker — это REPL для Laravel. Команда tinker позволяет взаимодействовать с приложением Laravel из командной строки в интерактивной оболочке.
Сначала протестируйте соединение с MySQL с помощью команды Laravel artisan migrate, которая создаст в БД таблицу migrations внутри контейнера:
docker-compose exec app php artisan migrate
Эта команда выполняет миграцию таблиц Laravel. В случае успешной миграции вы увидите такой вывод:
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
После завершения миграции вы можете отправить запрос для проверки подключения к БД:
docker-compose exec app php artisan tinker
Проверьте соединение MySQL:
Вы получите такой результат:
=> Illuminate\Support\Collection <#2856
all: [
<#2862
+»id»: 1,
+»migration»: «2014_10_12_000000_create_users_table»,
+»batch»: 1,
>,
<#2865
+»id»: 2,
+»migration»: «2014_10_12_100000_create_password_resets_table»,
+»batch»: 1,
>,
],
>
Вы можете использовать tinker для взаимодействия с базами данных и для экспериментов с сервисами и моделями.
Теперь приложение Laravel работает, а вы готовы к дальнейшей разработке и экспериментам.
Заключение
Теперь на вашем сервере есть рабочее приложение на основе стека LEMP.
Docker Compose упрощает установку, так как позволяет с помощью одной команды создавать группы контейнеров Docker, определенные в одном файле.
Разворачиваем связку Nginx+Php-Fpm+MySQL с magento2 на борту и раскладываем по контейнерам в Docker
Все чаще стучась в различные компании разработчиков в качестве DevOps инженера, я получаю приблизительно одни и те же тестовые задания. Они отличаются друг от друга версиями PHP или проектами которые надо запустить.
Но в целом они упираются в одну связку это Nginx\Appache, SQL (тут вариаций много, все зависит от предпочтений заказчика), PHP и желательно чтобы это было разложено по контейнерам.
Поэтому я решил рассказать на примере, как все это поднять без особых усилий.
Возможно кому-то это поможет понять, на простом примере, что к чему. Описывать что такое Docker я не буду, т.к. статей на эту тему вагон и маленькая тележка.
В данной статье, мы подготовим небольшую структуру:
Все зависит от системы в которой вы хотите работать, в отношении кроссплатформенности, docker приятно удивляет (один и тот же файл конфигурации позволяет собрать и запустить контейнеры на любой системе *nix, Win, iOS).
Для Linux (к примеру в CentOS)
Включаем и стартуем сервис:
Чтобы наша структура создавалась одной командой нам потребуется docker-compose.
Для начала поставим необходимые для него компоненты:
Дальше устанавливаем docker-compose и обновляем python:
(или # pip install docker-compose)
Для Win систем (многие считают это извращением)
Но если вы решили, настоятельно рекомендую вам это делать на версии которая поддерживает Hyper-V (например win10 Prof).
Включаем компонент Hyper-V в «Включении и отключении компонентов Windows» (Turn Windows features on or of).
Скачиваем установщик с оф.сайта докера и устанавливаем. Также, дополнительно вы можете поставить GUI (Kitematiс) для наглядного отображения.
Приступим к созданию окружения:
Для начала создадим под этот проект папку и заходим в нее:
Дальше строим структуру папок таким образом:
Создаем понятную среду для nginx:
MySQL — в этой папке будут храниться базы. Удобно бэкапить и переносить.
Nginx — тут будут храниться логи, файл конфигурации и наш проект.
PHP — сюда мы сложим Dockerfile с настройками и php.ini.
в корне (в нашем случе папка /mage) будет лежать файл docker-compose.yml.
Создадим конфигурационный файл для Nginx:
Можно использовать любой другой редактор. Если его нет — можно установить с помощью:
И добавляем в nginx.conf следующее:
Во втором блоке прописываем параметры fastcgi.
Третий блок нужен для решения проблемы отображения, в проекте показывалась пустая страница. Из документации вычитал что magento2 требует реврайтинга. (на других проектах таким проблем не возникало).
В папке www создаем каталог для нашего проекта:
Скачиваем с оф.сайта magento2
и извлекаем из архива в папку /mage/Nginx/www/magento2
C настройками для Nginx мы закончили.
Теперь займемся PHP:
Начнем с Dockerfile
Это нужно, чтобы мы могли использовать те модули, которые нужны именно под этот проект.
В этом файле мы рассказали что должно быть установленно в этом образе, а так же указали где будет располагаться корневая директория и куда скопировать настройки из php.ini
Теперь настроим php.ini:
Это взято из php.ini.sample который предлагают сами разработчики Magento2. Нечего сверхъестественного я в него не добавлял.
Все, на этом настройка PHP закончена.
Дальше создаем файл docker-compose который нам все соберет в одну удобную систему.
Тут мы распишем какие сервисы и с какими настройками должны запуститься:
И по экрану побегут строчки, а вы спокойно можете налить себе кружечку горячего кофе, пока машина будет работать за вас.
После установки, у вас в папке MySQL, создастся много файлов и папок, одна из которых будет magento2, а в папке Nginx/Logs появятся 2 лога.
Открыв браузер и набрав там localhost вы должны увидеть приглашение к установке Magento2.
Если все таки что-то не получилось, то возможно этот список решений, сможет вам помочь:
1) Версия docker-compose файла не подошла, тогда нужно поправить «version: ‘3.3’», посмотреть какая именно подойдет вам можно тут
2) Все нормально запустилось, но браузер открывает чистую страницу, без единой ошибки — поможет строчка в nginx.conf
3) Если после установки самой Magento2 (в браузере) у вас не прорисовываются фреймы и все выглядит как текстовый вариант сайта, вам нужно сделать следующее:
3.1 в SQL, советую зайти через phpmyadmin localhost:8090 логин root пароль mypassword, выбрать базу magento2 и ввести sql запрос
3.2 подключиться к контейнеру c PHP (php-fpm) и набрать
Он должен пересчитать и проверить все. И после этого все корректно должно отображаться.
4.1 в линуксе надо отключить политику защиты
Отключение до перезагрузки
или отключение навсегда
4.2 В windows нужно в настройках docker выбрать shared drivers и выбрать диск на котором у вас лежит проект. После перезапуска Docker проблема уйдет.

