БесплатноБесплатный аудит сайта и кода на 1С-Битрикс при заказе доработки или поддержки

Docker и контейнеризация 1С-Битрикс: dev-окружение, сборка и деплой

Контейнеризация 1С-Битрикс в Docker: сервисы nginx, php-fpm, mysql, memcached и push в отдельных контейнерах

«У меня локально работает» — фраза, из-за которой сорваны десятки релизов. Один разработчик собрал проект на PHP 8.1 с одним набором расширений, второй — на 7.4 из старого пакета, на бою крутится BitrixVM с третьей конфигурацией, и в итоге баг, который не воспроизводится ни у кого, кроме клиента. Docker решает ровно эту боль: окружение перестаёт быть свойством конкретной машины и становится кодом, который лежит в репозитории рядом с проектом и одинаково поднимается у всех.

Ниже — практический разбор контейнеризации 1С-Битрикс: из каких сервисов собрать стек, как написать Dockerfile и docker-compose, куда положить тома под /upload, ядро и базу, как не сломать права www-data, чем отличается dev-сборка от прод и как всё это подготовить к CI/CD. Это выжимка из наших проектов по разработке на 1С-Битрикс — без хайпа вокруг контейнеров, только то, что реально помогает командам.

Коротко

  • Docker превращает окружение в код: одинаковые PHP, расширения и версии сервисов у всей команды и на всех контурах.
  • Минимальный стек — nginx + php-fpm + mysql/percona, плюс memcached/redis под кэш и push-сервер под чат.
  • Постоянные данные (/upload, ядро, БД) выносим в тома; процесс php-fpm и владелец файлов — один пользователь www-data.
  • Настройки БД и кэша читаем из переменных окружения в .settings.php — один образ на dev, стейдж и прод.
  • Начинать проще с dev-окружения, а прод в контейнеры переносить вместе с настройкой CI/CD и деплоя.

Зачем контейнеризировать 1С-Битрикс

1С-Битрikс — платформа требовательная к окружению: конкретные версии PHP, набор расширений (mbstring, gd, mysqli, opcache, zip, xml), параметры opcache и памяти, правильно настроенный nginx с обработкой ЧПУ и композита. Собрать это вручную можно, но воспроизвести один в один на пяти машинах разработчиков и трёх серверах — задача, которая обычно проваливается. Контейнеризация делает окружение декларативным: вы описываете его один раз в Dockerfile и docker-compose, и дальше оно одинаково разворачивается где угодно.

Практическая ценность контейнеров для Битрикс-проекта складывается из нескольких вещей:

Важно понимать, что Docker не ускоряет сам Битрикс и не заменяет грамотную настройку кэша и базы. Он решает задачу воспроизводимости и управляемости окружения, а не производительности приложения как такового. Если проект тормозит из-за неоптимальных запросов или отсутствия композита, контейнеры этого не вылечат — они лишь сделают так, чтобы вы чинили одну и ту же проблему в одинаковых условиях у всех.

Важно: контейнеризация — это про инфраструктуру, а не про магию. Битрикс в Docker требует тех же расширений PHP, той же настройки opcache и той же дисциплины с кэшем, что и на классическом сервере. Разница в том, что теперь эта настройка зафиксирована в коде и повторяема.
nginx :80 / :443 php-fpm ядро Битрикс mysql / percona memcached / redis push-сервер Тома: /upload · /bitrix (ядро) · данные MySQL переживают пересоздание контейнеров
Схема: nginx принимает запросы и проксирует PHP на php-fpm, тот работает с базой, кэшем и push-сервером; постоянные данные вынесены в тома.

Docker против BitrixVM: что выбрать

BitrixVM (bitrix-env) — официальное преднастроенное окружение от 1С-Битрикс: виртуальная машина с готовым стеком nginx + Apache/php-fpm + MySQL + memcached + push-сервер и текстовым меню управления. Она закрывает большинство задач «из коробки» и не требует знания системного администрирования. Мы подробно разбирали её в отдельной статье про хостинг и инфраструктуру на BitrixVM. Docker решает ту же задачу окружения, но принципиально иначе — разбивая монолит ВМ на отдельные сервисы-контейнеры, описанные кодом.

Не стоит воспринимать выбор как «или-или навсегда». Многие команды используют BitrixVM на проде и Docker на разработке, а миграцию прода в контейнеры делают эволюционно. Но чтобы выбирать осознанно, полезно видеть отличия по ключевым осям:

КритерийBitrixVMDocker
Порог входаНизкий: меню, всё преднастроеноВыше: нужно собрать стек и понять сети/тома
ВоспроизводимостьРучная, через бэкап ВМПолная, окружение как код в репозитории
Версионирование окруженияНет из коробкиЕсть: Dockerfile под git
Изоляция проектов на машинеОдна ВМ — один стекМного проектов рядом в своих контейнерах
Официальная поддержкаДа, от 1С-БитриксНет, стек собираете сами
Путь к CI/CDЧерез доп. обвязкуЕстественный: собрал образ — выкатил
Обновление стека (PHP, MySQL)Через меню bitrix-envСтрока в Dockerfile + пересборка

Резюме простое. Если проект небольшой, команда одна и админить некому — BitrixVM даёт результат быстрее и с меньшими рисками. Если проектов много, в команде несколько разработчиков, нужен паритет окружений и вы движетесь к автоматическому деплою — Docker окупается за счёт повторяемости и управляемости, хотя и требует первоначальных вложений в настройку стека.

Совет: не переносите на прод в Docker то, что ещё не отработали на dev. Сначала соберите и обкатайте контейнерное dev-окружение, добейтесь, чтобы у всей команды всё поднималось одной командой, и только потом думайте о продакшене в контейнерах.

Из чего собрать окружение: сервисы стека

Контейнерное окружение для Битрикса — это набор сервисов, каждый в своём контейнере, соединённых внутренней сетью Docker. Минимальный работоспособный набор и типовые роли выглядят так:

К этому набору по мере надобности добавляют вспомогательные контейнеры: cron/агенты (об этом ниже отдельный раздел), mailhog или аналог для перехвата почты на dev, adminer/phpMyAdmin для работы с базой, sphinx/manticore если используется полнотекстовый поиск. Принцип один: один процесс — один контейнер, связь между ними по именам сервисов внутри сети compose.

СервисРоль в стекеЗа что отвечает
nginxВеб-сервер / проксиHTTP(S), статика, ЧПУ, композит, проксирование PHP
php-fpmПриложениеЯдро Битрикса, расширения, opcache
mysql / perconaХранилище данныхИнфоблоки, заказы, пользователи, настройки
memcached / redisКэшManaged-кэш, сессии, ускорение чтения
push (node)РеалтаймЧаты, уведомления, очередь сообщений
cron / agentsФоновые задачиАгенты Битрикса, обмены, регламентные задания

Dockerfile для php-fpm под Битрикс

Сердце сборки — образ php-fpm с нужными расширениями и настройками под Битрикс. За основу берут официальный образ php:8.x-fpm и доустанавливают то, что требует платформа. Битриксу нужны как минимум mysqli/pdo_mysql, mbstring, gd, zip, xml, opcache, а также корректная локаль и часовой пояс.

FROM php:8.2-fpm

# Системные пакеты для сборки расширений
RUN apt-get update && apt-get install -y --no-install-recommends \
    libfreetype6-dev libjpeg62-turbo-dev libpng-dev \
    libzip-dev libicu-dev libxml2-dev \
    && rm -rf /var/lib/apt/lists/*

# Расширения PHP, которые требует ядро Битрикс
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j"$(nproc)" \
       mysqli pdo_mysql mbstring gd zip intl opcache soap

# memcached-клиент под кэш
RUN pecl install memcached && docker-php-ext-enable memcached

# Свои php.ini-настройки под Битрикс
COPY php/bitrix.ini /usr/local/etc/php/conf.d/zzz-bitrix.ini

WORKDIR /var/www/html

Отдельным файлом подключают php.ini с параметрами, которые Битрикс проверяет в мониторе производительности: увеличенные лимиты памяти и загрузки, включённый opcache с достаточным размером, отключённый вывод ошибок в прод. Короткий фрагмент такого конфига:

; php/bitrix.ini
memory_limit = 512M
upload_max_filesize = 1024M
post_max_size = 1024M
max_input_vars = 10000
mbstring.func_overload = 0
opcache.enable = 1
opcache.memory_consumption = 256
opcache.max_accelerated_files = 100000
opcache.revalidate_freq = 0
date.timezone = Europe/Moscow

Обратите внимание на opcache.revalidate_freq: на dev его держат в 0 или 2, чтобы изменения кода подхватывались сразу, а на проде увеличивают и часто выключают opcache.validate_timestamps, чтобы opcache не проверял файлы на каждом запросе. Это одно из ключевых различий dev- и прод-сборки, к которому мы ещё вернёмся.

Важно: монитор производительности Битрикса на вкладке настроек проверяет ряд параметров PHP. Соберите Dockerfile так, чтобы образ проходил эти проверки «из коробки», — иначе каждый разработчик будет видеть красные галочки и путаться, что не так с его локальным окружением.

docker-compose: связываем сервисы

Dockerfile описывает один образ, а docker-compose — как сервисы соединяются в единое окружение: какие порты открыты, какие тома примонтированы, кто от кого зависит и какие переменные окружения получает. Ниже сокращённый пример compose-файла для Битрикса с базовым стеком.

services:
  nginx:
    image: nginx:1.25
    ports:
      - "80:80"
    volumes:
      - ./:/var/www/html:cached
      - ./docker/nginx/site.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - php

  php:
    build: ./docker/php
    volumes:
      - ./:/var/www/html:cached
    environment:
      DB_HOST: mysql
      DB_NAME: sitemanager
      DB_LOGIN: bitrix
      DB_PASSWORD: ${DB_PASSWORD}
      CACHE_HOST: memcached
    depends_on:
      - mysql
      - memcached

  mysql:
    image: percona:8.0
    command: --sql-mode="" --innodb-flush-log-at-trx-commit=2
    environment:
      MYSQL_DATABASE: sitemanager
      MYSQL_USER: bitrix
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
      - db-data:/var/lib/mysql

  memcached:
    image: memcached:1.6

volumes:
  db-data:

Несколько важных моментов в этом файле. Во-первых, nginx и php монтируют одну и ту же кодовую базу — nginx отдаёт статику и знает пути, php исполняет скрипты. Во-вторых, php обращается к базе по имени сервиса mysql, а к кэшу по имени memcached — Docker резолвит эти имена во внутренние адреса сети. В-третьих, пароль базы не зашит в файл, а приходит из переменной ${DB_PASSWORD}, которую compose берёт из .env рядом с проектом. Наконец, данные MySQL лежат в именованном томе db-data, поэтому переживают пересоздание контейнера.

Для команды такой файл — единая точка правды об окружении. Обновили версию Percona — поправили тег образа, зафиксировали в git, все подтянули изменение при следующем docker compose up. Добавили redis или push-сервер — дописали ещё один сервис. Никаких «а установи себе локально вот это» в переписке.

От базового образа к рабочему окружению 1. Базовый образ: php:8.2-fpm, nginx, percona 2. Dockerfile: расширения PHP + php.ini под Битрикс 3. docker-compose: сервисы, тома, сети, env 4. docker compose up → рабочий стек
Схема: базовый образ обогащается Dockerfile под Битрикс, сервисы связываются в docker-compose, и одна команда поднимает воспроизводимый стек.

Тома: /upload, ядро и база

Контейнеры по своей природе эфемерны: удалили и пересоздали — и всё, что было внутри, исчезло. Для Битрикса это неприемлемо: пользовательские файлы, ядро и база должны переживать любые пересоздания. Поэтому правильная работа с томами — не деталь, а фундамент. Данные Битрикса делятся на три класса, и с каждым обращаются по-своему.

Отдельная тонкость — каталоги кэша /bitrix/cache и /bitrix/managed_cache. Их можно и не выносить в постоянное хранилище (кэш регенерируется), но на macOS их часто монтируют в отдельные тома или держат внутри контейнера, чтобы не гонять тысячи мелких файлов через медленную проброшенную ФС. О производительности томов на macOS — в разделе про проблемы.

ДанныеТип томаЧто будет при потере
/uploadПостоянный (том/сетевой)Потеря всех загруженных файлов
Данные MySQLИменованный томПотеря базы целиком
Код / ядроbind-mount (dev) / в образе (прод)Восстанавливается из git/образа
/bitrix/cacheТом или внутри контейнераРегенерируется, просадка на прогрев
ЛогиТом или stdoutПотеря истории, если не собраны

Права и владелец файлов (www-data)

Проблема прав — самая частая боль новичков в контейнеризации Битрикса, и почти всегда она про одно: процесс php-fpm и владелец файлов должны совпадать. В официальных образах php-fpm работает от пользователя www-data с UID и GID 33. Значит, каталоги, в которые Битрикс пишет, — корень проекта, /upload, /bitrix/cache, /bitrix/managed_cache, /bitrix/tmp — должны принадлежать www-data и быть доступны на запись.

Если этого не сделать, симптомы узнаваемы: не создаётся кэш, не загружаются файлы, установщик модулей ругается на права, монитор производительности показывает ошибки записи. На проде, где код запечён в образ, права выставляют на этапе сборки. На dev, где код монтируется с хоста, начинается самое интересное: у локального пользователя UID обычно 1000, а не 33, и файлы, созданные в контейнере под www-data, оказываются недоступны на редактирование на хосте, и наоборот.

Классическое решение — параметризовать UID/GID контейнерного пользователя под хостовые через build-аргументы:

# Dockerfile (фрагмент)
ARG UID=1000
ARG GID=1000

RUN groupmod -g ${GID} www-data \
    && usermod -u ${UID} www-data

# docker-compose.yml (фрагмент)
  php:
    build:
      context: ./docker/php
      args:
        UID: ${UID:-1000}
        GID: ${GID:-1000}

Так контейнерный www-data получает тот же UID, что и разработчик на хосте, и файлы становятся общими для редактирования без конфликтов. На Linux это критично, на macOS и Windows проброс ФС работает через виртуализацию и обычно сглаживает разницу UID, но параметризация всё равно считается хорошим тоном.

Важно: никогда не «лечите» права командой chmod -R 777 на боевом проекте. Это открывает файлы на запись всем и является дырой в безопасности. Правильный путь — привести владельца к www-data (chown -R www-data:www-data) и выставить осмысленные права 755/644, а изменяемым каталогам — доступ на запись для владельца.

Переменные окружения и .settings.php

Чтобы один и тот же образ работал на dev, стейджинге и проде, настройки не должны быть зашиты в код. Битрикс хранит параметры подключения к базе и кэшу в файлах bitrix/.settings.php и bitrix/php_interface/dbconn.php. В контейнерном подходе эти значения читают из переменных окружения через getenv(), а сами переменные прокидывают через environment или env-файл в docker-compose.

<?php
// bitrix/.settings.php (фрагмент секции connections)
return [
  'connections' => [
    'value' => [
      'default' => [
        'className' => '\\Bitrix\\Main\\DB\\MysqliConnection',
        'host'      => getenv('DB_HOST') ?: 'mysql',
        'database'  => getenv('DB_NAME') ?: 'sitemanager',
        'login'     => getenv('DB_LOGIN') ?: 'bitrix',
        'password'  => getenv('DB_PASSWORD') ?: '',
        'options'   => 2,
      ],
    ],
    'readonly' => true,
  ],
  // ...
];

Такой подход даёт сразу несколько выгод. Секреты не попадают в git и в образ — пароль базы живёт только в окружении контейнера или в системе секретов оркестратора. Хост базы указывается именем сервиса (mysql), поэтому один и тот же файл работает в любой среде, где сервис так называется. А переключение между контурами сводится к смене env-файла, а не к правке кода.

Аналогично настраивают кэш: в .settings.php в секции cache указывают тип (memcached/redis) и адрес хранилища из переменной окружения. Так на dev можно использовать простой файловый кэш или memcached, а на проде — redis-кластер, не меняя ни строчки в кодовой базе.

Совет: держите в репозитории файл .env.example с полным списком переменных без реальных значений, а настоящий .env добавьте в .gitignore. Новый разработчик копирует пример, подставляет свои значения — и окружение поднимается, а секреты не утекают в историю коммитов.

Dev-окружение под команду

Главный приз контейнеризации на старте — единое dev-окружение, которое поднимается у всех одинаково и одной командой. Чтобы это работало на практике, а не только в теории, стоит соблюсти несколько принципов организации.

  1. Всё окружение — в репозитории. Dockerfile, docker-compose, конфиги nginx и php, скрипты инициализации лежат в каталоге docker/ внутри проекта под git. Никаких «локальных» файлов, которых нет у коллег.
  2. Одна команда на запуск. Заверните инициализацию в Makefile или простой скрипт: make up собирает образы, поднимает сервисы, накатывает дамп базы для разработки. Разработчик не должен помнить последовательность из десяти команд.
  3. Дамп базы для разработки. Договоритесь, откуда берётся стартовая база: обезличенный дамп с прода или сид-набор данных. Автоматизируйте его загрузку при первом старте.
  4. Единые версии. Зафиксируйте версии PHP, MySQL/Percona и расширений тегами образов. Обновление версии — через коммит, а не через «у меня уже новее».
  5. Локальный домен и почта. Настройте удобный локальный домен и перехват исходящей почты (mailhog), чтобы тестовые письма не уходили реальным клиентам и были видны в веб-интерфейсе.
  6. Документация в README. Короткая инструкция «клонируй — скопируй .env — make up» экономит часы онбординга каждому новому человеку в команде.

Когда это выстроено, онбординг нового разработчика сокращается с «день на настройку окружения» до «полчаса до первого коммита». А главное — исчезает целый класс багов «работает только у меня», потому что «у меня» и «у всех» теперь физически одно и то же окружение.

Проблемные места контейнеризации

Битрикс — большая и старая платформа, спроектированная под классический сервер, поэтому в контейнерах у неё есть характерные болевые точки. Их лучше знать заранее, чтобы не наступать вслепую.

Производительность томов на macOS. Самая известная проблема. Файловая система хоста пробрасывается в контейнер через виртуализацию, и каждое обращение к файлу проходит через прослойку. Битрикс на старте читает десятки тысяч мелких файлов ядра, поэтому bind-mount всего проекта на macOS даёт заметные тормоза — страница, которая на Linux открывается за 200 мс, на маке может грузиться секунды. Лечится это выносом ядра, vendor и каталогов кэша в именованные тома, включением делегированного режима (:cached/:delegated) и использованием VirtioFS в свежих Docker Desktop. На Linux монтирование нативное, проблемы нет.

Cron и агенты. Битрикс по умолчанию запускает агенты на хитах пользователей, но правильная эксплуатация требует cron. В одном контейнере php-fpm cron не запущен — нужен либо отдельный контейнер с планировщиком, либо supervisor. Об этом отдельный раздел ниже.

Композит и pull-соединения. Модуль «Композитный сайт» и push/pull-технология требуют аккуратной настройки на уровне nginx: правильного проксирования, заголовков и, для pull, отдельного push-сервера. В контейнерах это не сложнее, чем на BitrixVM, но конфиг nginx нужно перенести осознанно, а не скопировать частично. Про сам композит и его влияние на скорость мы писали в статье про композитный сайт на Битрикс.

Память под ORM и большие операции. D7-ORM, обмены с 1С, экспорт больших выборок и построение фасетов легко упираются в лимит памяти контейнера. По умолчанию контейнер может быть ограничен по RAM жёстче, чем хост, и процесс убивается OOM-киллером без внятной ошибки в логах приложения. Лимиты памяти php (memory_limit) и лимиты контейнера нужно согласовать и заложить запас под пиковые операции обмена и индексации.

ПроблемаСимптомРешение
Тома на macOSМедленная загрузка страницТома под ядро/кэш, VirtioFS, :cached
Агенты не идутОбмены и задачи не выполняютсяCron в отдельном контейнере/supervisor
Композит/pullНе работает realtime, чатPush-сервер + корректный nginx-конфиг
OOM при обменеПроцесс убит без явной ошибкиСогласовать memory_limit и лимит контейнера
Разные UIDФайлы не редактируются на хостеПараметризация UID/GID через build-args

Cron и агенты в контейнере

Агенты Битрикса — это отложенные и регламентные задачи: обмены, отправка отложенных писем, пересчёт, чистка. На классическом сервере их выносят на cron, вызывающий /bitrix/php_interface/cron/agents.php через php-cli, чтобы задачи не зависели от того, зашёл ли на сайт живой пользователь. В контейнерах ту же логику воспроизводят одним из двух способов.

Ключевой момент — перевести агенты в режим запуска на cron в настройках главного модуля (константа BX_CRONTAB) и в самих настройках, чтобы они перестали выполняться на хитах. Иначе задачи будут идти двумя путями сразу или конкурировать. Тонкости работы агентов, cron и фоновых заданий мы разбираем в отдельном материале рубрики Разработка и архитектура.

Важно: контейнер cron должен видеть те же тома и то же окружение (переменные подключения к базе), что и php-fpm. Если он ходит в другую базу или не имеет доступа к /upload, агенты будут падать или работать не с теми данными.

Подготовка к CI/CD и деплою

Контейнеризация раскрывается полностью, когда становится основой автоматического деплоя. Идея в том, что образ, собранный и протестированный в пайплайне, — это и есть артефакт, который едет на сервер. Ничего не собирается «на бою», исключается класс проблем «на сервере другая версия». Путь к этому строится поэтапно.

  1. Сборка образа в пайплайне. На каждый коммит/тег CI собирает образ приложения (php-fpm с запечённым кодом и vendor из composer), прогоняет линтеры и тесты и публикует образ в реестр с тегом версии.
  2. Неизменяемый артефакт. Один и тот же образ проходит через стейджинг и прод. Это гарантирует, что тестировали ровно то, что поедет в продакшен.
  3. Миграции и обновления. Обновления модулей и структуры базы Битрикса выносят в отдельный контролируемый шаг деплоя, а не оставляют на «мастер обновлений» вручную. Миграции прогоняют до переключения трафика.
  4. Прогрев кэша. После выката новый контейнер прогревают (первые запросы, регенерация managed-кэша), чтобы пользователи не попали на «холодный» сайт с просадкой скорости.
  5. Переключение и откат. Трафик переключают на новый контейнер, старый держат наготове для мгновенного отката. Тома с /upload и базой при этом общие и не пересоздаются.

Отдельная дисциплина — что попадает в образ, а что остаётся в томах. В образ запекают неизменяемое: код, ядро, vendor, ассеты. В томах живёт изменяемое: /upload, база, кэш, логи. Такое разделение делает деплой предсказуемым: выкатка новой версии не трогает пользовательские данные, а откат не теряет заказы. Полный разбор конвейера — в нашей статье про CI/CD и деплой Битрикс.

Коммит git push Сборка образ + тесты Реестр образ:tag Деплой на прод Миграции → прогрев кэша → переключение трафика тома /upload и БД — общие, не пересоздаются
Схема: коммит запускает сборку образа с тестами, образ публикуется в реестр и едет на прод, где проходят миграции, прогрев кэша и переключение трафика.

Прод против дева: чем отличаются сборки

Одна из главных ошибок — думать, что dev-окружение и прод должны быть идентичны на 100%. Паритет важен по стеку (версии PHP, MySQL, расширения), но по настройкам dev и прод сознательно расходятся. Понимание этих различий экономит много нервов.

ПараметрDevПрод
Кодbind-mount с хостаЗапечён в образ (immutable)
opcache.validate_timestampsВключён (видеть правки)Выключен (максимум скорости)
Вывод ошибокНа экран, debug наВ лог, display_errors off
КэшФайловый / memcachedRedis, композит включён
КомпозитЧасто выключенВключён
ДанныеОбезличенный дампБоевая база в томе
Мониторинг/лимитыМягкиеЖёсткие лимиты, метрики, алерты

Из таблицы видно главное правило: dev оптимизируют под скорость разработки, прод — под скорость и надёжность работы. На dev важно сразу видеть изменения кода и подробные ошибки, поэтому opcache не кэширует агрессивно, а debug включён. На проде наоборот — код неизменяем, opcache выкручен на максимум, ошибки уходят в лог, а не на экран пользователю, включён композит и настроены лимиты с мониторингом. Реализуют это одним образом с разными переменными окружения и, при необходимости, разными compose-файлами (docker-compose.override.yml для dev).

Частые ошибки

Мини-FAQ. Нужно ли запекать /upload в образ? Нет — /upload это изменяемые пользовательские данные, им место в постоянном томе. В образ запекают только неизменяемое: код, ядро, vendor и ассеты.

Чек-лист внедрения

Сведём всё в практический список, по которому удобно проверять готовность контейнерного окружения перед раздачей команде и выходом на прод:

  1. Стек описан кодом. Dockerfile и docker-compose с сервисами nginx + php-fpm + mysql/percona + memcached/redis (+ push при необходимости) лежат в репозитории.
  2. Расширения PHP на месте. Образ php проходит проверки монитора производительности Битрикса: mysqli, mbstring, gd, zip, intl, opcache и корректные лимиты.
  3. Тома настроены. База MySQL и /upload вынесены в постоянные тома, кэш обработан с учётом macOS.
  4. Права согласованы. Владелец файлов — www-data, UID/GID параметризованы под хост, никаких 777.
  5. Настройки в env. Подключение к базе и кэшу читается из переменных окружения в .settings.php, секреты не в git, есть .env.example.
  6. Cron поднят. Агенты переведены на cron в отдельном контейнере или через внешний планировщик, режим BX_CRONTAB включён.
  7. Dev запускается одной командой. make up или скрипт поднимает стек и накатывает дамп; онбординг описан в README.
  8. Прод-сборка отделена. Код запекается в образ, opcache и композит настроены под прод, различия dev/прод вынесены в переменные и override-файлы.
  9. Путь к CI/CD размечен. Понятно, где собирается образ, как проходят миграции, прогрев кэша и переключение трафика с возможностью отката.

Вывод

Docker не делает Битрикс быстрее сам по себе — он делает окружение воспроизводимым, версионируемым и одинаковым у всех, а это лечит целый класс проблем «работает только у меня» и открывает дорогу к автоматическому деплою. Начните с малого: соберите контейнерное dev-окружение из nginx, php-fpm и базы, добейтесь запуска одной командой, аккуратно решите вопросы томов, прав www-data и переменных окружения. Когда команда привыкнет и стек обкатается, тем же образом переносите на прод вместе с настройкой CI/CD. Так контейнеризация из модного слова становится рабочим инструментом, который экономит часы на каждом релизе и новом человеке в команде.

Частые вопросы

Можно ли запускать 1С-Битрикс в Docker на проде или это только для разработки?

Можно и на проде, но это осознанное инженерное решение, а не «поставил и забыл». В контейнерах прекрасно живут стейджинг и продакшен при условии, что вы решили вопросы с постоянным хранилищем (тома под /upload, ядро и базу), cron и агентами, а также с оркестрацией и мониторингом. Для многих проектов на старте разумнее использовать Docker только для dev-окружения, а на проде оставаться на BitrixVM или классической LNMP-сборке, постепенно перенося прод в контейнеры вместе с CI/CD.

Чем контейнеризация Битрикса отличается от готового образа BitrixVM?

BitrixVM — это цельная виртуальная машина с преднастроенным стеком и меню управления через bitrix-env, где всё живёт в одной системе. Docker разбивает тот же стек на отдельные контейнеры-сервисы (nginx, php-fpm, база, memcached/redis, push-сервер), которые описаны кодом в Dockerfile и docker-compose и легко воспроизводятся на любой машине. BitrixVM проще запустить «из коробки», Docker даёт повторяемость, версионирование окружения и путь к CI/CD, но требует ручной сборки стека и понимания, как связать сервисы между собой.

Как правильно раздать права на файлы в контейнере, чтобы Битрикс не ругался?

Ключевое правило — процесс php-fpm и владелец файлов должны совпадать. В официальных образах php-fpm обычно работает от пользователя www-data (UID/GID 33), поэтому каталоги /bitrix/cache, /bitrix/managed_cache, /upload и корень проекта должны принадлежать www-data и быть доступны на запись. Проблемы чаще возникают на dev-машинах, где локальный пользователь имеет другой UID, — тогда через build-аргументы задают UID/GID контейнерного пользователя под хостовые, чтобы файлы, созданные в контейнере, оставались редактируемыми на хосте и наоборот.

Почему на macOS Битрикс в Docker работает медленно и как это лечить?

На macOS файловая система хоста пробрасывается в контейнер через виртуализацию, и каждый вызов stat к файлу проходит через прослойку. Битрикс на старте обращается к десяткам тысяч мелких файлов ядра, поэтому bind-mount всего проекта даёт заметные тормоза. Лечится это несколькими способами: держать ядро и vendor в именованных томах вместо bind-mount, включать делегированный режим монтирования, использовать VirtioFS в свежих версиях Docker Desktop или выносить кэш и managed_cache в отдельные тома. На Linux этой проблемы нет, монтирование там нативное.

Как в контейнере работают агенты и cron Битрикса?

Агенты Битрикса по умолчанию запускаются на хитах пользователей, но на бою их правильнее выносить на cron через агент на php-cli. В Docker для этого либо поднимают отдельный контейнер с той же кодовой базой и запущенным cron/supervisor, который дёргает /bitrix/php_interface/cron/agents.php, либо используют внешний планировщик, вызывающий php-cli внутри контейнера. Держать cron в том же контейнере, что и php-fpm, — рабочий вариант для небольших проектов, но чище разделять веб-процесс и фоновые задачи по отдельным контейнерам с общими томами.

Что писать в .settings.php, чтобы вынести настройки БД и кэша в переменные окружения?

В .settings.php параметры подключения к базе и кэшу можно читать через getenv(), а сами значения передавать контейнеру через environment или env-файл docker-compose. Так один и тот же образ работает и на dev, и на стейджинге, и на проде — меняются только переменные окружения, а не код. Хост базы указывают именем сервиса из docker-compose (например, mysql или db), потому что внутри сети Docker сервисы доступны по именам. Секреты (пароль базы, ключи) не хранят в образе — их прокидывают через окружение или систему секретов оркестратора.

Поделиться:

Нужно контейнерное окружение и деплой без боли?

Соберём Docker-окружение под вашу команду, наведём порядок с томами, правами и настройками, настроим CI/CD и перенесём прод в управляемую инфраструктуру. Рассчитаем работы под ваш проект.

Услуга «Разработка»

Игорь Воскресенский

Основатель студии B2Bsite. С 2014 года команда разрабатывает и поддерживает интернет-магазины и корпоративные сайты на 1С-Битрикс, собирает контейнерные окружения, настраивает CI/CD и обмен с 1С для среднего и крупного бизнеса.

← Все статьи блога