Реєстри Docker-образів
Реєстри Docker-образів
Від локальних образів до глобального розповсюдження
У попередніх статтях ми навчилися створювати Docker-образи, оптимізувати їх розмір та швидкість збірки. Але всі ці образи існували лише на вашому локальному комп'ютері. У реальних проєктах образи потрібно розповсюджувати: передавати колегам, розгортати на серверах, використовувати в CI/CD pipeline, публікувати для спільноти.
Саме для цього існують Docker-реєстри (Docker Registries) — централізовані сховища для зберігання та розповсюдження Docker-образів. Це аналог NuGet для .NET пакетів, npm для JavaScript, або Maven для Java. Найпопулярніший реєстр — Docker Hub, але існують і інші: Microsoft Container Registry (MCR), GitHub Container Registry (GHCR), Amazon ECR, Google Container Registry, та приватні реєстри для корпоративного використання.
У цій статті ми детально розглянемо, що таке реєстри, як працює Docker Hub, що таке MCR і чому він важливий для .NET розробників, як правильно іменувати образи, як аутентифікуватися, публікувати та завантажувати образи, та як забезпечити безпеку при роботі з реєстрами.
Що таке реєстр Docker-образів?
Визначення
Docker Registry — це сервіс для зберігання та розповсюдження Docker-образів. Реєстр організований у вигляді репозиторіїв (repositories), кожен з яких містить різні версії одного образу, позначені тегами (tags).
Аналогія з NuGet:
| Концепція | NuGet | Docker Registry |
|---|---|---|
| Сховище | nuget.org | Docker Hub |
| Пакет | Newtonsoft.Json | nginx |
| Версія | 13.0.3 | 1.25.3 |
| Повна адреса | Newtonsoft.Json@13.0.3 | nginx:1.25.3 |
Архітектура реєстру
Типи реєстрів
1. Публічні реєстри:
- Docker Hub — найбільший публічний реєстр (мільйони образів)
- Microsoft Container Registry (MCR) — офіційні образи Microsoft (.NET, SQL Server, Azure)
- GitHub Container Registry (GHCR) — інтеграція з GitHub
- Quay.io — реєстр від Red Hat
2. Приватні реєстри:
- Docker Hub Private Repositories — приватні репозиторії на Docker Hub
- Amazon ECR — Elastic Container Registry від AWS
- Google Container Registry (GCR) — реєстр від Google Cloud
- Azure Container Registry (ACR) — реєстр від Microsoft Azure
- Self-hosted Registry — власний реєстр на вашій інфраструктурі
Навіщо потрібні реєстри?
Розповсюдження:
- Передача образів між розробниками
- Розгортання на production серверах
- Використання в CI/CD pipeline
Версіонування:
- Зберігання різних версій образу (v1.0.0, v1.1.0, v2.0.0)
- Rollback до попередніх версій при проблемах
- Тестування різних версій паралельно
Централізація:
- Єдине джерело правди для образів
- Контроль доступу та аудит
- Сканування вразливостей
Оптимізація:
- Реєстри кешують шари образів
- Завантажуються лише змінені шари (економія трафіку)
- Географічно розподілені CDN для швидкого завантаження
Docker Hub: найбільший публічний реєстр
Що таке Docker Hub?
Docker Hub (hub.docker.com) — це офіційний публічний реєстр Docker, який містить:
- Офіційні образи (Official Images) — перевірені Docker Inc. образи (nginx, postgres, redis)
- Verified Publishers — образи від перевірених компаній (Microsoft, Oracle, MongoDB)
- Community Images — образи від спільноти (будь-хто може опублікувати)
Статистика (2026):
- 15+ мільйонів репозиторіїв
- 100+ мільярдів завантажень образів
- 10+ мільйонів розробників
Офіційні образи (Official Images)
Офіційні образи — це курировані образи, які підтримуються Docker Inc. та спільнотою. Вони позначені значком "Official Image" на Docker Hub.
Приклади:
nginx— веб-серверpostgres— база даних PostgreSQLredis— in-memory база данихnode— Node.js runtimepython— Python runtimeubuntu— операційна система Ubuntu
Переваги офіційних образів:
- ✅ Регулярні оновлення безпеки
- ✅ Детальна документація
- ✅ Оптимізовані за розміром та продуктивністю
- ✅ Підтримка спільноти
Завантаження офіційного образу:
# Повна адреса (рідко використовується)
docker pull docker.io/library/nginx:latest
# Скорочена адреса (стандарт)
docker pull nginx:latest
# Без тегу (автоматично :latest)
docker pull nginx
docker pull nginx, Docker автоматично розширює це до docker.io/library/nginx:latest. docker.io — це адреса Docker Hub, library — namespace для офіційних образів.Verified Publishers
Verified Publishers — це образи від перевірених компаній, які пройшли сертифікацію Docker Inc.
Приклади:
mcr.microsoft.com/dotnet/sdk— .NET SDK від Microsoftmcr.microsoft.com/mssql/server— SQL Server від Microsoftmongo— MongoDB від MongoDB Inc.mysql— MySQL від Oracle
Відмінності від офіційних образів:
| Характеристика | Official Images | Verified Publishers |
|---|---|---|
| Хто підтримує | Docker Inc. + спільнота | Компанія-власник |
| Namespace | library/ | Власний (напр. microsoft/) |
| Сертифікація | Docker Inc. | Docker Inc. |
| Приклад | nginx | mcr.microsoft.com/dotnet/sdk |
Community Images
Community Images — це образи, опубліковані будь-яким користувачем Docker Hub. Вони не проходять перевірку Docker Inc.
Формат іменування:
username/repository:tag
Приклади:
arakviel/myapp:latest— ваш особистий образbitnami/postgresql:15— PostgreSQL від Bitnamilinuxserver/plex:latest— Plex Media Server від LinuxServer.io
- Кількість завантажень (популярні образи безпечніші)
- Дату останнього оновлення (застарілі образи небезпечні)
- Наявність Dockerfile (прозорість)
- Відгуки та рейтинг
Структура Docker Hub
Репозиторій (Repository):
Репозиторій — це колекція образів з однією назвою, але різними тегами.
Приклад: репозиторій nginx
nginx:latest # Остання стабільна версія
nginx:1.25.3 # Конкретна версія
nginx:1.25.3-alpine # Версія на базі Alpine Linux
nginx:stable # Стабільна гілка
nginx:mainline # Розробницька гілка
Теги (Tags):
Теги — це мітки для різних версій образу в одному репозиторії.
Типові теги:
latest— остання версія (за замовчуванням)1.25.3— конкретна версія (Semantic Versioning)1.25— мінорна версія (автоматично оновлюється до 1.25.x)1— мажорна версія (автоматично оновлюється до 1.x.x)alpine— варіант на базі Alpine Linuxslim— мінімізована версіяdev— розробницька версія
latest: Тег latest не означає "найновіша версія". Це просто тег за замовчуванням, який може вказувати на будь-яку версію. Для production завжди використовуйте конкретні версії (напр. nginx:1.25.3), щоб уникнути несподіваних оновлень.Microsoft Container Registry (MCR)
Що таке MCR?
Microsoft Container Registry (mcr.microsoft.com) — це офіційний реєстр Microsoft для розповсюдження образів продуктів Microsoft. MCR є публічним реєстром (не потрібна аутентифікація для завантаження), але образи публікуються виключно Microsoft.
Чому MCR, а не Docker Hub?
До 2019 року Microsoft публікував образи на Docker Hub (напр. microsoft/dotnet). Але з 2019 року всі офіційні образи Microsoft перенесені на MCR з наступних причин:
- Контроль якості — Microsoft повністю контролює інфраструктуру
- Продуктивність — глобальна CDN для швидкого завантаження
- Безпека — сканування вразливостей перед публікацією
- Надійність — SLA 99.9% uptime
microsoft/dotnet, microsoft/aspnetcore) застарілі та більше не оновлюються. Завжди використовуйте образи з MCR (mcr.microsoft.com/dotnet/*).Основні образи .NET на MCR
1. .NET SDK — для збірки додатків
# .NET 8.0 SDK (повна версія)
docker pull mcr.microsoft.com/dotnet/sdk:8.0
# .NET 8.0 SDK на Alpine Linux (мінімальний розмір)
docker pull mcr.microsoft.com/dotnet/sdk:8.0-alpine
# Конкретна версія
docker pull mcr.microsoft.com/dotnet/sdk:8.0.3
Розмір: ~700 МБ (Debian), ~500 МБ (Alpine)
Використання: Збірка, тестування, розробка
2. .NET Runtime — для запуску консольних додатків
# .NET 8.0 Runtime
docker pull mcr.microsoft.com/dotnet/runtime:8.0
# .NET 8.0 Runtime на Alpine
docker pull mcr.microsoft.com/dotnet/runtime:8.0-alpine
Розмір: ~190 МБ (Debian), ~110 МБ (Alpine)
Використання: Консольні додатки, worker services
3. ASP.NET Core Runtime — для запуску веб-додатків
# ASP.NET Core 8.0 Runtime
docker pull mcr.microsoft.com/dotnet/aspnet:8.0
# ASP.NET Core 8.0 на Alpine
docker pull mcr.microsoft.com/dotnet/aspnet:8.0-alpine
Розмір: ~210 МБ (Debian), ~120 МБ (Alpine)
Використання: Web API, MVC, Blazor Server
4. .NET Runtime Dependencies — мінімальний образ
# Лише залежності для self-contained додатків
docker pull mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine
Розмір: ~15 МБ (Alpine)
Використання: Self-contained додатки з AOT compilation
Порівняння .NET образів
| Образ | Розмір | Містить | Використання |
|---|---|---|---|
dotnet/sdk:8.0 | ~700 МБ | SDK + Runtime + ASP.NET | Збірка, розробка |
dotnet/aspnet:8.0 | ~210 МБ | ASP.NET Runtime + .NET Runtime | Web додатки |
dotnet/runtime:8.0 | ~190 МБ | .NET Runtime | Консольні додатки |
dotnet/runtime-deps:8.0 | ~110 МБ | Лише системні залежності | Self-contained |
dotnet/runtime-deps:8.0-alpine | ~15 МБ | Мінімальні залежності | Self-contained + AOT |
- Збірка (multi-stage):
dotnet/sdk:8.0 - Production Web API/MVC:
dotnet/aspnet:8.0-alpine - Production Console App:
dotnet/runtime:8.0-alpine - Production Self-Contained:
dotnet/runtime-deps:8.0-alpine
Інші продукти Microsoft на MCR
SQL Server:
# SQL Server 2022 для Linux
docker pull mcr.microsoft.com/mssql/server:2022-latest
PowerShell:
# PowerShell Core
docker pull mcr.microsoft.com/powershell:latest
Azure CLI:
# Azure Command-Line Interface
docker pull mcr.microsoft.com/azure-cli:latest
Windows Server Core:
# Windows Server Core (лише для Windows containers)
docker pull mcr.microsoft.com/windows/servercore:ltsc2022
Документація та підтримка
Офіційна документація:
- Каталог образів: https://mcr.microsoft.com/catalog
- .NET образи: https://hub.docker.com/_/microsoft-dotnet
- Dockerfile'и: https://github.com/dotnet/dotnet-docker
Підтримка:
- GitHub Issues: https://github.com/dotnet/dotnet-docker/issues
- Stack Overflow: тег
docker+.net - Microsoft Docs: https://learn.microsoft.com/dotnet/core/docker/
Іменування Docker-образів
Повна анатомія імені образу
Повне ім'я Docker-образу складається з кількох частин:
[registry]/[namespace]/[repository]:[tag]@[digest]
Приклади:
# Повна адреса
mcr.microsoft.com/dotnet/sdk:8.0@sha256:abc123...
# Без digest (найчастіше)
mcr.microsoft.com/dotnet/sdk:8.0
# Без тегу (автоматично :latest)
mcr.microsoft.com/dotnet/sdk
# Без registry (автоматично docker.io)
nginx:1.25.3
# Мінімальна форма (docker.io/library/nginx:latest)
nginx
Компоненти імені
1. Registry (реєстр)
Адреса реєстру, де зберігається образ.
docker.io # Docker Hub (за замовчуванням)
mcr.microsoft.com # Microsoft Container Registry
ghcr.io # GitHub Container Registry
gcr.io # Google Container Registry
quay.io # Quay.io від Red Hat
localhost:5000 # Локальний приватний реєстр
Якщо registry не вказано, Docker використовує docker.io за замовчуванням.
2. Namespace (простір імен)
Організація або користувач, який володіє образом.
library/ # Офіційні образи Docker Hub (можна опустити)
microsoft/ # Namespace Microsoft на Docker Hub (застарілий)
arakviel/ # Ваш особистий namespace
mycompany/ # Namespace вашої компанії
Для офіційних образів Docker Hub namespace library/ можна опустити:
docker pull nginx
# Еквівалентно: docker pull docker.io/library/nginx:latest
3. Repository (репозиторій)
Назва образу (проєкту, додатку, сервісу).
nginx # Веб-сервер Nginx
postgres # База даних PostgreSQL
myapp # Ваш додаток
api-gateway # API Gateway вашої компанії
4. Tag (тег)
Версія або варіант образу.
latest # За замовчуванням
8.0 # Мажорна версія
8.0.3 # Повна версія (Semantic Versioning)
8.0-alpine # Варіант на Alpine Linux
dev # Розробницька версія
v1.2.3 # Версія з префіксом v
20240414 # Версія за датою
Якщо тег не вказано, Docker використовує latest за замовчуванням.
5. Digest (хеш)
SHA256 хеш образу для гарантованої ідентифікації.
sha256:abc123def456...
Digest гарантує, що ви завантажите точно той самий образ, навіть якщо тег змінився.
Правила іменування
Допустимі символи:
- Lowercase літери:
a-z - Цифри:
0-9 - Спеціальні символи:
-,_,.,/
Недопустимі символи:
- Uppercase літери:
A-Z(автоматично конвертуються в lowercase) - Пробіли
- Спеціальні символи:
@,#,$,%, тощо (крім/для namespace)
Приклади:
# ✅ Правильно
myapp
my-app
my_app
my.app
mycompany/myapp
mycompany/my-api-gateway
# ❌ Неправильно
MyApp # Uppercase (буде конвертовано в myapp)
my app # Пробіл
my@app # Недопустимий символ
Стратегії тегування
1. Semantic Versioning (рекомендовано для production)
myapp:1.0.0 # Повна версія
myapp:1.0 # Мінорна версія (автоматично оновлюється до 1.0.x)
myapp:1 # Мажорна версія (автоматично оновлюється до 1.x.x)
2. Git-based (для CI/CD)
myapp:main # Гілка main
myapp:develop # Гілка develop
myapp:feature-123 # Feature branch
myapp:abc123 # Git commit SHA (короткий)
myapp:abc123def456 # Git commit SHA (повний)
3. Date-based (для щоденних збірок)
myapp:20260414 # Дата (YYYYMMDD)
myapp:2026-04-14 # Дата з дефісами
myapp:2026.04.14 # Дата з крапками
4. Environment-based (для різних середовищ)
myapp:dev # Development
myapp:staging # Staging
myapp:prod # Production
myapp:latest # Остання версія (не рекомендовано для production)
5. Комбінований підхід (найкраща практика)
myapp:1.0.0-alpine # Версія + варіант
myapp:1.0.0-dev # Версія + середовище
myapp:v1.0.0-20260414 # Версія + дата
myapp:1.0.0-abc123 # Версія + Git SHA
latest для production! Тег latest не гарантує стабільності та може змінюватися без попередження. Завжди використовуйте конкретні версії (напр. myapp:1.0.0) для production розгортань.Робота з реєстрами: аутентифікація та публікація
Аутентифікація: docker login
Перед публікацією образів у приватний реєстр або приватний репозиторій на Docker Hub потрібно аутентифікуватися.
Синтаксис:
docker login [OPTIONS] [SERVER]
Приклади:
# Аутентифікація на Docker Hub
docker login
# Вивід:
# Username: arakviel
# Password: ********
# Login Succeeded
# MCR — публічний реєстр, аутентифікація не потрібна для pull
docker pull mcr.microsoft.com/dotnet/sdk:8.0
# Аутентифікація на GHCR
docker login ghcr.io
# Username: ваш GitHub username
# Password: GitHub Personal Access Token (PAT)
# Аутентифікація на ACR
docker login myregistry.azurecr.io
# Username: з Azure Portal
# Password: з Azure Portal
Опції:
# Передати username через параметр
docker login -u arakviel
# Передати password через stdin (безпечніше для CI/CD)
echo $DOCKER_PASSWORD | docker login -u arakviel --password-stdin
# Вказати конкретний реєстр
docker login ghcr.io -u arakviel
Де зберігаються credentials?
# Linux/macOS
~/.docker/config.json
# Windows
%USERPROFILE%\.docker\config.json
Приклад config.json:
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "YXJha3ZpZWw6cGFzc3dvcmQ="
},
"ghcr.io": {
"auth": "Z2l0aHVidXNlcjp0b2tlbg=="
}
}
}
config.json містить закодовані (base64) credentials. Це не шифрування, а лише кодування. Не діліться цим файлом та не комітьте його в Git. Для production використовуйте Docker Credential Helpers або секрети CI/CD.Вихід з реєстру:
# Вийти з Docker Hub
docker logout
# Вийти з конкретного реєстру
docker logout ghcr.io
Тегування образів: docker tag
Перед публікацією образу потрібно присвоїти йому правильне ім'я, яке включає адресу реєстру та ваш namespace.
Синтаксис:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
Приклад: підготовка образу для Docker Hub
# Крок 1: Збудувати образ локально
docker build -t myapp .
# Локальне ім'я: myapp:latest
# Крок 2: Перетегувати для Docker Hub
docker tag myapp:latest arakviel/myapp:latest
docker tag myapp:latest arakviel/myapp:1.0.0
# Тепер у вас 3 образи (насправді це один образ з 3 іменами):
# - myapp:latest
# - arakviel/myapp:latest
# - arakviel/myapp:1.0.0
Перевірка:
docker images | grep myapp
Вивід:
myapp latest abc123def456 2 minutes ago 210MB
arakviel/myapp latest abc123def456 2 minutes ago 210MB
arakviel/myapp 1.0.0 abc123def456 2 minutes ago 210MB
docker tagне копіює образ, а лише створює нове ім'я (alias) для існуючого образу. Всі три імені вказують на той самий образ (однаковий IMAGE ID: abc123def456).Множинне тегування:
# Створити кілька тегів одразу
docker tag myapp:latest arakviel/myapp:latest
docker tag myapp:latest arakviel/myapp:1.0.0
docker tag myapp:latest arakviel/myapp:1.0
docker tag myapp:latest arakviel/myapp:1
Тегування для різних реєстрів:
# Docker Hub
docker tag myapp:latest arakviel/myapp:1.0.0
# GitHub Container Registry
docker tag myapp:latest ghcr.io/arakviel/myapp:1.0.0
# Azure Container Registry
docker tag myapp:latest myregistry.azurecr.io/myapp:1.0.0
Публікація образів: docker push
Після тегування образ можна опублікувати в реєстр.
Синтаксис:
docker push [OPTIONS] NAME[:TAG]
Приклад: публікація на Docker Hub
Крок 1: Аутентифікація
docker login
Крок 2: Збірка образу
docker build -t myapp .
Крок 3: Тегування
docker tag myapp:latest arakviel/myapp:1.0.0
docker tag myapp:latest arakviel/myapp:latest
Крок 4: Публікація
docker push arakviel/myapp:1.0.0
docker push arakviel/myapp:latest
Вивід docker push:
The push refers to repository [docker.io/arakviel/myapp]
5f70bf18a086: Pushed
d0e91e46e4f8: Pushed
1.0.0: digest: sha256:abc123def456... size: 1234
Що відбувається при push:
- Docker аналізує шари образу
- Перевіряє, які шари вже є в реєстрі
- Завантажує лише нові або змінені шари
- Створює manifest (опис образу)
- Повертає digest (SHA256 хеш образу)
Публікація всіх тегів:
# Опублікувати всі теги репозиторію
docker push arakviel/myapp --all-tags
Публікація в інші реєстри:
# GitHub Container Registry
docker push ghcr.io/arakviel/myapp:1.0.0
# Azure Container Registry
docker push myregistry.azurecr.io/myapp:1.0.0
# Приватний реєстр
docker push localhost:5000/myapp:1.0.0
Завантаження образів: docker pull
Завантаження образу з реєстру.
Синтаксис:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
Приклади:
# Завантажити останню версію
docker pull arakviel/myapp:latest
# Завантажити конкретну версію
docker pull arakviel/myapp:1.0.0
# Завантажити за digest (гарантована ідентичність)
docker pull arakviel/myapp@sha256:abc123def456...
# Завантажити з іншого реєстру
docker pull ghcr.io/arakviel/myapp:1.0.0
Що відбувається при pull:
- Docker перевіряє, чи є образ локально
- Якщо немає — завантажує manifest з реєстру
- Перевіряє, які шари вже є локально
- Завантажує лише відсутні шари
- Збирає образ з шарів
Вивід docker pull:
1.0.0: Pulling from arakviel/myapp
5f70bf18a086: Already exists
d0e91e46e4f8: Pull complete
Digest: sha256:abc123def456...
Status: Downloaded newer image for arakviel/myapp:1.0.0
docker.io/arakviel/myapp:1.0.0
Примусове завантаження:
# Завантажити образ, навіть якщо він вже є локально
docker pull arakviel/myapp:latest --platform linux/amd64
Повний workflow: від збірки до публікації
Сценарій: Опублікувати .NET Web API на Docker Hub
Крок 1: Створити Dockerfile
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["MyApp.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]
Крок 2: Збудувати образ
docker build -t myapp .
Крок 3: Протестувати локально
docker run -p 8080:8080 myapp
curl http://localhost:8080/health
Крок 4: Аутентифікуватися на Docker Hub
docker login
Крок 5: Перетегувати образ
docker tag myapp:latest arakviel/myapp:1.0.0
docker tag myapp:latest arakviel/myapp:latest
Крок 6: Опублікувати
docker push arakviel/myapp:1.0.0
docker push arakviel/myapp:latest
Крок 7: Перевірити на Docker Hub
Відкрийте https://hub.docker.com/r/arakviel/myapp
Результат:
- Образ доступний для завантаження:
docker pull arakviel/myapp:1.0.0 - Можна використовувати на будь-якому сервері
- Можна інтегрувати в CI/CD pipeline
Безпека Docker-образів
Довіра до образів
Не всі образи на Docker Hub безпечні. Перед використанням образу перевірте:
1. Джерело образу
- ✅ Official Images — найбезпечніші (nginx, postgres, redis)
- ✅ Verified Publishers — перевірені компанії (Microsoft, MongoDB, Oracle)
- ⚠️ Community Images — перевіряйте автора та репутацію
2. Популярність
arakviel/myapp
10M+ downloads ✅ Популярний (ймовірно безпечний)
100 downloads ⚠️ Непопулярний (перевірте код)
3. Дата оновлення
Last updated: 2 days ago ✅ Активно підтримується
Last updated: 2 years ago ❌ Застарілий (вразливості)
4. Наявність Dockerfile
- ✅ Dockerfile доступний на GitHub — можна перевірити код
- ❌ Dockerfile відсутній — непрозорий образ
5. Відгуки та рейтинг
- Перевірте коментарі на Docker Hub
- Шукайте issues на GitHub
- Перевірте Security Advisories
Сканування вразливостей: docker scout
Docker Scout — вбудований інструмент для сканування вразливостей в образах.
Увімкнення Docker Scout:
# Docker Scout увімкнений за замовчуванням у Docker Desktop 4.17+
docker scout version
Сканування образу:
# Сканувати локальний образ
docker scout cves myapp:latest
# Сканувати образ з реєстру
docker scout cves arakviel/myapp:1.0.0
Вивід:
✓ Image stored for indexing
✓ Indexed 150 packages
Overview:
│ Analyzed Image
────────────────────┼─────────────────────────────
Target │ myapp:latest
digest │ abc123def456
platform │ linux/amd64
vulnerabilities │ 2C 5H 8M 3L
size │ 210 MB
packages │ 150
Packages and Vulnerabilities:
0C 1H 0M 0L openssl 3.0.2-0ubuntu1.10
pkg:deb/ubuntu/openssl@3.0.2-0ubuntu1.10
✗ HIGH CVE-2023-12345
https://scout.docker.com/v/CVE-2023-12345
Рекомендації:
# Отримати рекомендації щодо виправлення
docker scout recommendations myapp:latest
Порівняння версій:
# Порівняти дві версії образу
docker scout compare myapp:1.0.0 --to myapp:1.1.0
docker scout у CI/CD pipeline, щоб автоматично сканувати образи перед публікацією. Це допоможе виявити вразливості на ранніх етапах розробки.Альтернативні інструменти сканування
1. Trivy (від Aqua Security)
# Встановлення (macOS)
brew install trivy
# Сканування образу
trivy image myapp:latest
# Сканування з фільтрацією за severity
trivy image --severity HIGH,CRITICAL myapp:latest
# Експорт у JSON
trivy image -f json -o report.json myapp:latest
2. Snyk
# Встановлення
npm install -g snyk
# Аутентифікація
snyk auth
# Сканування образу
snyk container test myapp:latest
3. Grype (від Anchore)
# Встановлення (macOS)
brew install grype
# Сканування образу
grype myapp:latest
Content Trust: підписування образів
Docker Content Trust (DCT) дозволяє підписувати образи для гарантії їх автентичності.
Увімкнення Content Trust:
# Увімкнути для всіх операцій
export DOCKER_CONTENT_TRUST=1
# Тепер docker pull та docker push перевірятимуть підписи
docker pull nginx:latest
Підписування образу при публікації:
# Увімкнути Content Trust
export DOCKER_CONTENT_TRUST=1
# Публікація автоматично підпише образ
docker push arakviel/myapp:1.0.0
# Вивід:
# Signing and pushing trust metadata
# Enter passphrase for root key:
# Enter passphrase for new repository key:
Перевірка підпису:
# Завантажити лише підписані образи
export DOCKER_CONTENT_TRUST=1
docker pull arakviel/myapp:1.0.0
# Якщо образ не підписаний:
# Error: remote trust data does not exist
Найкращі практики безпеки
1. Використовуйте офіційні базові образи
# ✅ Офіційний образ Microsoft
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
# ❌ Невідомий community образ
FROM randomuser/dotnet-custom:latest
2. Вказуйте конкретні версії
# ✅ Конкретна версія
FROM mcr.microsoft.com/dotnet/aspnet:8.0.3-alpine
# ❌ Тег latest (може змінитися)
FROM mcr.microsoft.com/dotnet/aspnet:latest
3. Мінімізуйте attack surface
# ✅ Alpine образ (мінімальний розмір)
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
# ✅ Distroless образ (лише runtime, без shell)
FROM gcr.io/distroless/dotnet:8
4. Не запускайте від root
# ✅ Створити non-root користувача
RUN addgroup -g 1000 appuser && adduser -u 1000 -G appuser -s /bin/sh -D appuser
USER appuser
5. Не зберігайте секрети в образах
# ❌ Секрети в ENV (залишаються в шарах)
ENV DATABASE_PASSWORD=mysecretpassword
# ✅ Використовуйте BuildKit secrets
RUN --mount=type=secret,id=db_password \
cat /run/secrets/db_password > /tmp/password
6. Регулярно оновлюйте базові образи
# Перебудувати образ з оновленим базовим образом
docker build --pull -t myapp:latest .
7. Сканування в CI/CD
# GitHub Actions приклад
- name: Scan image
run: |
docker scout cves myapp:latest --exit-code
Приватні реєстри
Коли потрібен приватний реєстр?
Сценарії використання:
- Корпоративні додатки — код не повинен бути публічним
- Комерційні продукти — захист інтелектуальної власності
- Compliance — вимоги регуляторів (GDPR, HIPAA)
- Контроль доступу — обмеження доступу для команди
- Швидкість — локальний реєстр швидше за публічний
Типи приватних реєстрів
1. Docker Hub Private Repositories
# Створити приватний репозиторій на hub.docker.com
# Settings → Repositories → Create Repository → Private
# Публікація (потрібна аутентифікація)
docker push arakviel/private-app:1.0.0
# Завантаження (потрібна аутентифікація)
docker login
docker pull arakviel/private-app:1.0.0
Обмеження безкоштовного плану:
- 1 приватний репозиторій
- Необмежена кількість публічних репозиторіїв
2. GitHub Container Registry (GHCR)
# Аутентифікація (потрібен GitHub PAT)
echo $GITHUB_TOKEN | docker login ghcr.io -u arakviel --password-stdin
# Публікація
docker tag myapp:latest ghcr.io/arakviel/myapp:1.0.0
docker push ghcr.io/arakviel/myapp:1.0.0
# Завантаження
docker pull ghcr.io/arakviel/myapp:1.0.0
Переваги:
- ✅ Безкоштовні приватні репозиторії
- ✅ Інтеграція з GitHub Actions
- ✅ Автоматичне сканування вразливостей
3. Azure Container Registry (ACR)
# Створити реєстр через Azure CLI
az acr create --name myregistry --resource-group mygroup --sku Basic
# Аутентифікація
az acr login --name myregistry
# Публікація
docker tag myapp:latest myregistry.azurecr.io/myapp:1.0.0
docker push myregistry.azurecr.io/myapp:1.0.0
4. Self-Hosted Registry
Запустити власний реєстр на вашій інфраструктурі:
# Запустити реєстр локально
docker run -d -p 5000:5000 --name registry registry:2
# Публікація
docker tag myapp:latest localhost:5000/myapp:1.0.0
docker push localhost:5000/myapp:1.0.0
# Завантаження
docker pull localhost:5000/myapp:1.0.0
Production-ready self-hosted registry:
# docker-compose.yml
version: '3.8'
services:
registry:
image: registry:2
ports:
- "5000:5000"
environment:
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- ./data:/data
- ./auth:/auth
Практичні завдання
Завдання 1: Публікація образу на Docker Hub
Мета: Створити та опублікувати .NET Web API на Docker Hub.
Кроки:
- Створіть простий ASP.NET Core Web API проєкт
- Створіть оптимізований Dockerfile (multi-stage)
- Зберіть образ локально
- Протестуйте образ локально
- Зареєструйтеся на Docker Hub (якщо ще не зареєстровані)
- Аутентифікуйтеся через
docker login - Перетегуйте образ з вашим Docker Hub username
- Опублікуйте образ з тегами
latestта1.0.0 - Перевірте образ на Docker Hub
- Завантажте образ на іншому комп'ютері або видаліть локально та завантажте знову
Очікуваний результат: Образ доступний за адресою docker pull yourusername/myapp:1.0.0
Завдання 2: Порівняння розмірів образів MCR
Мета: Дослідити різницю між різними варіантами .NET образів.
Кроки:
- Завантажте наступні образи:
mcr.microsoft.com/dotnet/sdk:8.0mcr.microsoft.com/dotnet/aspnet:8.0mcr.microsoft.com/dotnet/aspnet:8.0-alpinemcr.microsoft.com/dotnet/runtime:8.0-alpine
- Порівняйте розміри через
docker images - Створіть таблицю порівняння
- Зробіть висновок, який образ використовувати для production
Питання для аналізу:
- Яка різниця в розмірі між Debian та Alpine варіантами?
- Чому SDK образ такий великий?
- Який образ оптимальний для Web API?
Завдання 3: Сканування вразливостей
Мета: Навчитися виявляти вразливості в образах.
Кроки:
- Створіть Dockerfile на базі застарілого образу (напр.
ubuntu:18.04) - Зберіть образ
- Проскануйте образ через
docker scout cves - Проаналізуйте знайдені вразливості
- Оновіть базовий образ до актуальної версії
- Проскануйте знову та порівняйте результати
Очікуваний результат: Кількість вразливостей зменшиться після оновлення базового образу.
Завдання 4: Стратегії тегування
Мета: Розробити стратегію тегування для вашого проєкту.
Кроки:
- Створіть образ вашого додатку
- Застосуйте різні стратегії тегування:
- Semantic Versioning:
1.0.0,1.0,1 - Git-based:
main,abc123(commit SHA) - Date-based:
20260414 - Environment-based:
dev,staging,prod
- Semantic Versioning:
- Опублікуйте всі варіанти
- Перевірте на Docker Hub
Питання для аналізу:
- Яка стратегія найкраща для production?
- Як автоматизувати тегування в CI/CD?
- Чи потрібен тег
latest?
Резюме
У цій статті ми детально розглянули реєстри Docker-образів та роботу з ними:
Реєстри:
- Реєстр — це централізоване сховище для Docker-образів
- Docker Hub — найбільший публічний реєстр (15M+ репозиторіїв)
- MCR — офіційний реєстр Microsoft для .NET та інших продуктів
- Приватні реєстри — для корпоративних та комерційних додатків
Docker Hub:
- Офіційні образи — курировані Docker Inc. (nginx, postgres)
- Verified Publishers — перевірені компанії (Microsoft, MongoDB)
- Community Images — образи від спільноти (перевіряйте безпеку!)
Microsoft Container Registry:
mcr.microsoft.com/dotnet/sdk— для збіркиmcr.microsoft.com/dotnet/aspnet— для Web APImcr.microsoft.com/dotnet/runtime— для консольних додатків- Alpine варіанти — мінімальний розмір (економія 50-70%)
Іменування образів:
- Повний формат:
registry/namespace/repository:tag@digest - Скорочений формат:
nginx:1.25.3(автоматичноdocker.io/library/nginx:1.25.3) - Стратегії тегування: Semantic Versioning, Git-based, Date-based
Робота з реєстрами:
docker login— аутентифікація в реєстріdocker tag— перетегування образу (створення alias)docker push— публікація образу (завантажуються лише нові шари)docker pull— завантаження образу (завантажуються лише відсутні шари)
Безпека:
- Перевіряйте джерело образів (Official > Verified > Community)
- Сканування вразливостей:
docker scout, Trivy, Snyk - Content Trust — підписування образів для автентичності
- Найкращі практики: конкретні версії, non-root user, мінімальні образи
myapp:1.0.0), а не latest. Публікуйте кілька тегів одночасно: повну версію (1.0.0), мінорну (1.0), мажорну (1) та latest для зручності розробників.Build Context та кешування шарів
Оптимізація швидкості збірки Docker-образів через правильне використання build context, .dockerignore та механізму кешування
Контейнеризація .NET додатків
Повний цикл контейнеризації C# додатків — від консольних програм до ASP.NET Core Web API з production-ready конфігурацією