Привет!
Чтобы запустить локальный Laravel сайт в Docker на базе PHP-FPM + Nginx совсем не обязательно досконально изучать или знать эти технологии. Сейчас покажу все необходимые куски кода, которые помогут тебе запустить Laravel сайт на домене для локальной разработки.
Существуют множество других способов запустить Laravel в Docker, например Laravel Sail. Однако я предпочитаю все держать под контролем, поэтому развернул собственную систему Docker-контейнеров, которыми полностью могу управлять. Система достаточно проста и примитивна. Сейчас покажу как у меня все устроено
Внимание! Статья рассчитана на пользователей Ubuntu (Linux). Если ты работаешь на Windows, то рекомендую установить WSL и затем воспользоваться этой инструкцией. Ссылка — WSL для WEB-разработчика
Laravel сайт на локальном домене
Первое, что мне кажется нужным и удобным — это использовать “человекопонятный” локальный домен для разработки. Не какой ни будь http://localhost:8080, а http://my-top-client-project.docker. Это придает удобства в процессе работы. При необходимости можно запустить несколько сайтов на индивидуальных доменах для решения различных задач — смотри мою статью “Несколько доменов (хостов) в Docker на одном сервере и IP-адресе”.
И так, первое что необходимо — это добавить Reverse Proxy Container в нашу систем. На моей локальной машине существует следующая схема расположения файлов и папок.
В домашней папке существует директория server. То есть путь выглядит следующим образом:
/home/UserName/server
В этой директории я храню все содержимое, что касается моих локальных сайтов. Для каждого сайта внутри директории server у меня имеются соответствующие директории.
/home/UserName/server/my-top-client-project.docker
/home/UserName/server/subdomen.siteForImportantClient.docker
/home/UserName/server/subdomen.myPetProject.local
Полагаю тут нечего дополнительно объяснять.
Запускаем Reverse Proxy для обслуживания уникальных локальных доменов
Также внутри директории Server у меня хранится еще одна папочка, которая называется proxy, внутри этой папки хранится только один документ:
~/server/proxy/docker-compose.yml
Code language: JavaScript (javascript)
Содержимое файла docker-compose.yml следующее:
version: '3.0'
services:
proxy:
image: jwilder/nginx-proxy # используем внешний image
container_name: proxy_proxy # задаем конкретное имя контейнеру - будет использоваться в дальнейшем
restart: always # всегда перезапускаем контейнер
privileged: true
ports:
- 80:80 # прокидываем порт 80 для обработки http запросов
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
- proxy # указываем, с какой внутренней сетью будет работать контейнер
networks: # конфигурируем сеть
proxy: # указываем имя сети
driver: bridge # указываем драйвер
Code language: PHP (php)
Теперь переходим в папку прокси и запускаем Docker контейнер:
cd ~/server/proxy/
docker-compose up -d
Code language: JavaScript (javascript)
Устанавливаем и запускаем Laravel в Docker
После того, как запустили Nginx в режиме Reverse Proxy, Выполняем следующее. Создаем папку проекта в папке сервера:
mkdir ~/server/my-top-client-project.docker
mkdir ~/server/my-top-client-project.docker/docker
Code language: JavaScript (javascript)
Чтобы запустить laravel на локальном домене, необходимо добавить домен в файл «/etc/hosts». Для пользователей WSL необходимо добавить в файл «C:\Windows\System32\drivers\etc\hosts» от имени администратора
127.0.0.1 my-top-client-project.docker
127.0.0.1 phpmyadmin.my-top-client-project.docker
Code language: CSS (css)
Laravel в Docker Compose
Чтобы объединить PHP + Nginx + MySQL в единую систему и запускать их одной командой, будем использовать Docker Compose. Файл ~/server/my-top-client-project.docker/docker/docker-compose.yml
будет иметь следующее содержание:
version: '3.0'
services:
mtcp_nginx:
image: nginx
container_name: mtcp_docker_nginx
environment:
- VIRTUAL_HOST=my-top-client-project.docker
volumes:
- ./nginx/logs:/var/log/nginx/ # пробрасываем папку для логов
- ./nginx/conf.d/default.nginx:/etc/nginx/conf.d/default.conf # пробрасываем конфиг nginx
- ./../laravel/:/var/www/ # пробрасываем содержимое проекта в контейнер
networks:
- frontend # добавляем сеть для проксирования запросов
- backend # добавляем внутреннюю сеть для объединения контейнеров
mtcp_php:
container_name: "mtcp_docker_php"
build:
args:
user: wwwdata
uid: 1000
context: ./php
volumes:
- ./php/local.ini:/usr/local/etc/php/php.ini
- ./../laravel/:/var/www/
networks:
- frontend # добавляем сеть для проксирования запросов
- backend # добавляем внутреннюю сеть для объединения контейнеров
mtcp_mysql:
image: mysql:5.7
container_name: mtcp_docker_mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: mtcp
MYSQL_PASSWORD: mtcp
MYSQL_DATABASE: mtcp
volumes:
- ./mysql/data:/var/lib/mysql # подключаем папку для хранения данных MySQL
networks:
- backend # добавляем внутреннюю сеть для объединения контейнеров
mtcp_phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: mtcp_docker_phpmyadmin
environment:
- VIRTUAL_HOST=phpmyadmin.my-top-client-project.docker # указываем хост, на котором будет PhpMyAdmin
- PMA_HOST=mtcp_mysql
- PMA_USER=root
- PMA_PASSWORD=root
networks:
- frontend # добавляем сеть для проксирования запросов
- backend # добавляем внутреннюю сеть для объединения контейнеров
networks:
frontend: # конфигурируем сеть, которую создали ранее в reverse-proxy контейнере
external:
name: proxy_proxy # указываем имя сети, которое соответствует контейнеру в reverse-proxy
backend: # создаем внутреннюю сеть для объединения контейнеров
Code language: PHP (php)
Подготавливаем контейнер с PHP в Docker
Файл ~/server/my-top-client-project.docker/docker/php/Dockerfile
будет иметь следующее содержание:
FROM php:7.4-fpm
# Arguments defined in docker-compose.yml
ARG user
ARG uid
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
redis-server
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install pecl PHP xdebug
#RUN pecl install xdebug
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath
# по необходимости устанавливаем Redis
#RUN pecl install redis && docker-php-ext-enable redis
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
chown -R $user:$user /home/$user
# Set working directory
WORKDIR /var/www
USER $user
Code language: PHP (php)
Файл local.ini
позволит конфигурировать PHP в Docker. Файл ~/server/my-top-client-project.docker/docker/php/local.ini
будет иметь следующее содержание:
upload_max_filesize=200M
post_max_size=200M
Подготавливаем контейнер с Nginx в Docker
Файл ~/server/my-top-client-project.docker/docker/nginx/conf.d/default.nginx
будет иметь следующее содержание. Этот файл позволит конфигурировать Nginx для обработки запросов к сайту.
server {
listen 80; # слушаем порт 80 для обработки http запросов
listen [::]:80;
server_name my-top-client-project.docker;
root /var/www/public; # указываем директорию в контейнере с файлом index.php
location / {
try_files $uri /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass mtcp_php:9000; # указываем имя контейнера с PHP и порт
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /\.ht {
deny all;
}
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/host.error.log;
}
Code language: PHP (php)
Запускаем все контейнеры
cd ~/server/my-top-client-project.docker/docker
docker-compose up -d
Code language: JavaScript (javascript)
При этом должна произойти загрузка необходимых образов из docker.hub и затем запуск docker контейнеров.
Если возникли ошибки — напиши в комментариях, попробуем разобраться. Если все прошло успешно, то необходимо добавить файлы Laravel в папку с проектом. Для этого выполним в терминале команду ниже, чтобы попасть в контейнер с php:
docker exec -it mtcp_docker_php bash
Будучи в контейнере запустим команду, которая позаимствована из документации:
cd /var/www/
composer create-project laravel/laravel:^8.0
Code language: JavaScript (javascript)
При запуске команды выше произойдет загрузка файлов Laravel в локальную папку.
После этого, если не было допущено ошибок, то по адресу http://my-top-client-project.docker должна открыться страничка с логотипом Laravel. Это означает, что нам удалось запустить Laravel в Docker с помощью Docker Compose.
P.S. Таким образом файлы фреймворка будут располагаться в папке Laravel. Если же необходимо, чтобы файлы располагались непосредственно в корне проекта, то можно просто перенести их в корень и немного поправить docker-compose.yml и просто убрать папку laravel из пути — ./../laravel/:/var/www/