Как настроить Laravel, Nginx и MySQL с помощью Docker Compose

    Команда Simple-Server
    03.06.2026
    13 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Кратко о задаче

    Laravel — бесплатный фреймворк с открытым исходным кодом. Его используют для создания архитектурно сложных веб-приложений. Загрузим в домашнюю директорию из GitHub актуальную версию:

    cd ~ git clone https://github.com/laravel/laravel.git

    Смонтируем образ composer в каталог проекта Laravel, поскольку крайне не рекомендуется устанавливать Composer глобально и запускать из-под суперпользователя:

    cd laravel docker run -v $PWD:/app composer install

    Этой командой мы создаём виртуальный контейнер, который будет привязан к текущему каталогу; всё, что находится внутри каталога laravel, скопировано в контейнер. Каталог vendor, который создал менеджер зависимостей Composer в рамках команды install, также скопирован в текущий каталог, то есть в laravel.

    Затем изменим права на каталог так, чтобы к нему был доступ у обычного пользователя, поскольку нам понадобится запускать процессы в контейнере без root-привилегий.

    sudo chown -R username:username ~/laravel

    Теперь можно приступать к работе со службами с помощью Docker Compose.

    Для решения задач, связанных с развёртыванием проектов, которые используют несколько сервисов, разработан инструмент Docker Compose. Если Docker применяется для управления отдельными контейнерами, то Docker Compose позволяет работать с приложениями со сложной архитектурой и множеством зависимостей.

    Для настройки приложения Laravel создадим файл docker-compose.yml и определим необходимые службы — веб-сервер и базу данных.

    nano ~/laravel/docker-compose.yml version: '3' services: # PHP Service app: build: context: . dockerfile: Dockerfile image: php:8.1 container_name: app restart: unless-stopped tty: true environment: SERVICE_NAME: app SERVICE_TAGS: dev working_dir: /var/www volumes: - ./laravel/php/local.ini:/usr/local/etc/php/conf.d/local.ini networks: - app-network # Nginx Service webserver: image: nginx:alpine container_name: webserver restart: unless-stopped tty: true ports: - "80:80" - "443:443" volumes: - /home/username/laravel:/var/www - ./nginx/conf.d:/etc/nginx/conf.d networks: - app-network # MySQL Service db: image: mysql:5.7.22 volumes: - ./mysql:/var/lib/mysql container_name: db restart: unless-stopped tty: true ports: - "3306:3306" environment: SERVICE_TAGS: dev SERVICE_NAME: mysql MYSQL_ROOT_PASSWORD: p@$w0rd networks: - app-network # Docker Networks networks: app-network: driver: bridge

    Подробно разберём некоторые ключевые моменты в этом файле:

    1. app. Содержит приложение Laravel и запускает образ php, который мы определим в дальнейшем. Также определяет рабочую директорию — /var/www.
    2. webserver. Содержит образ nginx:alpine и определяет порты 80 (http) и 443 (https) для работы веб-сервера.
    3. db. Указываем образ mysql из Docker Hub. Кроме этого определяем переменные среды — базу данных laravel, пароль (в нашем случае — p@$w0rd) и порт.

    Если Docker Hub недоступен, можно использовать наш бесплатный прокси, который возобновляет этот доступ.

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

    Для того чтобы организовать взаимодействие между контейнерами, подключим службы к соединительной сети app-network. Так приложения из разных сетей не смогут взаимодействовать друг с другом — это значительно повысит безопасность проекта.

    Далее приступим к настройке основных служб.

    С помощью специального файла Dockerfile можно указать, как собирать образы, на основе которых создаётся контейнер. Этот файл содержит инструкции и аргументы, которые при работе с Docker обрабатываются сверху вниз.

    Наш Dockerfile расположим в корне проекта:

    nano ~/laravel/Dockerfile

    В первой строке мы указываем, что нужно создать образ PHP-FPM версии 8.1. Кроме того, установим нужные для работы приложения Laravel пакеты: pdo_mysql , mbstring , imagick __ и composer.

    В качестве аргументов директивы RUN укажем команды для установки и обновления зависимостей. А также создадим пользователя и группу www __ для работы с приложением Laravel. Так мы снизим риски при запуске контейнера Docker, поскольку иначе они бы запускались с правами суперпользователя.

    С помощью Workdir укажем рабочий каталог /var/www и зададим необходимые права для нового пользователя www, воспользовавшись командой COPY. Директивой EXPOSE откроем 9000 порт для сервера php-fpm.

    После создания контейнера нужно запустить php-fpm сервер, для этого используем команду CMD.

    Чаще всего для веб-приложений достаточно основных файлов конфигурации служб. В рамках нашего примера мы всё же переопределим базовые настройки для демонстрации возможностей контейнеризации.

    После того, как мы определили конфигурацию контейнера, нужно настроить PHP для обработки входящих запросов NGINX. Для начала нужно создать файл local.ini, путь к нему мы указывали в файле docker-compose.yml — /usr/local/etc/php/conf.d/local.ini. Если мы не создадим этот файл, контейнер будет использовать стандартный файл конфигурации PHP: php.ini.

    В директории приложения laravel создаём каталог php и файл local.ini в нём:

    mkdir ~/laravel/php nano ~/laravel/php/local.ini

    В этот файл вставим директиву для отображения всех ошибок:

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

    В нашем примере мы используем NGINX в качестве прокси-сервера. Это значит, что все входящие запросы будут асинхронно передаваться на бэкенд (в нашем случае — PHP-FPM).

    По аналогии с настройкой PHP мы также создадим в каталоге laravel файл /nginx/conf.d/app.conf:

    mkdir -p ~/laravel/nginx/conf.d nano ~/laravel/nginx/conf.d/app.conf

    Внутри файла определим конфигурацию прокси-сервера:

    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 ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location / { try_files $uri $uri/ /index.php?$query_string; gzip_static on; } }

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

    1. Listen — порт, на котором сервер будет отлавливать запросы.
    2. Index — индексные файлы веб-приложения.
    3. Error_log, access_log — файлы для записи журналов ошибок и запросов к серверу.
    4. root — корневой каталог веб-приложения.

    Внутри первого блока location определим настройки PHP. В частности, укажем, что служба app прослушивает 9000 порт. Директива fastcgi_pass указывает, что сервер PHP-FPM должен выполнять прослушивание через сокет TCP. Второй блок location задаёт правила перенаправления всех запросов на индексный файл index.php с сохранением параметров.

    Настройка MySQL осуществляется аналогично конфигурации веб-сервера и PHP. Сначала мы создадим файл в каталоге, который указали внутри файла docker-compose.yml:

    mkdir ~/laravel/mysql nano ~/laravel/mysql/my.cnf

    В этом файле определим общие правила журналирования:

    [mysqld] general_log = 1 general_log_file = /var/lib/mysql/general.log

    После того, как мы определили конфигурацию для основных служб, можно запускать контейнеры. Но перед этим укажем настройки приложения Laravel в специальном файле .env. Внутри каталога Laravel уже есть пример такого файла, который поставляется в дистрибутиве — .env.example. Копируем его и указываем свои настройки там, где это нужно:

    cd ~/laravel cp .env.example .env nano .env

    Основная настройка для приложения — доступ для подключения к базе данных и адрес сервера. В файле найдём строку APP_URL и укажем домен или IP-адрес нашего сайта, далее в блоке DB_CONNECTION укажем наши данные:

    APP_URL=http://domain.com DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD=p@$w0rd MYSQL_ROOT_PASSWORD=p@$w0rd

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

    При первом вызове Docker будет загружать в систему образы, поэтому запуск может занять некоторое время. После сохранения образов на локальной машине Docker Compose создаст наши контейнеры. При этом, чтобы обеспечить их работу в фоновом режиме, мы должны использовать флаг -d.

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

    Для корректной работы приложения Laravel мы должны сгенерировать ключ APP_KEY в .env-файл. Для этого воспользуемся docker-compose exec, эта утилита позволяет выполнять команды в конкретных контейнерах:

    docker-compose exec app php artisan key:generate

    … и сохраним настройки в кэш для ускорения загрузки:

    docker-compose exec app php artisan config:cache

    При кэшировании настройки будут загружены в файл /var/www/bootstrap/cache/config.php.

    Теперь, если ввести IP-адрес вашего сервера в адресную строку браузера, вы увидите стартовую страницу Laravel.

    Создание пользователя MySQL

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

    По умолчанию MySQL создаётся только одна учётная запись — root. Но использовать её в веб-среде небезопасно, поскольку root-пользователь обладает неограниченными привилегиями.

    Воспользуемся командой docker-compose exec для того, чтобы перейти в интерактивную оболочку bash в контейнере db:

    docker-compose exec db bash

    Поскольку при создании файла docker-compose.yml мы определили базу данных laravel, она уже создана. Убедимся в этом:

    show databases; +--------------------+ | Database           | +--------------------+ | information_schema | | laravel            | | mysql              | | performance_schema | | sys                | +--------------------+ 5 rows in set (0.01 sec)

    Создаём учётную запись laravel __ с доступом только к этой базе данных. Пароль нужно указать такой же, как и в файле .env:

    GRANT ALL ON laravel.* TO 'laravel'@'%' IDENTIFIED BY 'p@$w0rd';

    Обновляем привилегии, закрываем MySQL и выходим из контейнера:

    mysql> FLUSH PRIVILEGES; mysql> EXIT; # exit

    В этой статье мы рассмотрели преимущества использования контейнеризации в работе с веб-приложениями. Среди основных плюсов — независимость приложений друг от друга и от сервера, на котором они находятся.

    Для упрощения работы с контейнерами использовали Docker Compose, который позволяет создавать группу контейнеров Docker, а не запускать каждый по отдельности. В качестве демонстрации простоты работы с контейнерами создали простое Laravel-приложение, используя стек LEMP.

    В официальном канале Simple-Server собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490₽

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190₽

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны