Docker-образ — собранная файловая система и программа для запуска. Контейнер — запущенный экземпляр образа. Git хранит исходники; registry хранит образы; *.images.tar — файл с их копиями. Это разные вещи.
Что использует приложение
| Образ | Что делает | Как работает |
|---|---|---|
| backend | Go API, migrate для SQL, admin для первого аккаунта | API работает постоянно; migrate/admin запускаются для отдельного действия |
| admin | Собранный React-интерфейс и Nginx | Постоянный frontend-контейнер обслуживает UI и API-прокси |
| ops | Проверка конфигурации, состояние операций, дамп и восстановление | Временные служебные контейнеры во время команд control |
| postgres:16-bookworm | Сервер PostgreSQL | Постоянный контейнер БД с данными вне образа |
| certbot | Получение и обслуживание HTTPS-сертификатов | Запускается для работы с сертификатами |
| nginx | Базовый Nginx-образ и служебные проверки конфигурации | Используется frontend и его проверками |
Если рядом размещен самостоятельный сайт, у него свой образ и контейнер. Он не является старой версией админки.
Для чего нужен ops
deploy/control вызывает ops, чтобы проверить настройки и релиз, записать этапы операции, сформировать конфигурацию, проверить готовность API, создать дамп через pg_dump и восстановить его через pg_restore. Ops также содержит клиентские инструменты PostgreSQL, OpenSSL, curl, jq и оператор admingen-ops. Миграции приложения выполняет migrate из backend-образа.
Сейчас ops собран на postgres:16-bookworm, как и образ БД. Сервер PostgreSQL внутри ops не запускается: эта основа дает готовые инструменты той же версии. Уменьшенный ops пока не реализован. Docker хранит общие слои один раз, поэтому размеры в списке образов нельзя просто складывать.
Даже с backup None ops остается нужен для команд управления. Его нельзя считать мусором только потому, что постоянного ops-контейнера нет. Сохраняйте точные ops-образы текущего и предыдущего релиза вместе с backend и admin.
Образы сборки
Go и Node собирают исходники внутри промежуточных стадий Docker. Они не работают отдельными постоянными контейнерами приложения и не входят целиком в итоговый backend/admin/ops. После сборки остаются кэш и иногда базовые образы, чтобы следующий build был быстрее. Source не требует собственного registry, но базовые образы Docker все равно получает из внешних источников, если их нет локально.
Посмотреть реальные контейнеры
На машине, где приложение запущено:
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
docker image ls
Для выбранного контейнера, подставив его имя из первой команды:
docker inspect ИМЯ_КОНТЕЙНЕРА --format 'Image={{.Image}} Configured={{.Config.Image}} Status={{.State.Status}}'
Старые теги образов не доказывают наличие лишних контейнеров. После релиза сохраняются старые образы для восстановления; их очистка описана отдельно.
Если нужный образ удален
Для Source/Archive восстановите образы из сохраненного архива текущего релиза:
docker load -i /полный/путь/к/релизу.images.tar
Здесь путь берется из state/current.json, поля imageArchive, и фактического местоположения архива. В runtime имя файла — SHA256 из этой записи плюс .tar. Команда загружает образы без перезапуска приложения. Для Registry скачайте точную ссылку образа из записи релиза через docker pull. Не заменяйте потерянный образ новой сборкой под старым тегом.