Докеризация приложения Laravel 11
Создание необходимых конфигурационных файлов
Для начала создадим в проекте следующие файлы:
./deploy/docker-compose.yml
./deploy/Dockerfile
./deploy/nginx.conf
./deploy/php.ini
./.dockerignore
Эти файлы содержат необходимую конфигурацию для создания образа Docker и управления контейнерами.
Создание Dockerfile
Dockerfile
определяет среду разработки для приложения Laravel. В данном случае разделим её на два этапа: один — для создания приложения, другой — для его запуска в продакшен (не обязательно), как показано ниже:
# deploy/Dockerfile
# Этап 1: этап сборки
FROM php:8.3-fpm-alpine as build
# Установка системных зависимостей и php расширений
RUN apk add --no-cache \
zip \
libzip-dev \
freetype \
libjpeg-turbo \
libpng \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
nodejs \
npm \
&& docker-php-ext-configure zip \
&& docker-php-ext-install zip pdo pdo_mysql \
&& docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-enable gd
# Установка composer
COPY /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
# Копирование необходимых файлов и изменение разрешений
COPY . .
RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 775 /var/www/html/storage \
&& chmod -R 775 /var/www/html/bootstrap/cache
# установка php и node.js зависимостей
RUN composer install --no-dev --prefer-dist \
&& npm install \
&& npm run build
RUN chown -R www-data:www-data /var/www/html/vendor \
&& chmod -R 775 /var/www/html/vendor
# Этап 2: этап продакшена
FROM php:8.3-fpm-alpine
# Установка nginx
RUN apk add --no-cache \
zip \
libzip-dev \
freetype \
libjpeg-turbo \
libpng \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev \
oniguruma-dev \
gettext-dev \
freetype-dev \
nginx \
&& docker-php-ext-configure zip \
&& docker-php-ext-install zip pdo pdo_mysql \
&& docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd \
&& docker-php-ext-enable gd \
&& docker-php-ext-install bcmath \
&& docker-php-ext-enable bcmath \
&& docker-php-ext-install exif \
&& docker-php-ext-enable exif \
&& docker-php-ext-install gettext \
&& docker-php-ext-enable gettext \
&& docker-php-ext-install opcache \
&& docker-php-ext-enable opcache \
&& rm -rf /var/cache/apk/*
# Копирование файлов с этапа сборки
COPY /var/www/html /var/www/html
COPY ./deploy/nginx.conf /etc/nginx/http.d/default.conf
COPY ./deploy/php.ini "$PHP_INI_DIR/conf.d/app.ini"
WORKDIR /var/www/html
# Добавление всех папок, в которых хранятся файлы, требующие постоянного хранения, если необходимо. В противном случае удалите эту строку.
VOLUME ["/var/www/html/storage/app"]
CMD ["sh", "-c", "nginx && php-fpm"]
Создание файл docker-compose.yml
Этот файл определяет сервисы, необходимые для запуска Laravel-приложения в Docker. В приведённом ниже файле docker-compose.yml
определяется сервис для приложения Laravel, а также сервис для базы данных MySQL.
# deploy/docker-compose.yml
version: '3.8'
services:
laravel:
restart: unless-stopped
container_name: laravelapp
build:
context: ../
dockerfile: ./deploy/Dockerfile
# При необходимости выделите столько томов, сколько нужно.
volumes:
- ../storage/app:/var/www/html/storage/app
environment:
APP_NAME: ${APP_NAME}
APP_ENV: ${APP_ENV}
APP_DEBUG: ${APP_DEBUG}
APP_KEY: ${APP_KEY}
APP_VERSION: ${APP_VERSION}
APP_URL: ${APP_URL}
DB_CONNECTION: mysql
DB_HOST: database
DB_PORT: 3306
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
MAIL_MAILER: ${MAIL_MAILER}
MAIL_HOST: ${MAIL_HOST}
MAIL_PORT: ${MAIL_PORT}
MAIL_USERNAME: ${MAIL_USERNAME}
MAIL_PASSWORD: ${MAIL_PASSWORD}
MAIL_ENCRYPTION: ${MAIL_ENCRYPTION}
MAIL_FROM_ADDRESS: ${MAIL_FROM_ADDRESS}
MAIL_FROM_NAME: ${MAIL_FROM_NAME}
ports:
- "8080:80"
networks:
- n-laravel
depends_on:
- database
database:
restart: unless-stopped
image: mariadb:lts-jammy
volumes:
- v-database:/var/lib/mysql
environment:
MARIADB_DATABASE: ${DB_DATABASE}
MARIADB_USER: ${DB_USERNAME}
MARIADB_PASSWORD: ${DB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
networks:
- n-laravel
volumes:
v-database:
networks:
n-laravel:
driver: bridge
В конфигурации тома (volumes
) можно добавить или удалить нужные тома. В данном случае добавляется только том для папки storage/app
, поскольку предполагается, что это единственная папка, нуждающаяся в постоянном хранении. Также, если он не нужен, его можно удалить.
Аналогично, не обязательно использовать каталог в качестве тома; можно без проблем использовать том Docker.
Конфигурирование сервера Nginx
Далее настроим файл nginx.conf
для обслуживания Laravel-приложения. Этот файл определяет конфигурацию сервера Nginx и то, как обрабатывать запросы к приложению.
# deploy/nginx.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/public;
client_max_body_size 10M;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico {
access_log off; log_not_found off;
}
location = /robots.txt {
access_log off; log_not_found off;
}
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
}
Конфигурирование PHP
Если необходимо настроить PHP, это можно сделать через файл php.ini
. Как показано в следующем примере, где максимальный размер загружаемого файла установлен в 10 МБ.
# deploy/php.ini
upload_max_filesize = 10M
Создание файла .dockerignore
В этом файле указывается, какие файлы или каталоги должны игнорироваться Docker при сборке образа. Например, не следует копировать каталог vendor
для совместимости, времени и т. д.
# .dockerignore
/deploy/docker-compose.yml
/deploy/Dockerfile
/.phpunit.cache
/node_modules
/public/build
/public/hot
/public/storage
/public/bucket
/storage/*.key
/vendor
.env
.env.example
.env.backup
.env.production
.phpunit.result.cache
Homestead.json
Homestead.yaml
auth.json
npm-debug.log
yarn-error.log
/.fleet
/.idea
/.vscode
.git
Конфигурация переменных среды
По умолчанию при создании проекта Laravel создаётся файл .env
с необходимыми переменными среды для разработки.
Но если вдруг файл .env
отсутствует, необходимо создать его в корне проекта и определить необходимые переменные среды для приложения. Вот ссылка, на пример, как должен выглядеть .env
-файл: https://github.com/laravel/laravel/blob/11.x/.env.example
Из всего этого набора настроек важно отредактировать параметры базы данных. Которые по умолчанию до редактирования выглядят следующим образом:
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
Необходимо изменить их на:
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=admin
DB_PASSWORD=admin
DB_ROOT_PASSWORD=root
В данном случае игнорируются следующие параметры: DB_CONNECTION
, DB_HOST
и DB_PORT
. Причина в том, что эти параметры уже определены в файле docker-compose.yml
.
Кроме того, добавляем: DB_ROOT_PASSWORD
, необходимый для корректной сборки образа MySQL, так как он требует пароль пользователя root
.
Создание Docker-образа
Когда всё настроено, пришло время собрать Docker-образ. Для этого воспользуемся следующими командами:
Сборка и установка контейнеров
docker compose -f deploy/docker-compose.yml --env-file ./.env up --build
Запуск миграций Laravel
docker exec -t laravelapp php artisan migrate
Запуск Laravel seeder-ов
На этом шаге не достаточно только выполнить команду, если используется библиотека fakerphp/faker
, необходимо изменить файл composer.json
, переместив библиотеку из списка зависимостей разработки в список зависимостей продакшена.
Это происходит потому, что при создании образа указано не устанавливать зависимости разработки, и поэтому при запуске команды будет выдана ошибка о невозможности найти библиотеку.
Пример, как должен выглядеть composer.json
:
До:
{
"require": {
...
},
"require-dev": {
"fakerphp/faker": "^1.23"
}
}
После:
{
"require": {
...
"fakerphp/faker": "^1.23"
},
"require-dev": {
...
}
}
А теперь можно выполнить команду:
docker exec -t laravelapp php artisan db:seed
Настройка томов
Как вы знаете, в Dockerfile
мы определяем том для папки storage/app
приложения. Аналогично, в файле docker-compose.yml
том настраивается как каталог для постоянного хранения файлов.
Однако можно столкнуться с проблемой, когда при записи в этот каталог будет возникать ошибка прав доступа.
Это происходит потому, что Nginx не имеет достаточных прав на запись в каталог. Моим решением этой проблемы стало выполнение следующей команды для изменения и добавления этих разрешений:
# Первое: изменение группы (nginx)
sudo chown -R :81 storage/app
# Второе: изменение разрешений
sudo chmod -R 775 storage/app
Доступ к приложению
После того как образ создан и контейнеры подняты с помощью команды docker compose
, можно проверить работоспособность приложения в браузере.
Убедитесь, что обращаетесь к URL http://localhost:8080
, и если всё в порядке, увидите главную страницу приложения Laravel.
Заключение
Выполнив эти шаги, вы создадите образ Docker для своего приложения Laravel 11. Теперь можно развернуть приложение в любой среде, не заботясь о зависимостях и конфигурации сервера.
Стоит отметить, что необходимо тщательно проверить, не нужно ли добавить дополнительные зависимости в Dockerfile
, а также изменить другие параметры, которые могут потребоваться для работы приложения: Nginx, php.ini
и даже версию используемого PHP, возможно, придётся изменить.