Серверы

Docker на сервере: когда контейнеры окупаются

Разработчик сказал «просто положи это в Docker», и теперь на сервере работают шесть контейнеров, и никто точно не знает, что делает каждый из них. Или наоборот: приложение много лет назад установили на сервер вручную, и каждое обновление пугает, потому что никто не помнит, от каких библиотек и настроек оно зависит.

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

Короткий ответ: Docker окупается, когда на сервере несколько приложений с разными требованиями к версиям, когда приложение нужно устанавливать многократно и одинаково или когда старое приложение нужно изолировать от новой системы. Для одного простого сайта, который никто не обновляет, он чаще всего лишь добавляет сложности.

Когда контейнеры действительно помогают

  • Несколько приложений, разные требования. Одному нужна старая версия Java или PHP, другому новая. Без контейнеров это путаница версий на сервере; в контейнере у каждого приложения своё окружение.
  • Обновление и откат. Новая версия — это новый образ (image). Если что-то пошло не так, вы запускаете предыдущий образ и за минуты возвращаетесь в исходное состояние.
  • Переезд. Когда приложение в контейнере, а данные чётко отделены, перенос на новый сервер становится гораздо предсказуемее. То же касается перехода на новый Ubuntu LTS — обновление хост-системы не ломает библиотеки внутри приложения.
  • Повторяемая установка. Среды разработки, тестирования и продакшена собираются по одному описанию, а не вручную «примерно одинаково».

Когда Docker — просто лишняя сложность

  • На сервере одно простое приложение, которое работает и редко меняется.
  • Некому следить за контейнерами и обновлять их. Контейнер сам не обновляется — старый образ остаётся старым, даже если хост пропатчен.
  • Приложение тесно связано с самим сервером (железо, файловая система, специфические сервисы), и перенос в контейнер означал бы большую переделку без явной пользы.

Что меняется с контейнерами

Обновления. Кроме операционной системы, обновлять нужно и образы. Старый образ с тегом latest, который месяцами не скачивали заново, может содержать такое же устаревшее ПО, как и заброшенный сервер. Я всегда договариваюсь, кто и как часто обновляет образы.

Резервное копирование — здесь больше всего ошибок. Контейнер одноразовый, данные — нет. База данных, загруженные файлы и конфигурация должны находиться в томах (volumes) или на хосте, и бэкапы должны охватывать именно их. Если база данных живёт в контейнере без тома, она исчезнет вместе с контейнером. Базу данных я всегда копирую её собственным инструментом (например, дамп PostgreSQL или MySQL/MariaDB), а не копированием файлов тома во время работы.

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

Безопасность. Контейнер сам по себе не является границей безопасности. Не запускайте приложение от root, не открывайте порт базы данных наружу и не вшивайте пароли в образ. Защита самого сервера остаётся прежней — см. также мой чек-лист по защите Linux-сервера.

Типичная схема

Для приложения малого бизнеса я чаще всего использую такую схему:

  1. Nginx впереди — принимает HTTPS-соединения и направляет запросы в нужный контейнер. Сам Nginx может работать в контейнере или на хосте.
  2. Приложение в контейнере — со своими версиями, не мешая остальным.
  3. База данных — либо в отдельном контейнере с томом, либо прямо на хосте. Когда данных много и важна производительность, я часто предпочитаю базу на хосте: её проще мониторить, настраивать и резервировать.

Та же логика действует и для более тяжёлых компонентов — Tomcat, Elasticsearch или OpenSearch: каждый в своём контейнере с чётко определёнными каталогами данных.

Перенос старого приложения в контейнеры шаг за шагом

Переделывать всё сразу не нужно. Обычно я действую так:

  1. Описываю, что реально работает на сервере: версии, настройки, задания по расписанию, где лежат данные.
  2. Помещаю приложение в контейнер, а база данных пока остаётся как есть. Тестирую в отдельной среде.
  3. Переключаю, когда тесты пройдены, — старая установка остаётся запасной.
  4. Только после этого решаем, переносить ли в контейнеры базу данных и остальные части.

Если само приложение нуждается в серьёзном обновлении, см. также статью обновить старое ПО или переписать и услугу модернизация ПО. Если вместе с этим меняется сервер, поможет руководство по переносу сервера.

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

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

Делает ли Docker сервер быстрее?

Не заметно. Накладные расходы контейнера невелики, но это не прирост производительности. Docker — инструмент установки и обслуживания, а не ускоритель.

Должна ли база данных быть в контейнере?

Может, если данные лежат в томе и резервное копирование настроено. При большом объёме данных и высоких требованиях я часто предпочитаю базу прямо на хосте.

Хватит ли Docker Compose или нужен Kubernetes?

Для приложений малого бизнеса на одном сервере обычно хватает Docker Compose. Kubernetes оправдан, только когда серверов и сервисов много и их нужно масштабировать автоматически.

Обновляются ли контейнеры сами?

Нет. Образы нужно регулярно обновлять, а контейнеры перезапускать — это одно из первых, о чём я договариваюсь в рамках обслуживания.

Читайте также

Связанные услуги

Кто следит за вашим сервером?

Установка, обновления, резервные копии и мониторинг — Linux-сервер, за которым стоит человек, которому можно позвонить.