Введение
Docker упрощает запуск и развертывание приложений, основой его работы являются образы и виртуальные контейнеры.
Разверните свежее приложение Laravel и настройте его для базовой работы.
Для запуска его в виртуальном контейнере нам потребуется установленный Docker на рабочей машине.
После его установки приступим к настройке.
Dockerfile
Docker позволяет задавать описание настройки среды внутри отдельных контейнеров с помощью файла Dockerfile.
Создайте файл Dockerfile в корне проекта laravel. Данная конфигурация будет использоваться для создания образа приложения, установки всех необходимых зависимостей приложения.
Пример Dockerfile для локальной разработки проекта:
FROM php:7.4-fpm
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
libonig-dev \
locales \
nodejs \
npm \
zlib1g-dev \
libicu-dev \
supervisor \
g++ \
--no-install-recommends \
&& rm -r /var/lib/apt/lists/* \
&& sed -i 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/' /etc/locale.gen \
&& locale-gen
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl intl bcmath gd
RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install NPM
RUN curl https://www.npmjs.com/install.sh | sh
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
Данная конфигурация не потребует много времени на выполнение, но так же и не сделает вещи, которые необходимы для стабильной работы в режиме production.
Поэтому так же рассмотрим вторую версию.
Пример Dockerfile для развертывания проекта на боевом сервере:
FROM php:7.4-fpm
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
wget \
cmake \
gcc \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
libonig-dev \
locales \
nodejs \
npm \
zlib1g-dev \
libicu-dev \
supervisor \
g++ \
--no-install-recommends \
&& rm -r /var/lib/apt/lists/* \
&& sed -i 's/# ru_RU.UTF-8 UTF-8/ru_RU.UTF-8 UTF-8/' /etc/locale.gen \
&& locale-gen
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl intl bcmath gd
RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Install NPM
RUN curl https://www.npmjs.com/install.sh | sh
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy existing application directory permissions
COPY --chown=www:www . /var/www
RUN npm install && \
composer install && \
composer dumpautoload -o
#laravel cache and optimization
RUN php artisan optimize && \
php artisan route:cache && \
php artisan config:cache && \
php artisan scribe:generate --force
#building frontend assets
RUN npm run development
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
Данная конфигурация смонтирует образ из базового Docker образа php:7.4-fpm.
Так же установятся указанные пакеты wget, cmake, gcc и прочие. Команда WORKDIR укажет рабочий каталог нашего приложения.
Директива RUN помогает описывать команды, которые должны быть исполнены для установки и настройки различных параметров.
Контейнеры в Docker по умолчанию запускаются с привилегиями root, поэтому мы создаем пользователя www с ограниченными правами и указываем запуск контейнера от его имени.
Команда EXPOSE открывает порт в контейнере для php-fpm, а CMD указывает команду для запуска сервера.
Docker-compose
Как Dockerfile будет готов, создайте файл docker-compose.yml с инструкциями для запуска контейнера по образу Dockerfile.
Пример docker-compose.yml:
version: '3.9'
services:
php:
build:
context: .
dockerfile: Dockerfile
image: "${ENV}-laravel-app:latest"
container_name: "${ENV}-laravel-app"
volumes:
- laravel-app-volume:/var/www
- ./storage:/var/www/storage:rw
command: /bin/bash -c "php artisan migrate --force && php-fpm"
links:
- mysql
mysql:
image: mysql:latest
container_name: "${ENV}-laravel-mysql"
expose:
- "3306"
environment:
- MYSQL_ROOT_PASSWORD
- MYSQL_DATABASE
- MYSQL_USER
- MYSQL_PASSWORD
volumes:
- ./mysql:/var/lib/mysql
nginx:
image: nginx:latest
container_name: "${ENV}-laravel-nginx"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- laravel-app-volume:/var/www/
- ./storage/app/public:/var/www/public/storage:ro
- ./nginx/logs:/var/log/nginx/
environment:
- PROJECT_URL
- PROJECT_ROOT
- DIRTY_HACK
- VIRTUAL_HOST
- VIRTUAL_PORT
- LETSENCRYPT_HOST
- LETSENCRYPT_EMAIL
expose:
- $VIRTUAL_PORT
ports:
- $VIRTUAL_PORT:$VIRTUAL_PORT
command: /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/my.conf && nginx -g 'daemon off;'"
links:
- php
volumes:
laravel-app-volume:
name: "${ENV}-laravel-app-volume"
external: false
В приведенном коде задаются базовые элементы, запускаемые внутри контейнеров. Так это сервис nginx, mysql, php и прочее.
В каждом блоке требуется указать необходимую информацию для корректной работы сервисов. Их имена, название образов, из которых будут созданы, конфигурации, а так же связи между разделами контейнеров.
Context параметра build в блоке php сообщает о том, какой каталог относительно docker-compose.yml будет использован как рабочая директория проекта. То есть мы указываем путь до нашего приложения.
Dockerfile указывает название Dockerfile'а, который будет использован для создания образа. Image используется для определения образа для запуска контейнера, если такой dockerfile не определен или образ по нему уже был смонтирован.
Containername задает имя создаваемого контейнера. Command позволяет запустить указанные команда после запуска контейнера, а links используется для указания алиасов, посредством которых контейнеры могут свободно общаться между друг-другом.
С помощью environment определяются переменные из файла .env, которые будут использоваться при запуске контейнеров.
И, наконец, volumes необходим для создания тома, который обеспечит постоянное сохранения файлов, даже если работа контейнера будет остановлена. А так же указания монтируемого образа, который свяжет наши конфигурационные файлы с сервисами контейнеров.
.ENV
Для работы с динамическими данными, а так же данными, которые должны храниться на сервере и не использоваться внутри Git репозиториев используются переменные из файла .env.
Его пример:
ENV=dev
MYSQL_ROOT_PASSWORD=password
MYSQL_DATABASE=laravel_database
MYSQL_USER=laravel_user
MYSQL_PASSWORD=laravel_password
PROJECT_URL=localhost
PROJECT_ROOT=/var/www/public
DIRTY_HACK=$
VIRTUAL_HOST=localhost
VIRTUAL_PORT=8000
Конфигурация nginx
Так же в docker-compose.yml используются файлы для конфигурации ngnix сервиса.
Создайте в проекте папку nginx и подпапку conf.d с двумя файлами: laravel-conf.template и laravel.conf.
В первом файле мы опишем базовую структуру конфигурации ngnix и использованием переменных из .env, после чего во время создания контейнера сервис создаст файл с итоговой конфигурацией и будет его использовать для своей работы.
Пример laravel-conf.template:
server {
listen ${VIRTUAL_PORT};
client_max_body_size 100M;
server_name ${PROJECT_URL};
access_log /var/log/nginx/${PROJECT_URL}-access.log;
error_log /var/log/nginx/${PROJECT_URL}-error.log;
root ${PROJECT_ROOT};
index index.php index.html index.htm;
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|pdf|ppt|txt|bmp|rtf|js)$ {
#access_log off;
#expirs 3d;
#add_header Cache-Control "public, max-age=259200";
add_header Cache-Control "s-maxage:259200";
}
location / {
try_files ${DIRTY_HACK}uri ${DIRTY_HACK}uri/ /index.php${DIRTY_HACK}is_args${DIRTY_HACK}args;
}
location ~ \.php$ {
fastcgi_param HTTPS on;
fastcgi_param DEVEL_SITE 0;
try_files ${DIRTY_HACK}uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME ${DIRTY_HACK}document_root${DIRTY_HACK}fastcgi_script_name;
include fastcgi_params;
}
}
Заключение
Таким образом мы подготовили все необходимое для создания образов и контейнеров.
Выполните команду:
docker-compose up -d
Docker посредством содержимого docker-compose.yml создаст контейнеры из указанных в файле образов, после чего автоматически их запустит.
Флаг -d преобразует процесс в демона, с которым контейнеры остаются запущенными в фоновом режиме.
Для остановки контейнеров возможно использование команды:
docker-compose down -v