Перейти к содержанию

Работа с OCI / Docker

CodeScoring.Save реализует стандарт OCI Distribution Spec на префиксе /v2/, поддерживая Docker, Helm OCI-чарты и любые другие OCI-артефакты (например, oras).

Proxy-репозиторий

curl -X POST https://save.example.com/api/v1/repos \
  -H "Content-Type: application/json" \
  -u "<username>:<password>" \
  -d '{
    "project": "common",
    "name": "dockerhub-proxy",
    "format": "docker",
    "repository_type": "proxy",
    "remote_url": "https://registry-1.docker.io",
    "cache_ttl": 86400
  }'

Для образов с одним именем (без слешей) применяется стандартная нормализация Docker Hub library/<image>.

Hosted-репозиторий

curl -X POST https://save.example.com/api/v1/repos \
  -H "Content-Type: application/json" \
  -u "<username>:<password>" \
  -d '{
    "project": "common",
    "name": "docker-hosted",
    "format": "docker",
    "repository_type": "hosted"
  }'

URL-схема

Базовая схема — путевая, как требует Docker / OCI:

<host>/<project>/<repository>/<image>:<tag>

Дополнительно поддерживается Nexus-совместимая маршрутизация плоских URL (flat-alias). Для совместимых репозиториев <project>/<repository> префикс заменяется коротким алиасом или вовсе опускается.

Настройка клиента

Docker / Podman

# Логин
docker login save.example.com

# Pull через proxy
docker pull save.example.com/common/dockerhub-proxy/library/nginx:latest

# Push в hosted
docker tag myapp:latest save.example.com/common/docker-hosted/myapp:1.0.0
docker push save.example.com/common/docker-hosted/myapp:1.0.0

Anonymous read и docker login

Endpoint /v2/ всегда отвечает 401 с challenge-заголовком WWW-Authenticate: Bearer realm=..., даже если репозиторий допускает анонимное чтение. Это нужно, чтобы Docker-клиент корректно выполнил cycle 401 → retry → 200 и затем при необходимости отправил Basic Auth. Это требование OCI Distribution Spec.

Robot-аккаунты в CI

Для CI/CD используйте robot-аккаунт: docker login -u 'sa$<robot-name>' -p '<api-key>' save.example.com. То же самое работает для helm registry login и oras login. Подробнее — в общем разделе Аутентификация.

Helm

CodeScoring.Save принимает Helm-чарты как обычные OCI-артефакты. Push/pull выполняется стандартными командами helm:

# Логин (Helm 3.8+)
helm registry login save.example.com -u <username>

# Push
helm package ./mychart                                          # → mychart-0.1.0.tgz
helm push mychart-0.1.0.tgz oci://save.example.com/common/docker-hosted

# Pull
helm pull oci://save.example.com/common/docker-hosted/mychart --version 0.1.0

Plain HTTP для тестовых стендов

Для тестовых стендов без TLS используйте флаг --plain-http (Helm 3.13+):

helm push mychart-0.1.0.tgz oci://save.example.com/common/docker-hosted --plain-http

oras

oras работает с любым OCI-совместимым артефактом — конфигами, политиками, SBOM, бинарями и т. д.:

# Push произвольного файла как OCI-артефакта
oras push save.example.com/common/docker-hosted/configs/app:v1 \
  -u <username> -p <password> \
  ./config.yaml:application/vnd.example.config

# Pull
oras pull save.example.com/common/docker-hosted/configs/app:v1 \
  -u <username> -p <password>

containerd / nerdctl

nerdctl login save.example.com
nerdctl pull save.example.com/common/dockerhub-proxy/library/alpine:latest

Маршрутизация плоских URL

Save поддерживает Nexus-совместимое плоское пространство имён для бесшовной миграции с Nexus / Artifactory: репозиторий можно сконфигурировать с префиксом-алиасом, чтобы он отвечал на запросы без <project>/<repository> в пути.

Применяется longest-prefix matching:

  • docker pull save.example.com/common/external/golang:1.24.1 — попадёт в репозиторий, чей flat-alias = common/external/.
  • docker pull save.example.com/johnny-depp:v1 — попадёт в catch-all hosted-репозиторий (если он сконфигурирован).

При создании репозитория с flat-alias указываются параметры flat_alias_prefix и/или is_catch_all. Префиксы валидируются на уникальность.

Миграция URL репозитория

Сценарий использования: миграция Docker-реестра из Nexus / Artifactory на CodeScoring.Save.

Источник URL до миграции URL после миграции (с проектом) URL после миграции (flat-alias)
Nexus nexus.host.ru:5000/library/nginx:latest save.example.com/common/dockerhub-proxy/library/nginx:latest save.example.com/library/nginx:latest
Artifactory jfrog.host.ru/docker-remote/library/nginx save.example.com/common/dockerhub-proxy/library/nginx save.example.com/library/nginx
Docker Hub docker.io/library/postgres:16 save.example.com/common/dockerhub-proxy/library/postgres:16 save.example.com/library/postgres:16

Flat-alias-вариант ничего не требует от клиента — старые скрипты, в которых жёстко прописано nexus.host.ru/library/nginx, начинают работать после простой замены хоста.

Устранение неполадок

Проверка /v2/

curl -i https://save.example.com/v2/
# Ожидается: HTTP/1.1 401 Unauthorized с Www-Authenticate: Bearer realm=...

Проверка эндпоинта токена

curl -u "<username>:<password>" \
  "https://save.example.com/v2/token?service=save.example.com&scope=repository:common/dockerhub-proxy/library/nginx:pull"

В ответе — JSON с полем token, содержащим короткоживущий Docker v2 JWT.

Список тегов

curl -u "<username>:<password>" \
  https://save.example.com/v2/<project>/<repository>/<image>/tags/list

Состояние сервиса

curl https://save.example.com/health

Аудит по репозиторию

curl -u "<username>:<password>" \
  "https://save.example.com/api/v1/admin/audit?resource_type=repository&q=dockerhub-proxy&limit=50"
Страница была полезна?