Битрикс — не самая дружелюбная к Docker система: он рассчитан на конкретную серверную конфигурацию, тянет за собой десятки тысяч файлов и придирчив к настройкам MySQL. Поэтому большинство инструкций из интернета доводят до состояния «контейнеры поднялись», а дальше начинается вечер с непонятными ошибками установки.
Ниже — конфигурация, которую я довёл до рабочего состояния на нескольких проектах, вместе с объяснением тех мест, где связка ломается по умолчанию.
Зачем Docker для Битрикс-разработки
Если вы работаете с несколькими проектами на 1С-Битрикс, то наверняка сталкивались с проблемой: у одного клиента PHP 7.4, у другого — 8.1, у третьего — специфические настройки MySQL. Держать всё это на локальной машине — боль.
Docker решает эту проблему — каждый проект живёт в изолированном контейнере со своими версиями PHP, MySQL и настройками. Переключаться между проектами — дело одной команды.
Что получите в итоге: Готовое окружение с nginx, PHP-FPM (любой версии), MySQL 8, Redis, xdebug и автоматическим бэкапом базы.
Структура проекта
Начнём со структуры директорий. Я использую такую организацию для всех Битрикс-проектов:
project/
├── docker/
│ ├── nginx/
│ │ └── default.conf
│ ├── php/
│ │ ├── Dockerfile
│ │ └── php.ini
│ └── mysql/
│ └── my.cnf
├── src/ # Корень Битрикс
│ ├── bitrix/
│ ├── local/
│ └── index.php
├── docker-compose.yml
└── Makefile # Удобные командыКонфигурация docker-compose.yml
Главный файл конфигурации. Определяем все сервисы: веб-сервер, PHP, базу данных и кэш.
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./src:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
build:
context: ./docker/php
dockerfile: Dockerfile
volumes:
- ./src:/var/www/html
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
environment:
# trigger вместо постоянно включённой отладки: xdebug стартует
# только при явном запросе из IDE и не замедляет обычную работу
XDEBUG_MODE: debug,develop
XDEBUG_CONFIG: "client_host=host.docker.internal start_with_request=trigger"
mysql:
image: mysql:8.0
# Битриксу нужен нестрогий sql_mode, иначе часть запросов ядра
# падает на ONLY_FULL_GROUP_BY и STRICT_TRANS_TABLES
command: >
--sql-mode=""
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
ports:
# Слушаем только localhost: иначе база проекта торчит наружу,
# а порт конфликтует с соседними проектами
- "127.0.0.1:3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: bitrix
volumes:
- mysql_data:/var/lib/mysql
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
redis:
image: redis:alpine
ports:
- "127.0.0.1:6379:6379"
volumes:
mysql_data:Два места, где связка Битрикс + MySQL 8 ломается прямо на старте.
sql_mode по умолчанию. В MySQL 8 включены ONLY_FULL_GROUP_BY и STRICT_TRANS_TABLES, а ядро Битрикса на них не рассчитано: получите ошибки в самых неожиданных местах — от админки каталога до оформления заказа. Отсюда --sql-mode="" в команде запуска.
Плагин аутентификации. MySQL 8 по умолчанию использует caching_sha2_password. Современные сборки PHP с ним работают, но если проект живёт на PHP 7.x со старым mysqlnd, соединение не установится — сообщение при этом будет невнятным. В таком случае добавьте --default-authentication-plugin=mysql_native_password.
Обе проблемы выглядят как «Битрикс не ставится» или «сайт белый», и найти их без подсказки стоит вечера.
Ключ version в docker-compose.yml больше не нужен — Compose v2 его игнорирует и предупреждает об устаревшей схеме. В новых файлах начинайте сразу с services.
Dockerfile для PHP
Битрикс требует множество PHP-расширений. Собираем свой образ на базе официального PHP-FPM:
FROM php:8.1-fpm
# Системные зависимости
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libzip-dev \
libicu-dev \
&& rm -rf /var/lib/apt/lists/*
# PHP-расширения для Битрикс
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
mysqli \
pdo_mysql \
opcache \
intl \
zip \
exif
# Redis
RUN pecl install redis && docker-php-ext-enable redis
# Xdebug (только для разработки!)
RUN pecl install xdebug && docker-php-ext-enable xdebug
WORKDIR /var/www/htmlВажно: Не используйте xdebug на продакшене — он сильно замедляет выполнение. Создайте отдельный Dockerfile.prod без отладчика.
Конфигурация nginx
Стандартная конфигурация для Битрикс с правильной обработкой URL-rewrite:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php;
# Битрикс urlrewrite
location / {
try_files $uri $uri/ @bitrix;
}
location @bitrix {
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/bitrix/urlrewrite.php;
}
location ~ \.php$ {
# Без try_files nginx отдаёт в PHP-FPM любой запрос, оканчивающийся
# на .php, включая несуществующие пути вида /upload/pic.jpg/x.php
try_files $uri =404;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# Запрет доступа к служебным файлам
location ~ /\.(ht|git) {
deny all;
}
}Makefile для удобства
Чтобы не запоминать длинные команды Docker, создаём Makefile:
up:
docker-compose up -d
down:
docker-compose down
restart:
docker-compose restart
logs:
docker-compose logs -f
shell:
docker-compose exec php bash
mysql:
docker-compose exec mysql mysql -uroot -proot bitrix
# Бэкап базы. Флаг -T обязателен: без него docker-compose выделяет
# псевдотерминал и дописывает в поток \r, ломая дамп
backup:
docker-compose exec -T mysql mysqldump -uroot -proot bitrix > backup.sql
# Восстановление
restore:
docker-compose exec -T mysql mysql -uroot -proot bitrix < backup.sqlТеперь запуск проекта — это просто make up, а вход в консоль PHP — make shell.
Частые проблемы
Права на файлы
Самая частая проблема — Битрикс не может писать в директории. Корень её в том, что внутри контейнера PHP работает от www-data с UID 82 или 33, а файлы на хосте принадлежат вам с UID 501 или 1000. Правильное решение — совместить эти идентификаторы:
# В Dockerfile: подгоняем UID www-data под пользователя хоста
ARG UID=1000
RUN usermod -u ${UID} www-data && groupmod -g ${UID} www-data# В docker-compose.yml передаём UID хоста при сборке
php:
build:
context: ./docker/php
args:
UID: ${UID:-1000}chmod -R 777 — не решение, а способ отложить проблему. Он работает, поэтому встречается в каждой второй инструкции, но приучает к правам, которые нельзя переносить на боевой сервер, — а перенести конфиг «как на локалке» рано или поздно попробуют. На macOS с Docker Desktop проблема прав вообще не возникает из-за особенностей монтирования, поэтому команда просто ничего не решает; на Linux она даёт всем пользователям системы право писать в код вашего проекта.
Память и таймауты
Битрикс любит память. В php.ini выставляем:
memory_limit = 512M
max_execution_time = 300
post_max_size = 100M
upload_max_filesize = 100M
max_input_vars = 10000Чего это окружение не даёт
Важно понимать границы: описанная конфигурация — окружение для разработки, и она намеренно отличается от боевой.
Это не BitrixVM. Продакшен-сервер большинства проектов — виртуальная машина от 1С-Битрикс со своей связкой nginx + Apache, своими путями и своими настройками PHP. Различия в конфигурации регулярно дают «на локалке работает, на проде нет»: разное поведение .htaccess, разные пути к сессиям, разный набор расширений. Если проект едет на BitrixVM, полезно хотя бы сверить phpinfo() в обеих средах.
Производительность на macOS и Windows будет хуже, чем ожидаете. Битрикс — это десятки тысяч файлов, и монтирование исходников через bind mount упирается в файловую систему. Если админка открывается неприлично долго, смотрите в сторону нативных томов для bitrix/ или включённого VirtioFS.
docker-compose exec mysql mysqldump — не стратегия резервного копирования. Для локальной разработки достаточно, но команда в Makefile не заменяет ни проверки восстановления, ни бэкапа upload/.
Итоги
Docker для Битрикс-разработки решает ровно одну, но очень назойливую проблему: несколько проектов с несовместимыми требованиями к окружению на одной машине. Переключение между версиями PHP становится вопросом одной строки в Dockerfile, а не переустановки половины системы.
Что стоит настроить сразу, а не когда прижмёт: нестрогий sql_mode у MySQL, xdebug в режиме trigger, совпадение UID внутри и снаружи контейнера, порты баз только на 127.0.0.1. Каждый из этих пунктов иначе всплывёт в самый неудобный момент и потратит вечер.
Весь код из статьи доступен в репозитории на GitHub.
Комментарии
Система комментариев скоро будет подключена. А пока вы можете написать мне в Telegram или на email.