Site icon 8HOST.COM

Запуск приложения Laravel через Docker Compose

Laravel – это открытый PHP-фреймворк, в котором вы найдете набор инструментов и ресурсов для создания современных PHP-приложений. Эта серия руководств поможет вам создать простое приложение на платформе Laravel, используя среду разработки PHP, контейнеризованную при помощи Docker Compose. В итоге вы получите одностраничный веб-сайт, которым можно управлять с помощью команд Artisan. На этом сайте вы сможете делиться с аудиторией актуальными ссылками.

Примечание: Другие части этой серии можно найти по этой ссылке.

Прежде всего нам нужно создать контейнерную среду, способную поддерживать работу PHP и Composer (это инструмент управления зависимостями PHP). После этого мы загрузим новое приложение Laravel; таким образом, устанавливать среду PHP на вашем локальном компьютере или сервере разработки не будет необходимости.

Вы найдете простые инструкции по настройке такой среды в нашем мануале Установка и настройка Laravel с помощью Docker Compose в Ubuntu 20.04. Пожалуйста, обратитесь к этому мануалу, если вам нужны более подробные сведения о параметрах, используемых в файле Docker Compose, к которым мы обратимся в этом руководстве.

Итак, создайте новый каталог для вашего приложения в своей домашней папке:

mkdir ~/landing-laravel
cd ~/landing-laravel

Затем создайте файл docker-compose.yml, который будет определять контейнерную среду. Здесь мы настроим сервис по имени app, который будет основан на пользовательском образе Docker, созданном с помощью Dockerfile (этот файл мы создадим позже).

Аргументы сборки user и uid, которые определены в файле docker-compose.yml (и используются в Dockerfile во время сборки), нужно изменить – они должны отражать имя вашего пользователя и uid на вашем локальном компьютере или сервере разработки. Чтобы узнать uid вашего текущего пользователя, введите:

echo $UID
1000

Переменные user и uid будут доступны во время сборки; наш Dockerfile будет использовать их для создания нового пользователя в сервисе app. У этого пользователя будет то же имя и uid, что и у текущего системного пользователя на вашем локальном компьютере или сервере разработки. Такой подход позволит избежать проблем с правами доступа и собственности при работе с файлами приложения как из контейнера, так и с хоста, на котором работает Docker.

Теперь создайте новый файл docker-compose.yml с помощью любого удобного текстового редактора (мы используем редактор nano):

nano docker-compose.yml

Скопируйте в этот файл следующие строки и не забудьте заменить выделенные значения соответствующими данными:

version: "3.7"
services:
app:
build:
args:
user: 8host
uid: 1000
context: ./
dockerfile: Dockerfile
image: landing-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- landing
networks:
landing:
driver: bridge

Сохраните и закройте файл. Если вы используете nano, нажмите Ctrl+X, а затем Y и Enter для подтверждения.

После этого мы создадим файл Dockerfile, на который ссылается наш файл docker-compose.yml; он настроит пользовательский образ для сервиса app:

nano Dockerfile

Этот Dockerfile будет основан на стандартном образе Docker, php:7.4-fpm. Он использует переменные user и uid для создания нового пользователя, способного запускать команды Artisan и Composer. Кроме того, он установит несколько зависимостей PHP, необходимых Laravel, и исполняемый файл Composer.

Скопируйте следующие строки и вставьте их в свой Dockerfile:

FROM php:7.4-fpm
# аргументы, определенные в docker-compose.yml
ARG user
ARG uid
# установка зависимостей
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# чистка кэша
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# установка расширений PHP
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# получение последней версии Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# создание системного пользователя для запуска команд Composer и Artisan
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
# создание рабочего каталога
WORKDIR /var/www
USER $user

Сохраните и закройте файл, когда закончите редактирование, после чего вы можете обновить свою среду с помощью этой команды:

docker-compose up -d

Эта команда запустит Docker Compose в «detached mode» (на это указывает флаг –d), что означает, что он будет работать в фоновом режиме. При первом запуске среды с пользовательским образом Docker Compose автоматически соберет образ, прежде чем создавать необходимые контейнеры. На это может уйти некоторое время. Вы увидите примерно такой результат:

Creating network "landing-laravel_landing" with driver "bridge"
Building app
Step 1/11 : FROM php:7.4-fpm
---> fa37bd6db22a
...
Step 10/11 : WORKDIR /var/www
---> Using cache
---> 769afd5d44d8
Step 11/11 : USER $user
---> Using cache
---> 841eb5852b69
Successfully built 841eb5852b69
Successfully tagged landing-app:latest
WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating landing-laravel_app_1 ... done

Чтобы убедиться, что среда запустилась, введите команду:

docker-compose ps
Name                    Command              State    Ports
------------------------------------------------------------------------
landing-laravel_app_1   docker-php-entrypoint php-fpm   Up      9000/tcp

Когда сервис app запущен, вы можете запустить Composer, – инструмент управления зависимостями PHP, – чтобы загрузить новое приложение Laravel. Мы используем команду docker compose exec для отправления команд сервису app, где установлен PHP.

Следующая команда с помощью Docker Compose выполнит команду composer create-project, что запустит новую установку Laravel на основе пакета laravel/laravel:

docker-compose exec app composer create-project laravel/laravel --prefer-dist application
Creating a "laravel/laravel" project at "./application"
Installing laravel/laravel (v8.4.0)
- Downloading laravel/laravel (v8.4.0)
- Installing laravel/laravel (v8.4.0): Extracting archive
Created project in /var/www/application
> @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
Updating dependencies
Lock file operations: 104 installs, 0 updates, 0 removals

Package manifest generated successfully.
71 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan key:generate --ansi
Application key set successfully.

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

Скопируйте файлы приложения в тот каталог, в котором находится файл docker-compose.yml, чтобы поделиться переменными среды Laravel с Docker Compose. После этого можно будет удалить каталог application, созданный Composer:

cp -rT application .
rm -rfv application

Итак, приложение запущено, но работа еще не окончена. Сейчас нам нужно включить пару сервисов в файл Docker Compose, чтобы иметь доступ к приложению из браузера. Сервис nginx будет обслуживать приложение с помощью веб-сервера Nginx, а сервис db создаст базу данных MySQL для хранения данных нашего приложения.

Во-первых, отключите свою среду с помощью этой команды:

docker-compose down
Stopping landing-laravel_app_1 ... done
Removing landing-laravel_app_1 ... done
Removing network landing-laravel_landing

Она удалит все контейнеры и сети, связанные с этой средой.

Во-вторых, мы должны отредактировать файл docker-compose.yml и добавить в него новые сервисы. Но прежде чем сделать это, создайте новый каталог, чтобы поделиться конфигурационными файлами с контейнерами. Это позволит правильно настроить Nginx для работы с PHP-приложением Laravel.

mkdir -p docker-compose/nginx

Создайте новый файл по имени landing-laravel.conf, где будет храниться пользовательский блок server для Nginx. Позже мы настроим том для совместного использования этого файла внутри контейнера nginx.

Откройте новый конфигурационный файл Nginx:

nano docker-compose/nginx/landing-laravel.conf

Следующий блок server настраивает Nginx для обработки кода PHP и обслуживания приложения Laravel с помощью внешнего сервиса (app). Скопируйте этот блок и вставьте его в свой конфигурационный файл 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 ~ \.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;
}
}

Сохраните и закройте файл.

Затем откройте файл docker-compose.yml:

nano docker-compose.yml

Добавьте в него следующую конфигурацию для сервиса nginx на том же уровне, что и ранее настроенный сервис app. Это создаст новый сервис на основе образа nginx:alpine, после чего все запросы на порт 8000 хоста, на котором работает Docker, будут перенаправлены на порт 80 контейнера сервиса. Мы предоставим общий доступ как к файлам приложения, так и к новому тому, содержащему конфигурационный файл Nginx для приложения Laravel:

nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d/
networks:
- landing

Затем добавьте в файл следующий блок конфигурации для сервиса db. Этот блок создаст сервис на основе стандартного образа MySQL 8 и извлечет значения, определенные в файле среды Laravel, чтобы затем настроить доступ к базе данных. Вот этот блок:

db:
image: mysql:8
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
networks:
- landing

В результате обновленный файл docker-compose.yml, должен выглядеть так:

version: "3.7"
services:
app:
build:
args:
user: 8host
uid: 1000
context: ./
dockerfile: Dockerfile
image: landing-app
restart: unless-stopped
working_dir: /var/www/
volumes:
- ./:/var/www
networks:
- landing
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- 8000:80
volumes:
- ./:/var/www
- ./docker-compose/nginx:/etc/nginx/conf.d/
networks:
- landing
db:
image: mysql:8
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_USER: ${DB_USERNAME}
networks:
- landing
networks:
landing:
driver: bridge

Примечание: За более подробной информацией о контейнерных средах Laravel, общих томах и сетях обратитесь к руководству по установке Laravel с помощью Docker Compose в Ubuntu 20.04.

Сохраните и закройте файл, когда закончите редактирование. Обновите файл .env и направьте конфигурацию хоста БД MySQL на тот хост, на котором будет работать сервис MySQL по имени db:

nano .env

Файл .env, который автоматически создается инструментом Composer при установке, содержит некоторые стандартные значения, которые вы, возможно, захотите изменить. Например, это могут быть параметры APP_NAME и APP_URL. Переменную базы данных DB_HOST нужно изменить и указать в ней сервис, который будет запускать MySQL. Вы можете ссылаться на БД по имени сервиса, которое определено в файле docker-compose.yml. В нашем примере мы использовали имя сервиса db, следовательно, БД будет доступна в контейнерной сети как хост db.

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

APP_NAME=LandingLaravel
APP_ENV=local
APP_KEY=base64:ffYPNP8kPeQDf8gE/qh3kWjk59p6gFY66kCKhhKUa2w=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=landing-db
DB_USERNAME=landing-user
DB_PASSWORD=dev-password
...

Изменять другие разделы этого файла не нужно, но если хотите, вы можете настроить его в соответствии с вашими требованиями.

Сохраните и закройте файл, когда закончите редактировать его.

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

docker-compose up -d
Creating network "landing-laravel_landing" with driver "bridge"
Creating landing-laravel_app_1   ... done
Creating landing-laravel_db_1    ... done
Creating landing-laravel_nginx_1 ... done

После полной настройки среды вы можете открыть браузер и ввести localhost или IP-адрес вашего удаленного сервера и порт 8000:

http://localhost:8000

Если все работает правильно, вы увидите приветственную страницу Laravel со ссылками на документацию, новости и т.п.

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