С командами ремесленника, командами композитора, командами npm, заданиями cron, очередями, базой данных и кэш-контейнерами Redis.

Оглавление

1. Introduction
2. Prerequisites for this guide
3. Set up git
4. Download and install docker and docker-compose
5. Clone laravel application and create root folders
6. Create .env, .env.example and .gitignore files
7. Docker compose yaml file
8. Main containers
9. Utility containers
10. Configuring Vite asset bundler and InertiaJS
11. Starting your containers
12. Pushing code to github
13. Resources/Links
14. Conclusion

1. Введение

Это руководство покажет вам, как настроить среду разработки стека Laravel-React с помощью Docker и включить несколько дополнительных служебных контейнеров, чтобы завершить настройку.

Установка не зависит от операционной системы и не имеет никаких зависимостей, кроме Docker и Docker Compose. Он может работать во всех основных операционных системах, таких как Microsoft Windows, Apple macOS и Linux, если установлены Docker и Docker compose.

Эта настройка позволяет вам смешивать и сопоставлять версии ваших сервисов в соответствии с вашими предпочтениями, просто редактируя одну или две строки. Например, вы можете комбинировать PHP 7.4, 8.0, 8.1 или 8.2 с Laravel 7, 8 или 9 по своему усмотрению.

Мы поместим приложение Laravel 9 в контейнер и позволим ему взаимодействовать с другими основными/служебными контейнерами, формируя полную докеризированную среду разработки.

В таблицах ниже показаны сервисы (контейнеры), которые мы будем запускать в нашей среде Docker. Я сгруппировал их в два (основные контейнеры и служебные контейнеры).

  • Основные контейнеры — работают непрерывно после запуска и часто перезапускаются при сбое, если не остановлены.
  • Служебные контейнеры — эти контейнеры запускают команды для настройки и оптимизации всего приложения. Контейнеры уничтожаются после запуска команд.

2. Требования к этому руководству

  1. Вы должны осознавать необходимость создания контейнеров и то, как они работают.
  2. Требуется знакомство с ReactJS и понимание того, как работает Laravel.

Теперь давайте углубимся в код и команды докера.

3. Настройте Git

Чтобы использовать Git в командной строке, вам необходимо настроить Git на своем компьютере. Вы будете использовать Git для клонирования приложения Laravel 9. Ближе к концу этого руководства я покажу вам, как отправить весь код установки в репозиторий GitHub с помощью Git.

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

4. Загрузите и установите Docker и docker-compose

Скачайте и установите Docker отсюда. Вы можете использовать либо клиент Docker Desktop, либо клиент Docker CLI. Скачайте и установите docker-compose отсюда.

5. Клонируйте приложение Laravel и создайте корневые папки

Перейдите в папку, в которой вы хотите, чтобы ваш проект хранился локально, и создайте следующую папку/подпапки в списке ниже. Вы можете открыть папку проекта из Visual Studio IDE (VS Code) и создать все свои папки и файлы.

  • докер/логи
  • докер/mysql
  • докер/nginx

Мы будем использовать папку docker/logs для хранения журналов контейнера, docker/mysql для хранения данных mysql и docker/nginx для файлов конфигурации NGINX. Если эти папки не настроены, данные, созданные при запуске контейнеров, уничтожаются при каждом их перезапуске.

Из корня папки вашего проекта клонируйте репозиторий Laravel в папку с именем src с помощью Git. В VS Code переключите терминал и вставьте приведенную ниже команду.

git clone https://github.com/laravel/laravel.git src

ПРИМЕЧАНИЕ. Удалите папки .github и .git в папке src. .github содержит действия GitHub по умолчанию для laravel, а .git содержит сведения о репозитории Laravel. Мы создадим новый репозиторий git из корня каталога нашего проекта. Мы также создадим пользовательские действия GitHub в следующем руководстве.

6. Создайте файлы .env, .env.example и .gitignore.

Скопируйте .env.example из папки src в корень каталога вашего проекта. Этот файл является лишь примером того, что может быть в файле .env. Вы можете изменить версию этого файла.

В том же каталоге создайте файл .env. Переменные конфигурации вашего приложения будут храниться здесь. Этот файл может иметь разные значения для разных серверов и разных разработчиков при совместной работе над проектом. Поэтому он не должен быть версионным.

Создайте файл .gitignore и добавьте следующий код:

.env
docker/logs/*
docker/mysql/*

7. Docker Compose YAML-файл

Compose — это инструмент для определения и запуска многоконтейнерных приложений Docker. С Compose вы используете файл YAML для настройки служб вашего приложения. Затем с помощью одной команды вы создаете и запускаете все службы из вашей конфигурации. — Докер композиций

Наша файловая структура docker-compose.yml выглядит так:

version: '3'
networks:
  laravel:
services:
  ... services go here

version: '3' относится к версии Docker compose. По сравнению с версией 2, версия 3 совместима со Swarm; следовательно, вам не придется ничего менять, если вы решите использовать оркестратор Docker Swarm позже.

Сеть под названием laravel настроена в разделе networks:. Контейнеры, которые присоединяются к этой сети, будут доступны другим контейнерам в сети. Их также можно обнаружить по имени хоста, идентичному имени контейнера.

services: представляет экземпляры изображений, например, службы базы данных, службы Redis, службы PHP и т. д.

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

Не беспокойтесь о деталях в этом файле; мы рассмотрим их в следующих разделах этого руководства.

Структура папок проекта теперь выглядит так:

8. Основные контейнеры

8.1. Nginx-сервис

Настройте контейнер, который будет служить самим веб-сервером. Он будет получать HTTP-запросы от конечных пользователей и отправлять их в контейнер PHP, который будет обрабатывать наш код Laravel.

Вот сервисный код NGINX:

Авария

  • build — определяет параметры конфигурации, которые Compose применяет для создания образа Docker.
  • context — определяет путь к нашему dockerfile Nginx.
  • dockerfile — это файл Dockerfile, используемый для создания образа Nginx, и он разрешается из контекста.
  • args — определяет аргументы сборки, т. е. значения nginx.dockerfile ARG, как показано в следующем разделе.
  • restart — определяет политику перезапуска контейнера.
  • container_name — определяет имя контейнера.
  • ports — Сопоставляет порт хост-компьютера с портом контейнера.
  • volumes — монтирует содержимое каталога проекта в каталог контейнеров /var/www/html, а файл .env — в местоположение контейнера /var/www/html/.env. Любое изменение содержимого проекта, сделанное на хост-компьютере, отразится в контейнере и наоборот.
  • depends_on — Это определяет зависимость от другой службы, которая должна быть запущена перед созданием этой службы.
  • networks — служба будет напрямую взаимодействовать с другими службами в сети laravel.

nginx.dockerfile

Контекст этого файла — папка docker проекта. Ниже находится наш файл nginx.dockerfile. Он основан на образе nginx:stable-alpine, который очень легкий, всего около 5 МБ.

В приведенном выше файле docker мы копируем файл default.conf из каталога nginx нашего проекта в каталог контейнера. Он переопределит конфигурации Nginx по умолчанию.

Ниже представлен наш файл default.conf:

Конфигурация, которая позволяет контейнеру Nginx передавать запросы PHP FPM (FastCGI Process Manager), — fastcgi_pass php:9000 . Эти запросы передаются в контейнер с именем php через порт 9000.

8.2. PHP-сервис

В отличие от веб-сервера Apache, Nginx должен использовать PHP-FPM как отдельный процесс для обработки клиентских запросов PHP.

Ниже приведен раздел службы PHP:

Авария

Здесь мы используем собственный файл докеров с именем php.dockerfile. container_name — это php, и этот контейнер доступен только внутри других контейнеров через порт 9000.

php.dockerfile

Контекст этого файла также является папкой docker проекта. Ниже находится наш файл php.dockerfile. Он основан на альпийском образе (он облегченный) php:8.1-fpm-alpine.

8.3. Сервис MySQL

Для нашего контейнера базы данных, на котором работает Mysql, мы будем использовать официальный образ MariaDB DockerHub непосредственно в нашем файле docker-compose.yml. Он поставляется предварительно настроенным и поддерживается сообществом с использованием лучших практик.

Вот как это выглядит:

В этой службе мы должны определить переменные среды: ${DB_DATABASE}, ${DB_USERNAME} и ${DB_PASSWORD}. Они определяются из файла .env, который мы создали ранее. Ниже приведен пример конфигурации .env.

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel_user
DB_PASSWORD=%6larav31

Как правило, в Laravel DB_HOST обычно настраивается как IP-адрес базы данных, то есть DB_HOST=127.0.0.1. Однако в этом случае мы будем использовать имя службы mysql, то есть DB_HOST=mysql.

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

Чтобы избежать потери данных базы данных при перезапуске контейнера, том ./docker/mysql монтируется в /var/lib/mysql внутри контейнера. Таким образом, данные Mysql будут сохраняться на хост-компьютере в каталоге ./docker/mysql.

8.4. Служба Redis

Мы добавим сервис Redis на основе образа redis:alpine, чтобы заставить Redis работать. Сервис будет выглядеть так, как показано ниже:

Нам также необходимо обновить наш файл .env, чтобы использовать эту службу Redis для управления очередями и сеансами. Обновите следующие разделы файла .env. Мы используем имя нашей службы Redis в качестве хоста Redis, REDIS_HOST=redis.

QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

8.5. Служба занятости Cron

Этот сервис будет основан на php.dockerfile, который мы создали ранее.

Вот служебный файл:

Мы используем команду schedule:work вместо schedule:run, работающей на переднем плане, и каждую минуту вызываем планировщик. Команда entrypoint выполняется при запуске контейнера.

8.6. Служба очередей

Этот сервис также основан на php.dockerfile. Конфигурации службы будут выглядеть следующим образом:

entrypoint этой службы запустит команду Laravel php artisan queue:work. Эта команда запускает базовую службу очередей Laravel, которая обрабатывает все задания в очереди. Это способ обработки очередей в Laravel по умолчанию. Вы также можете настроить Горизонт и использовать вместо него.

Horizon предоставляет красивую панель управления и управляемую кодом конфигурацию для ваших очередей Redis на базе Laravel. При использовании Horizon вы обновите точку входа до entrypoint: ['php', '/var/www/html/artisan', 'horizon'].

8.7. Почтовый сервис

Mailhog — отличный инструмент для подтверждения того, что ваша рассылка работает должным образом в среде разработки. Он имеет веб-интерфейс пользователя, из которого вы можете проверить свою электронную почту.

Этот сервис основан на изображении mailhog/mailhog:latest. Это не официальное изображение, но команда Mailhog поддерживает его, так что вы в надежных руках. В отличие от официальных образов, где репозиторий образов указан так {repository}:{tag}. Здесь мы также должны идентифицировать пользователя, {user}/{repository}:{tag}.

По умолчанию Mailhog хранит журналы. Нам они бесполезны, поэтому мы установим для logging driver значение none.

Порт 8025 предназначен для подключения к панели управления пользовательского интерфейса, а порт 1025 — для подключения к почтовому серверу. Вы можете получить доступ к панели инструментов через http://localhost:8025 на вашем хост-компьютере.

8.8. Служба PhpMyAdmin

PhpMyAdmin предоставит нам графический интерфейс для управления нашей базой данных без необходимости доступа к ней через оболочку/терминал. Ниже приведены его конфигурации службы:

Этот сервис основан на phpmyadmin:5.2.0, который представляет собой предварительно сконфигурированный официальный образ докера.

Переменные среды ${DB_HOST}, ${DB_USERNAME}, ${DB_PASSWORD} и ${DB_PORT} будут автоматически выбраны Compose из нашего файла .env. Эта служба зависит от mysql, поэтому перед запуском нашего графического интерфейса необходимо запустить базу данных. Хост-компьютер использует порт 8888 для подключения к нашему интерфейсу. Вы можете получить доступ к панели инструментов PhpMyAdmin через http://localhost:8888.

9. Универсальные контейнеры

При запуске контейнеров docker с помощью команды docker-compose up будут запущены все службы в файле docker-compose.yml. Однако запускать служебные контейнеры следует только при необходимости.

Для запуска только основных контейнеров используем команду docker-compose up build nginx. Это гарантирует, что будут запускаться только те контейнеры, от которых зависит nginx service. Это контейнеры, перечисленные в разделе depends_on документа nginx service.

Мы также будем использовать profiles для блокировки служебных служб таким образом, чтобы они запускались только в том случае, если был активирован отдельный профиль или при запуске конкретной службы с использованием docker-compose run service_name.

При запуске служебных контейнеров используется команда docker-compose run --rm вместо docker-compose up. И аргументы службы/контейнера прикрепляются в конце. run используется для запуска одноразовой команды для службы, а --rm удаляет контейнер после выполнения команды. Если вам нужно подключиться к другим контейнерам докеров, используйте опцию --service-ports. Например docker-compose run --rm --service-ports service_name argument.

9.1. Миграция-seed-сервис

Этот сервис запускает миграции и сеялки. Он также основан на php.dockerfile.

Точка входа этой службы будет запускать команды php artisan migrate и php artisan db:seed последовательно при запуске контейнера.

Запуск команды laravel-migrate-seed

docker-compose run --rm laravel-migrate-seed

9.2. Сервис композитора

Composer — менеджер зависимостей для PHP. Служба Composer используется для запуска команд композитора. Он использует пользовательский файл докеров с именем composer.dockerfile, контекстом которого является папка докеров нашего проекта.

Вот конфигурация службы:

composer.dockerfile

Этот файл докеры основан на образе composer:2, официальном файле образа докера предварительной сборки composer версии 2.

Запуск команд композитора

Команды Composer запускаются с помощью команды docker-compose run --rm и добавления аргументов композитора в конце. Ознакомьтесь с примерами в таблице ниже:

9.3. Ремесленное обслуживание

Этот сервис запускает ремесленные команды Laravel. Он основан на php.dockerfile.

Запуск ремесленных команд

Как и команды композитора, ремесленные команды запускаются с помощью команды docker-compose run --rm и добавления ремесленных аргументов в конце. Ниже приведены примеры:

9.4. Служба NPM

Мы будем использовать этот сервис для запуска команд npm. Он основан на официальном образе докера node:alpine.

Запуск npm-команд

Команды NPM также запускаются с помощью команды docker-compose run --rm и добавления аргументов npm в конце. Однако при запуске npm run dev необходимо установить связь между этим контейнером npm и контейнером PHP для горячей перезагрузки. Поэтому мы включаем опцию --service-ports в нашу команду.

Примеры npm-команд:

10. Настройка Vite Asset Bundler и InertiaJS

Начиная с Laravel 9, опыт разработчиков улучшился благодаря внедрению Vite, внешнего сборщика ресурсов. Раньше Laravel использовал webpack в качестве сборщика ресурсов по умолчанию. В этом руководстве мы будем использовать Vite для интеграции ReactJS в Laravel.

InertiaJS поможет нам собрать стек React и Laravel в одном проекте. Вы можете думать об этом как о клее, скрепляющем наши внешние и внутренние стеки вместе. Установите InertiaJS, введя в терминале следующую команду:

docker-compose run --rm composer require inertiajs/inertia-laravel

Давайте установим промежуточное ПО инерции в нашем проекте, используя команду artisan ниже:

docker-compose run --rm artisan inertia: middleware

Перейдите в каталог src/app/Http, затем в файле Kernel.php добавьте следующую строку в массив $middlewareGroups[] в его массив web[].

'web' => [
  // ...
  \App\Http\Middleware\HandleInertiaRequests::class,
],

Чтобы наши маршруты распознавались во фронтенде при рендеринге с помощью JavaScript вместо блейда, мы будем использовать специальный пакет под названием ziggy. Давайте установим его с помощью composer.

docker-compose run --rm composer require tightenco/ziggy

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

Давайте создадим новый блейд-файл app.blade.php. Это будет наша точка входа blade. Поместите в файл следующий код:

@vite() и @viteReactRefresh сообщают приложению Laravel, что Vite компилирует наши ресурсы (файлы JS и CSS) и что мы будем использовать JSX для нашего внешнего интерфейса. Файл CSS также можно вызвать из этого файла, добавив строку @vite('resources/css/app.css'). Однако идеально вызывать его из файла resources/js/app.jsx и вызывать этот файл в blade , как показано выше.

Настройка React-интерфейса

Мы будем использовать npm container для установки наших внешних зависимостей.

Выполните следующую команду на своем терминале:

docker-compose run --rm npm i react react-dom @inertiajs/inertia @inertiajs/inertia-react jsconfig.json @inertiajs/progress

Приведенная выше команда установит React, react-dom, зависимости внешнего интерфейса инерции, индикатор выполнения инерции для загрузки страницы и файл jsconfig.json.

Далее мы добавим плагин vite для React.

docker-compose run --rm npm add @vitejs/plugin-react

Перейдите к файлу src/resources/js/app.js и добавьте следующий скрипт под оператором import "./bootstrap". Затем переименуйте файл в app.jsx. Как видите, app.css импортируется из этого файла.

Наконец, нам нужно сообщить Vite, что мы используем React, и указать наш файл точки входа. Мы поместим нашу конфигурацию в src/vite.config.js, файл, установленный в Laravel 9 по умолчанию. Давайте направимся туда, изменим и добавим следующие строки:

Строка input: "resources/js/app.jsx", указывает нашу точку входа JSX. server settings указывает адрес npm container и служебный порт. npm container доступен через порт 3000, как показано в нашем файле докера.

Создание приветственной страницы и приветственного маршрута

Давайте теперь создадим маршрут для нашей страницы приветствия. Перейдите к файлу src/routes/web.php и добавьте следующие строки, чтобы Laravel знал о маршруте на нашу страницу приветствия.

Route::get('/', function () {
   return inertia('Welcome');
}

Затем мы создадим приветственную страницу нашего интерфейса. Создайте новую папку Pages и добавьте файл Welcome.jsx в каталог src/resources/js/. Поместите следующий код в файл.

export default function Welcome () {
    return (
        <>
            <div>Hello Docker Multiverse!</div>
        </>
    );
}

11. Запуск ваших контейнеров

Запуск миграций

Создайте таблицы базы данных, выполнив следующую команду:

docker-compose run --rm laravel-migrate-seed

Он создаст таблицы базы данных по умолчанию, которые настроены в файлах миграции Laravel.

Запуск основных контейнеров

Чтобы запустить main containers, перейдите в корень каталога вашего проекта и выполните следующую команду:

docker-compose up --build nginx -d

Мы запускаем команду выше, а не просто docker-compose up --build -d, потому что мы хотим запустить только main containers. Наш nginx container зависит от всех остальных основных контейнеров; следовательно, он запустит их первым.

Аргумент -d запускает команду в режиме демона без вывода журналов на ваш терминал.

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

Вы можете проверить запущенные контейнеры, выполнив команду docker ps на своем терминале, как показано на изображении ниже.

Конфигурации приложения Laravel

Установите пакеты PHP с помощью композитора, выполнив следующую команду:

docker-compose run --rm composer install

Давайте завершим настройку нашего приложения, установив ключ приложения и очистив все кэшированные файлы конфигурации. Мы можем добиться этого, выполнив следующие команды.

docker-compose run --rm artisan key:generate
docker-compose run --rm artisan optimize

Код нашего локального приложения монтируется в контейнеры artisan и composer при запуске контейнеров. Таким образом, выполнение приведенных выше команд обновит как код контейнеров, так и код, локальный для вашего компьютера, как если бы вы запускали команды локально.

Запуск интерфейса React

Мы запустим наш интерфейс React в режиме разработки с включенной горячей перезагрузкой, используя следующую команду.

docker-compose run --rm  --service-ports npm run dev

Примечание. Убедитесь, что вы обновили файл .env вашего приложения, чтобы он отражал правильный APP_URL. Открытый порт определяет указанный URL-адрес в нашем файле nginx service. В нашем случае мы используем порт 8000. Мы обновим APP_URL до APP_URL=http://localhost:8000.

Давайте теперь проверим наше приложение:

Вставьте любой из следующих URL-адресов в свой браузер.

Приложение — http://localhost:8000

Страница src/resources/js/Pages/Welcome.jsx должна отображаться.

Почтальонhttp://localhost:8025

PhpMyAdminhttp://localhost:8888

12. Отправка кода на GitHub

Чтобы иметь возможность отслеживать проект, мы отправим его на GitHub.

Создание локального репозитория

  • Заходим в родительский каталог нашего проекта.
  • Введите git init.
  • Введите git add ., чтобы добавить все соответствующие файлы. Файлы, указанные в .gitignore, будут игнорироваться.
  • Введите git commit -m “first commit”.

Подключение репозитория к GitHub

  • Перейдите на GitHub.
  • Войдите в свой аккаунт.
  • Нажмите кнопку Новый репозиторий в правом верхнем углу и инициализируйте пустой репозиторий.
  • Нажмите кнопку «Создать репозиторий».
  • Скопируйте URL репозитория.
  • На своем терминале в корне каталога вашего проекта введите приведенные ниже команды и замените URL-адрес репозитория на свой.
git remote add origin https://github.com/username/new_repo.git
git branch -M main
git push -u origin main
  • Наконец, вы можете добавить файл LICENSE и файл README для описания проекта. Вы можете сделать это непосредственно из GitHub или создав файлы локально и отправив изменения в GitHub.

13. Ресурсы/Ссылки

GitHub — проект Laravel 9 плюс React с предварительно настроенной настройкой Docker.

Заключение

Я надеюсь, что это было полезное руководство. Спасибо за чтение!