
Вот готовая конфигурация, скрипт развертывания и подробные инструкции для Ubuntu 26.04 и локальной разработки на macOS.
Создайте единую директорию для инфраструктуры сервера (например, /opt/webserver):
/opt/webserver/
├── docker-compose.yml
├── nginx/
│ ├── nginx.conf
│ └── conf.d/
│ ├── app1.conf
│ ├── app2.conf
│ └── app3.conf
└── mysql/
└── init.sql (опционально)
docker-compose.ymlДля базы данных используется MySQL 8.4 LTS (актуальная версия с долгосрочной поддержкой).
services:
# 1. Nginx — единая точка входа (роутер)
nginx:
image: nginx:1.26-alpine
container_name: global_nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
# Проброс публичных папок сайтов для раздачи статики
- /var/www/site1/public:/var/www/site1/public:ro
- /var/www/site2/public:/var/www/site2/public:ro
- /var/www/site3/public:/var/www/site3/public:ro
networks:
- app_network
depends_on:
- site1
- site2
- site3
# 2. PHP-FPM 8.4 — Сайт 1
site1:
image: php:8.4-fpm-alpine
container_name: site1_app
restart: always
volumes:
- /var/www/site1:/var/www/site1
networks:
- app_network
# 3. PHP-FPM 8.4 — Сайт 2
site2:
image: php:8.4-fpm-alpine
container_name: site2_app
restart: always
volumes:
- /var/www/site2:/var/www/site2
networks:
- app_network
# 4. PHP-FPM 8.4 — Сайт 3
site3:
image: php:8.4-fpm-alpine
container_name: site3_app
restart: always
volumes:
- /var/www/site3:/var/www/site3
networks:
- app_network
# 5. MySQL 8.4 LTS
mysql:
image: mysql:8.4
container_name: global_mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: "CHANGE_ME_ROOT_PASSWORD"
volumes:
- mysql_data:/var/lib/mysql
networks:
- app_network
networks:
app_network:
driver: bridge
volumes:
mysql_data:
nginx/nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '\(remote_addr -\)remote_user [\(time_local] "\)request" '
'\(status\)body_bytes_sent "$http_referer" '
'"\(http_user_agent" "\)http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*.conf;
}
nginx/conf.d/Создайте по одному файлу на каждый сайт (измените доменные имена):
nginx/conf.d/app1.conf
server {
listen 80;
server_name site1.com www.site1.com;
root /var/www/site1/public;
index index.php index.html;
location / {
try_files \(uri\)uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass site1:9000; # Имя сервиса из docker-compose
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/site1/public$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
(Аналогично создайте app2.conf со значением fastcgi_pass site2:9000; и app3.conf со значением fastcgi_pass site3:9000;).
Создайте файл setup.sh на сервере:
#!/bin/bash set -e echo "=== Обновление системы ===" sudo apt update && sudo apt upgrade -y echo "=== Установка необходимых утилит ===" sudo apt install -y ca-certificates curl gnupg lsb-release git echo "=== Установка Docker и Docker Compose ===" sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu/ \ \((. /etc/os-release && echo "\)VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin echo "=== Настройка прав Docker для текущего пользователя ===" sudo usermod -aG docker $USER echo "=== Подготовка директорий для проектов ===" sudo mkdir -p /var/www/site1 /var/www/site2 /var/www/site3 sudo chown -R \(USER:\)USER /var/www echo "=== Готово! Перезагрузите сессию (exit) или выполните 'newgrp docker' ==="
Запуск скрипта:
chmod +x setup.sh ./setup.sh newgrp docker
Для обеспечения гибкости и удобства разработки в каждый репозиторий сайта целесообразно добавить локальный Dockerfile для сбора расширений PHP (например, pdo_mysql, gd, zip).
Dockerfile в корень репозитория каждого проектаСоздайте файл Dockerfile в корне сайта:
FROM php:8.4-fpm-alpine
# Установка необходимых системных зависимостей и расширений PHP
RUN apk add --no-cache \
libpng-dev \
libzip-dev \
zip \
unzip \
git
RUN docker-php-ext-install pdo_mysql gd zip
WORKDIR /var/www/html
.gitignore проектаУбедитесь, что в .gitignore репозитория сайта внесены локальные конфигурации, чтоб не затереть файлы сервера:
/vendor .env .DS_Store
Если вы используете собственные Dockerfile в проектах, в основном docker-compose.yml измените блоки сервисов:
site1:
build:
context: /var/www/site1
dockerfile: Dockerfile
container_name: site1_app
restart: always
volumes:
- /var/www/site1:/var/www/html
networks:
- app_network
На macOS рекомендуется использовать Docker Desktop или OrbStack.
docker-compose.yml в проектеДля изолированной работы над одним сайтом создайте в его репозитории локальный docker-compose.override.yml или docker-compose.local.yml:
services:
app:
build: .
container_name: my_app_local
volumes:
- .:/var/www/html
environment:
DB_HOST: db
DB_DATABASE: app_db
DB_USERNAME: root
DB_PASSWORD: secret_password
web:
image: nginx:1.26-alpine
container_name: my_web_local
ports:
- "8080:80"
volumes:
- .:/var/www/html:ro
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app
db:
image: mysql:8.4
container_name: my_db_local
environment:
MYSQL_ROOT_PASSWORD: secret_password
MYSQL_DATABASE: app_db
ports:
- "3306:3306"
Шаг 2: Создание локального конфига Nginx (docker/nginx.conf)
server {
listen 80;
root /var/www/html/public; # или /var/www/html в зависимости от фреймворка
index index.php index.html;
location / {
try_files \(uri\)uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;
include fastcgi_params;
}
}
Запуск окружения:
docker compose up -d
Выполнение команд внутри PHP-контейнера (Composer, Artisan, Migrations):
docker compose exec app composer install docker compose exec app php artisan migrate
Подключение к базе данных в контейнере через локальный GUI (TablePlus, DBeaver, Datagrip):
Host: 127.0.0.1 или localhost
Port: 3306
User: root
Password: secret_password
Выполните setup.sh.
Клонируйте ваши проекты в /var/www/site1, /var/www/site2, /var/www/site3.
Перейдите в директорию с основным docker-compose.yml (/opt/webserver).
Запустите стек:
docker compose up -d --build
5. База данных MySQL будет доступна для всех PHP-контейнеров по хост-имени mysql и порту 3306.
Друзья! Приглашаем вас к обсуждению. Если у вас есть своё мнение, напишите нам в комментарии.