Вы собрали образ у себя на ноутбуке — теперь нужно, чтобы он оказался на сервере. Реестр образов — это именно то место, через которое образ переезжает с одной машины на другую, и откуда CI берёт и кладёт образы автоматически.
Что такое реестр образов
Реестр образов (registry) — это хранилище Docker-образов, доступное по сети. Принцип тот же, что у репозитория git: вы отправляете (push) образ в реестр, а потом скачиваете (pull) его на любой машине — локально, на сервере, в Kubernetes.
Самые распространённые реестры:
- Docker Hub (
hub.docker.com) — публичный реестр по умолчанию. Бесплатный для публичных образов; приватные — ограничены на бесплатном тарифе. Когда вы пишетеdocker pull nginx, Docker идёт именно туда. - GitHub Container Registry (
ghcr.io) — реестр от GitHub, удобен, если код уже там. Права управляются через токены GitHub. - Приватные реестры — можно поднять собственный (например, через
registry:2или Harbor) или использовать реестр облачного провайдера (Amazon ECR, Google Artifact Registry, Yandex Container Registry).
Все они работают по единому протоколу — OCI Distribution Spec, поэтому команды docker push / docker pull одинаковы вне зависимости от реестра.
Именование образов и теги
Полное имя образа выглядит так:
<реестр>/<пространство-имён>/<имя>:<тег>
Несколько примеров:
nginx:1.27 # Docker Hub, официальный образ
myuser/myapp:latest # Docker Hub, пользовательский образ
ghcr.io/myorg/backend:v1.4.2 # GitHub Container Registry
registry.company.ru/team/api:sha-abc1234 # приватный реестр
Если реестр не указан — Docker Hub. Если тег не указан — latest.
Тег — это просто метка на конкретный слой образа. Теги изменяемы: latest сегодня и latest через неделю могут указывать на разные образы. Поэтому latest удобен для разработки, но опасен в продакшне.
Стратегия тегов
Хаотичное именование — источник головной боли: непонятно, что задеплоено, сложно откатиться, трудно проследить, из какого коммита образ собран.
Три устойчивые стратегии:
1. Семантическое версионирование (semver)
myapp:1.4.2
myapp:1.4
myapp:1
Понятно людям, поддерживает «плавающие» теги (1.4 → всегда последний патч-релиз). Подходит для библиотек и публичных образов.
2. Git SHA коммита
myapp:sha-abc1234f
Однозначно привязывает образ к исходному коду. Невозможно перезаписать случайно. Рекомендуется как основной тег в CI — всегда знаете, из какого коммита собрано.
3. Комбинированный
myapp:1.4.2 # для релизного тега
myapp:sha-abc1234f # для точного отслеживания
Можно ставить оба тега на один образ.
Короткая формула: в продакшне никогда не используйте latest — только версионированный или sha-тег.
docker tag, push и pull
Прежде чем отправить образ в реестр — войдите в него:
docker login ghcr.io -u USERNAME --password-stdin <<< "$GITHUB_TOKEN"
Образ тегируется командой docker tag:
# сначала собираем
docker build -t backend:local .
# добавляем «адрес» для реестра
docker tag backend:local ghcr.io/myorg/backend:sha-abc1234f
docker tag backend:local ghcr.io/myorg/backend:v1.4.2
Отправляем:
docker push ghcr.io/myorg/backend:sha-abc1234f
docker push ghcr.io/myorg/backend:v1.4.2
Скачиваем на другой машине:
docker pull ghcr.io/myorg/backend:sha-abc1234f
Один образ (один набор слоёв) может иметь сколько угодно тегов — это дёшево: теги — просто указатели, данные не дублируются.
Сборка и публикация в CI
Ручная сборка и push — это хорошо для экспериментов. В реальном проекте образ собирается автоматически при каждом пуше в основную ветку или при создании тега релиза.
Общая схема конвейера:
Код → git push → CI запускается → docker build → docker tag → docker push → (развёртывание)
Пример конфигурации для GitHub Actions (.github/workflows/build.yml):
name: Сборка и публикация образа
on:
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # нужно для публикации в ghcr.io
steps:
- uses: actions/checkout@v4
- name: Войти в GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Собрать образ и опубликовать
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
Что здесь происходит:
- При пуше в
mainзапускается задание. - CI входит в реестр с помощью автоматического токена
GITHUB_TOKEN. - Образ собирается из
Dockerfileв корне репозитория. - Присваиваются два тега: sha коммита (стабильный) и
latest(для удобства при разработке). - Образ отправляется в реестр.
В реальном проекте рядом обычно идёт следующий шаг — обновление манифеста Kubernetes или вызов kubectl rollout restart, но это уже выходит за пределы Docker как инструмента сборки.
Немного про многоэтапную сборку и размер образа
Если вы используете многоэтапную сборку (multi-stage build), CI ничего особенного делать не должен — docker build сам разберётся. Для Spring Boot это выглядит так: в первом этапе компилируете jar, во втором — копируете только его поверх базового eclipse-temurin:21-jre. В реестр попадает только финальный, лёгкий образ.
# --- этап сборки ---
FROM eclipse-temurin:21-jdk AS build
WORKDIR /app
COPY . .
RUN ./gradlew bootJar -x test
# --- финальный образ ---
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=build /app/build/libs/app.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
Такой образ занимает 200–300 МБ вместо 600+ МБ с полным JDK — и именно он уйдёт в реестр.
Коротко
- Реестр образов — хранилище, через которое образ переезжает между машинами; самые популярные: Docker Hub, GitHub Container Registry, приватные реестры облачных провайдеров.
- Полное имя образа:
<реестр>/<пространство-имён>/<имя>:<тег>; без реестра — Docker Hub, без тега —latest. - В продакшне используйте конкретный тег (semver или sha коммита), а не
latest— иначе непонятно, что именно задеплоено. docker tagдобавляет новый указатель на уже собранный образ; данные не копируются.- Конвейер CI:
build → tag → push; следующий шаг — развёртывание (Kubernetes, systemd, Compose на сервере). - В GitHub Actions
GITHUB_TOKENдостаточно для публикации вghcr.io— дополнительные секреты не нужны.
Что почитать дальше
- Многоэтапная сборка и слои образа — как устроены слои, почему порядок инструкций влияет на размер и скорость сборки.
- Лучшие практики образов — безопасность, минимальный базовый образ, непривилегированный пользователь.
- Запуск Spring Boot в Docker — полный пример: Dockerfile, конфигурация JVM, профили Spring.