Кейс: я заменил Portainer на Lazydocker и терминал — опыт миграции, настройка и итоги
Рассказываю, почему отказался от Portainer в пользу Lazydocker и терминала: как подготовил миграцию, на что обратил внимание при настройке, что выиграл и что потерял в ежедневной эксплуатации.
Кейс: почему я отказался от Portainer
Portainer много лет был моим дефолтным способом управлять контейнерами: удобно видеть стеки, перезапускать сервисы и обновлять образы через веб-интерфейс. Но со временем я захотел уменьшить накладные расходы, сузить поверхность атаки (минус ещё один веб-сервис), ускорить повседневные операции и приблизиться к GitOps-подходу. В результате я убрал Portainer и оставил связку Lazydocker + классический терминал с Docker Compose.
Контекст кейса: один хост (домашний сервер/внутренний VPS), десяток сервисов в docker-compose, обратный прокси, периодические обновления, доступ по SSH. Командная работа и многохостовые сценарии не требовались — это важно для вывода.
Что такое Lazydocker и чем он заменяет Portainer
Lazydocker — это TUI (терминальный интерфейс) для Docker и Docker Compose. Он показывает контейнеры, сервисы, образы, тома, даёт быстрый доступ к логам и метрикам, позволяет перезапускать и пересобирать сервисы, не выходя из терминала. Никаких дополнительных демонов: утилита запускается по требованию, потребляет минимум ресурсов и работает поверх установленного Docker CLI.
Что важно знать заранее:
- Lazydocker не заменяет корпоративные функции Portainer: нет RBAC, команд, агентной модели, каталогов шаблонов и подробного UI для реестров.
- Для большинства повседневных задач соло-админа (логирование, рестарт, обновление образов, просмотр ресурсов) функционала более чем достаточно.
Среда и требования
- ОС: Linux (Debian/Ubuntu/Alpine и т.п.) или macOS; Docker CE/EE установлен.
- Docker Compose v2 как плагин к Docker (docker compose …).
- Доступ по SSH, желательно tmux/screen для устойчивых сессий.
- Права пользователя в группе docker (или rootless Docker, если хотите повысить безопасность).
Установка и базовая настройка
Общее:
# Linux (вариант через curl из релизов)
curl -L https://github.com/jesseduffield/lazydocker/releases/latest/download/lazydocker_<OS>_<ARCH>.tar.gz \
| tar xz -C /usr/local/bin lazydocker
# или через пакетный менеджер (где доступно)
# macOS (Homebrew)
brew install jesseduffield/lazydocker/lazydocker
# Проверка
lazydocker --version
Рекомендации по настройке:
- Запускайте от пользователя в группе docker (или используйте rootless Docker), чтобы не давать лишних привилегий.
- Если управляете удалённым хостом, используйте Docker Context: это удобнее и безопаснее, чем прокидывать сырой DOCKER_HOST.
- Конфиг Lazydocker хранится в ~/.config/lazydocker/config.yml — там можно задать горячие клавиши, поведение логов и команд.
Пример минимального конфига:
# ~/.config/lazydocker/config.yml
gui:
showAllContainers: true
wrapMainPanel: true
commandTemplates:
restartService: "docker compose -f {{ .ComposeFile }} restart {{ .Service.Name }}"
rebuildService: "docker compose -f {{ .ComposeFile }} up -d --build {{ .Service.Name }}"
Миграция с Portainer: пошаговый подход
- Инвентаризация стеков. Зафиксируйте все проекты и их параметры (переменные, сети, тома, политики рестарта). Если стек создавался через Portainer, выгрузите/восстановите docker-compose.yml и .env.
- Разложите проекты по каталогам. На хосте заведите папки ~/stacks/app1, ~/stacks/app2 и т.д., храните в них docker-compose.yml и .env. Это упростит обслуживание и бэкапы.
- Стандартизируйте compose-файлы. Убедитесь, что у сервисов есть restart: unless-stopped, корректные volumes, сети и лимиты ресурсов (deploy/resources для Swarm или mem_limit/cpu_shares для обычного Docker).
- Перенесите секреты и переменные. Portainer мог хранить их в UI. Перенесите в .env или Docker secrets (если используете Swarm), проверьте, что они не попадают в репозиторий.
- Запуск и проверка. Для каждого проекта:
docker compose pull
docker compose up -d
docker compose psПроверьте логи и работоспособность.
- Чистка Portainer. Остановите и удалите контейнер Portainer и связанные тома, если они больше не нужны.
Ежедневная эксплуатация в терминале
Типовые ритуалы заменяются парами команд:
- Статус и логи: Lazydocker показывает CPU/RAM и хвост логов по контейнеру; быстро переключаюсь между сервисами, перезапускаю их горячими клавишами.
- Ручное обновление образов:
docker compose pull && docker compose up -d - Просмотр логов в реальном времени:
docker compose logs -f --tail=200 - Войти внутрь контейнера:
docker exec -it <container> sh # или bash - Чистка мусора:
docker system prune -f
Для удалённых хостов удобно настроить Docker Context и переключаться одной командой:
# Разовая настройка контекста по SSH
docker context create homelab --docker "host=ssh://user@server"
# Переключение
docker context use homelab
# Теперь все команды docker/*compose работают с удалённым хостом
lazydocker # тоже наследует активный контекст/окружение
Обновления и безопасность
- Версионируйте образы. Избегайте latest в продакшене, фиксируйте теги и меняйте их осознанно.
- Автообновления. Для личных проектов можно использовать watchtower, но в критичных сервисах предпочитайте ручное обновление и канареечные перезапуски.
- Сужайте доступ. Не публикуйте Docker API наружу, вход — только по SSH/VPN. Ограничьте открытые порты, проверяйте файрвол.
- Рассмотрите rootless Docker: снизит риск компрометации хоста через контейнер.
Мониторинг и логи без Portainer
- Минимальный вариант: Lazydocker + docker compose logs в tmux окнах.
- Продвинутый: cAdvisor + Prometheus + Grafana для метрик контейнеров и узла.
- Удобные логи: Dozzle — легковесный веб-просмотрщик логов (можно держать только в локальной сети/VPN).
Результаты: плюсы и минусы перехода
Плюсы:
- Минус один веб-сервис: ниже потребление памяти/CPU, меньше апдейтов и CVE-поверхность.
- Быстрее повседневные операции: логирование, перезапуск, обновления — в один-два шага.
- Ближе к GitOps: вся конфигурация в compose и .env, легко переносить и бэкапить.
- Работает офлайн и по медленным каналам (SSH + TUI).
Минусы:
- Нет графического RBAC, каталогов шаблонов и многохостовой оркестрации.
- Порог входа для новичков выше: нужно уверенно владеть CLI и понимать Docker Compose.
- Нет единого веб-интерфейса «для всех» — тяжело делегировать управление команде без CLI.
Когда выбор Lazydocker оправдан, а когда нет
- Подходит: домашние/пет-проекты, один-два хоста, соло-админ, ориентация на конфиг-код.
- Сомнительно: команды с ролевой моделью доступа, десятки хостов, требование централизованного веб-UI и аудита без CLI.
Краткая шпаргалка
# Обновить и перезапустить весь стек
cd ~/stacks/app && docker compose pull && docker compose up -d
# Перезапустить один сервис
docker compose restart service_name
# Посмотреть логи сервиса
docker compose logs -f service_name
# Войти в контейнер
docker exec -it service_container sh
# Запустить TUI
lazydocker
Частые ошибки и как их избежать
- Случайные потери данных: не монтируете постоянные тома — проверьте volumes перед перезапусками.
- Раздутые логи: настройте лог-драйвер и ограничения (например, json-file с max-size).
- Несогласованные окружения: храните .env рядом с compose и документируйте переменные.
- Тэг latest везде: фиксируйте версии, обновляйтесь осознанно.
- Без бэкапов: делайте дампы томов/баз и проверяйте восстановление.
Альтернативы и дополнения
- Dockly (TUI), ctop (метрики), Dozzle (веб-логи) — лёгкие инструменты вокруг Docker.
- Yacht/Dockge — веб-альтернативы полегче Portainer.
- Podman + podman-compose — без демона, с rootless по умолчанию.
- Если доросли до оркестрации — Kubernetes и k9s вместо Lazydocker.
Итоги
Для моего сценария связка Lazydocker + терминал оказалась быстрее, проще и безопаснее Portainer. Если у вас один-два хоста и вы комфортно чувствуете себя в CLI, переход окупается: меньше сервисов для поддержки, больше контроля и предсказуемости. Если же нужны роли, мультихост и единый веб-UI для команды — Portainer по-прежнему остаётся удобным выбором.