⚠️ Проект находится в активной разработке. API и функциональность могут существенно изменяться. Используйте с осторожностью.
Go-инструмент для создания и публикации OCI-артефактов из разнородных источников.
oci-packer — инструмент на языке Go для упаковки произвольных источников (файлы, директории, OCI-образы, HTTP-ресурсы)
в OCI-совместимые артефакты и их публикации в реестры контейнеров.
Проект разработан компанией Arenadata и предназначен для управления дистрибуцией артефактов в инфраструктуре на базе OCI (Open Container Initiative), в том числе для сценариев, выходящих за рамки классических Docker-образов: конфигурации, шаблоны, бинарные данные, слои с зависимостями.
ORAS (OCI Registry As Storage) — референсный CLI-инструмент CNCF для работы с OCI-артефактами:
позволяет загружать и скачивать отдельные файлы или группы файлов с явным указанием их типов. oci-packer решает
смежную задачу, но с принципиально иным подходом:
| Критерий | ORAS | oci-packer |
|---|---|---|
| Описание артефакта | Императивное: файлы и типы передаются аргументами CLI | Декларативное: YAML Pack-файл описывает всю структуру |
| Источники | Локальные файлы и директории | Файлы, директории, HTTP/HTTPS, OCI-реестры, S3 |
| Мультиплатформенность | Ограниченная поддержка индексов | Нативное создание OCI Index с platform-вариантами |
| Конфигурационный дескриптор | Фиксированный пустой config | Произвольный config-дескриптор из любого источника |
| Интеграция в CI/CD | Push-команды в скриптах | Один файл — полная спецификация артефакта |
| Монтирование из реестра | Нет | Поддержка oci://-источников с mount из реестра |
| Зрелость | Стабильный, CNCF Sandbox | Work In Progress |
oci-packer ориентирован на сценарии, где структура артефакта сложна и воспроизводима: несколько источников разных
типов, мультиплатформенные сборки, кастомные config-объекты — всё описывается в одном файле и воспроизводится
детерминированно.
- Множество типов источников: файлы (
file://), директории (dir://), HTTP/HTTPS-ресурсы (http://,https://), OCI/Docker-реестры (oci://,docker://), S3 (s3://, в разработке) - Мультиплатформенные сборки: создание индекс-манифестов с вариантами для разных архитектур (linux/amd64, linux/arm64 и т.д.)
- OCI Layout: поддержка локального формата
oci-layoutс распаковкой слоёв - Публикация в реестр: прямая загрузка артефактов через OCI Distribution API
- Аннотации и метаданные: гибкое управление OCI-аннотациями на уровне артефакта, манифеста и каждого слоя
- Конфигурационные дескрипторы: кастомные
config-объекты вместо стандартного пустого конфига - CLI-интерфейс: построен на базе Cobra
- Структурированное логирование: через logrus
oci-packer/
├── cmd/ # CLI-команды (pack, copy, proxy, ...)
├── internal/
│ └── logger/ # Внутренний логгер
├── pkg/
│ ├── registry/ # Клиент OCI-реестра, pusher/puller
│ │ └── reference/ # Парсинг схем источников (file://, dir://, oci://, ...)
│ └── http/ # HTTP-клиент
├── builder.go # Оркестрация сборки (index / manifest)
├── handlers.go # Обработчики источников (file, dir, http, oci)
├── pack.go # Модели данных, валидация, загрузка Pack-файла
├── pusher.go # Публикация манифестов и слоёв в реестр
└── utils.go # Утилиты: digest, MediaType, дескрипторы
Ключевые типы:
Pack— корневая структура, описывающая артефакт (тип, метаданные, список элементов)Descriptor— описание одного источника (откуда взять, тип, платформа, аннотации)ConvertHandler— функциональный тип, преобразующий источник в набор дескрипторовPusher— интерфейс для записи манифеста/индекса в реестр
Поток выполнения:
Pack-файл (YAML) → Validate → handleItem (выбор хендлера по схеме)
├── file:// → fileHandler
├── dir:// → walkDirHandler (обход директории)
├── http(s):// → httpHandler (скачивание → временный файл)
└── oci:// → ociHandler (монтирование из реестра)
→ makeManifest / makeIndex → Push → OCI Registry / OCI Layout
Pack-файл — декларативный YAML, описывающий содержимое артефакта:
# Тип артефакта (MIME-тип)
type: application/vnd.example.artifact
# Глобальные аннотации
annotations:
org.opencontainers.image.title: "Мой артефакт"
org.opencontainers.image.vendor: "Arenadata"
# Конфигурационный дескриптор (опционально)
config:
from: file://schema.json
type: application/vnd.example.schema
# Список элементов для упаковки
items:
# Файл
- from: file://config.tmpl
type: application/vnd.example.template
annotations:
description: "Конфигурационный шаблон"
# Директория (все файлы рекурсивно)
- from: dir://data/
type: application/vnd.example.data
# HTTP-ресурс
- from: https://example.com/binary.tar.gz
# OCI-образ из реестра (с указанием платформы для мульти-манифеста)
- from: oci://registry.example.com/myimage:latest
platform: linux/amd64
- from: oci://registry.example.com/myimage:latest
platform: linux/arm64| Схема | Пример | Описание |
|---|---|---|
file:// |
file://path/to/file.tar.gz |
Локальный файл |
dir:// |
dir://path/to/directory/ |
Все файлы директории |
http:// / https:// |
https://example.com/data.bin |
HTTP-загрузка |
oci:// / docker:// |
oci://registry/image:tag |
OCI/Docker-реестр |
s3:// |
s3://bucket/key |
Amazon S3 (в разработке) |
При наличии поля platform или источника oci:// автоматически создаётся OCI Index (мульти-манифест):
type: application/vnd.example.multiarch
items:
- from: oci://registry.example.com/app:v1.0
platform: linux(v8)/amd64
- from: oci://registry.example.com/app:v1.0-arm
platform: linux/arm64Готовые бинарники для Linux, macOS и Windows публикуются на
странице релизов (собираются GoReleaser).
Скачайте архив под свою платформу и распакуйте бинарь в PATH:
tar -xzf oci-packer_*_linux_amd64.tar.gz
sudo install oci-packer /usr/local/bin/Через Go:
go install github.com/arenadata/oci-packer/cmd/oci-packer@latestИли сборка из исходников:
git clone https://github.com/arenadata/oci-packer.git
cd oci-packer
go build ./cmd/...Требования: Go 1.26+
Полная документация по командам и решение проблем — в каталоге docs/:
- Хаб документации — указатель на все команды
pack·copy·proxy·mount/umount·delete·list- Troubleshooting — типичные ошибки и их устранение
Одна команда list работает в двух режимах в зависимости от ссылки: без
:repo:tag — список образов и артефактов в OCI layout; со ссылкой на образ —
компоненты (config и слои) выбранного Pack, с именами файлов из аннотации
org.opencontainers.image.title.
# Список образов в layout
oci-packer list oci://./layout
# Компоненты одного Pack (для индекса — по каждой платформе)
oci-packer list oci://./layout:example/service:v1Подробности — в docs/list.md.
Удаляет образ из OCI layout и собирает мусор — блобы, на которые больше никто не ссылается. Общие слои, используемые другими образами в этом layout, сохраняются; смонтированный слой (unpack-режим, Linux) удалить нельзя, пока он не размонтирован.
# Удалить образ; общие с другими образами слои остаются
oci-packer delete oci://./layout:example/service:v1
# Короткий алиас
oci-packer rm oci://./layout:example/worker:v2Подробности — в docs/delete.md.
# Упаковать и опубликовать в реестр
oci-packer -f artifact.yaml registry.example.com/myartifact:v1.0
# Указать временную директорию для HTTP-загрузок
oci-packer -f artifact.yaml registry.example.com/myartifact:v1.0 --tmp-dir /tmp/packeroci-packer copy \
cr://source-registry.example.com/image:tag \
oci://target/directory:image:tag
# Скопировать только одну платформу из мультиплатформенного образа
oci-packer copy --platform linux/arm64 \
cr://source-registry.example.com/image:tag \
oci://target/directory:image:tagПри --platform из OCI Index выбирается манифест нужной платформы, и в назначение
копируется одноплатформенный образ. Формат — ОС/архитектура[/вариант], напр.
linux/amd64, linux/arm64, linux/arm/v7.
oci-packer proxy cr://registry.example.comКоманда mount монтирует слои образа из распакованного OCI Layout (созданного через
copy --unpack) в директорию только для чтения через overlayfs. Один layout может
содержать много образов, поэтому ссылка указывает конкретный образ:
oci://<каталог>:<репозиторий>:<тег>. Записываемые пути (/tmp, /run, /var/tmp)
автоматически монтируются как tmpfs.
# Скачать образ в OCI Layout с распаковкой слоёв
oci-packer copy --unpack cr://registry.example.com/example/service:v1 oci://./layout:example/service:v1
# Смонтировать read-only rootfs образа (нужен root)
sudo oci-packer mount oci://./layout:example/service:v1 /mnt/app
# С writable bind-директорией и постоянным systemd-юнитом
sudo oci-packer mount oci://./layout:example/service:v1 /mnt/app \
--bind /srv/data:/var/lib/app \
--persistent --unit-dir /etc/systemd/system --enable
# Размонтировать всё (overlay + tmpfs + bind) одной командой
sudo oci-packer umount /mnt/appПодробное описание, флаги и ограничения — в docs/mount.md.
| Библиотека | Назначение |
|---|---|
containerd/containerd/v2 |
OCI Distribution API клиент |
opencontainers/image-spec |
OCI-спецификации (дескрипторы, манифесты) |
opencontainers/go-digest |
Вычисление SHA256-дайджестов |
containerd/platforms |
Парсинг и форматирование платформ |
moby/go-archive |
Работа с tar-архивами |
spf13/cobra |
CLI-фреймворк |
sirupsen/logrus |
Структурированное логирование |
docker/go-units |
Форматирование размеров файлов |
gopkg.in/yaml.v3 |
Парсинг YAML |
klauspost/compress |
Zstd-сжатие |
- Упаковка артефактов (build pack)
- Копирование между реестрами и OCI Layout
- Валидация Pack-файлов
- Поддержка OCI Layout (с распаковкой слоёв)
- Структурированное логирование
- Юнит-тесты
- CLI-команды:
proxy,copy,mount,umount,delete,list - E2E tests
- Прогресс-бар
- Поддержка S3-хендлера
- CLI-команда: список образов и компонентов Pack (
list) - CLI-команда: монтирование (
mount,umount) - CLI-команда: удаление образа из layout (
delete)
Apache License 2.0. Подробности в файле LICENSE.
Разработано командой Arenadata.
oci-packer is a Go tool for packaging arbitrary sources — files, directories, OCI images, HTTP resources — into
OCI-compliant artifacts and pushing them to container registries.
Developed by Arenadata, it is designed for artifact distribution management in OCI (Open Container Initiative) infrastructure, including use cases that go beyond classic Docker images: configurations, templates, binary data, dependency layers.
ORAS (OCI Registry As Storage) is the CNCF reference CLI for OCI artifacts: it lets you push and
pull individual files or file groups with explicit media types specified as CLI arguments. oci-packer solves a related
problem but with a fundamentally different approach:
| Criterion | ORAS | oci-packer |
|---|---|---|
| Artifact definition | Imperative: files and types passed as CLI arguments | Declarative: YAML Pack file describes the full structure |
| Sources | Local files and directories | Files, directories, HTTP/HTTPS, OCI registries, S3 |
| Multi-platform | Limited index support | Native OCI Index creation with platform variants |
| Config descriptor | Fixed empty config | Arbitrary config descriptor from any source |
| CI/CD integration | Push commands in scripts | One file — complete artifact specification |
| Registry mount | No | Supports oci:// sources with registry-side mount |
| Maturity | Stable, CNCF Sandbox | Work In Progress |
oci-packer is oriented towards scenarios where the artifact structure is complex and must be reproducible: multiple
sources of different types, multi-platform builds, custom config objects — all described in a single file and produced
deterministically.
- Multiple source types: files (
file://), directories (dir://), HTTP/HTTPS resources (http://,https://), OCI/Docker registries (oci://,docker://), S3 (s3://, in progress) - Multi-platform builds: create index manifests with variants for different architectures (linux/amd64, linux/arm64, etc.)
- OCI Layout: native support for local
oci-layoutformat with layer extraction - Registry push: direct artifact upload via OCI Distribution API
- Annotations and metadata: flexible OCI annotation management at artifact, manifest, and individual layer level
- Config descriptors: custom
configobjects instead of the standard empty config - CLI interface: built on top of Cobra
- Structured logging: via logrus
oci-packer/
├── cmd/ # CLI commands (pack, copy, proxy, ...)
├── internal/
│ └── logger/ # Internal logger
├── pkg/
│ ├── registry/ # OCI registry client, pusher/puller
│ │ └── reference/ # Source scheme parsers (file://, dir://, oci://, ...)
│ └── http/ # HTTP client
├── builder.go # Build orchestration (index / manifest)
├── handlers.go # Source handlers (file, dir, http, oci)
├── pack.go # Data models, validation, Pack file loading
├── pusher.go # Manifest and layer publishing to registry
└── utils.go # Utilities: digest, MediaType, descriptors
Key types:
Pack— root structure describing the artifact (type, metadata, items list)Descriptor— description of a single source (where to fetch from, type, platform, annotations)ConvertHandler— functional type converting a source into a set of descriptorsPusher— interface for writing manifests/indexes to a registry
Execution flow:
Pack file (YAML) → Validate → handleItem (handler selection by scheme)
├── file:// → fileHandler
├── dir:// → walkDirHandler (recursive directory walk)
├── http(s):// → httpHandler (download → temp file)
└── oci:// → ociHandler (mount from registry)
→ makeManifest / makeIndex → Push → OCI Registry / OCI Layout
A Pack file is a declarative YAML describing the artifact contents:
# Artifact type (MIME type)
type: application/vnd.example.artifact
# Global annotations
annotations:
org.opencontainers.image.title: "My Artifact"
org.opencontainers.image.vendor: "Arenadata"
# Config descriptor (optional)
config:
from: file://schema.json
type: application/vnd.example.schema
# List of items to pack
items:
# A file
- from: file://config.tmpl
type: application/vnd.example.template
annotations:
description: "Configuration template"
# A directory (all files recursively)
- from: dir://data/
type: application/vnd.example.data
# An HTTP resource
- from: https://example.com/binary.tar.gz
# OCI image from a registry (with platform for multi-manifest)
- from: oci://registry.example.com/myimage:latest
platform: linux/amd64
- from: oci://registry.example.com/myimage:latest
platform: linux/arm64| Scheme | Example | Description |
|---|---|---|
file:// |
file://path/to/file.tar.gz |
Local file |
dir:// |
dir://path/to/directory/ |
All files in directory |
http:// / https:// |
https://example.com/data.bin |
HTTP download |
oci:// / docker:// |
oci://registry/image:tag |
OCI/Docker registry |
s3:// |
s3://bucket/key |
Amazon S3 (coming soon) |
When platform field or oci:// source is present, an OCI Index (multi-manifest) is automatically created:
type: application/vnd.example.multiarch
items:
- from: oci://registry.example.com/app:v1.0
platform: linux(v8)/amd64
- from: oci://registry.example.com/app:v1.0-arm
platform: linux/arm64Prebuilt binaries for Linux, macOS and Windows are published on the
releases page (built with GoReleaser).
Download the archive for your platform and put the binary on your PATH:
tar -xzf oci-packer_*_linux_amd64.tar.gz
sudo install oci-packer /usr/local/bin/Via Go:
go install github.com/arenadata/oci-packer/cmd/oci-packer@latestOr build from source:
git clone https://github.com/arenadata/oci-packer.git
cd oci-packer
go build ./cmd/...Requirements: Go 1.26+
Full per-command documentation and troubleshooting live in docs/:
- Documentation hub — index of all commands
pack·copy·proxy·mount/umount·delete·list- Troubleshooting — common errors and fixes
A single list command works in two modes depending on the reference: without a
:repo:tag it lists the images and artifacts in the layout; with an image
reference it shows the components (config and layers) of that one Pack, with file
names taken from the org.opencontainers.image.title annotation.
# List images in a layout
oci-packer list oci://./layout
# Components of one Pack (per platform for an index)
oci-packer list oci://./layout:example/service:v1See docs/list.md for details.
Removes an image from an OCI layout and garbage-collects the blobs nothing else references. Layers shared with other images in the layout are kept; a mounted layer (unpack mode, Linux) cannot be deleted until it is unmounted.
# Delete an image; layers shared with other images are retained
oci-packer delete oci://./layout:example/service:v1
# Short alias
oci-packer rm oci://./layout:example/worker:v2See docs/delete.md for details.
# Pack and push to registry
oci-packer -f artifact.yaml registry.example.com/myartifact:v1.0
# Specify temp directory for HTTP downloads
oci-packer -f artifact.yaml registry.example.com/myartifact:v1.0 --tmp-dir /tmp/packeroci-packer copy \
cr://source-registry.example.com/image:tag \
oci://target/directory:image:tag
# Copy only a single platform from a multi-platform image
oci-packer copy --platform linux/arm64 \
cr://source-registry.example.com/image:tag \
oci://target/directory:image:tagWith --platform, the manifest for the requested platform is selected from an OCI Index and a
single-platform image is copied to the destination. The format is os/arch[/variant], e.g.
linux/amd64, linux/arm64, linux/arm/v7.
oci-packer proxy cr://registry.example.comThe mount command mounts the layers of an image from an unpacked OCI Layout (produced by
copy --unpack) onto a directory read-only via overlayfs. A single layout may hold many
images, so the reference selects one: oci://<dir>:<repository>:<tag>. Writable paths
(/tmp, /run, /var/tmp) are mounted as tmpfs automatically.
# Pull an image into an OCI Layout with unpacked layers
oci-packer copy --unpack cr://registry.example.com/example/service:v1 oci://./layout:example/service:v1
# Mount the image's read-only rootfs (requires root)
sudo oci-packer mount oci://./layout:example/service:v1 /mnt/app
# With a writable bind directory and a persistent systemd unit
sudo oci-packer mount oci://./layout:example/service:v1 /mnt/app \
--bind /srv/data:/var/lib/app \
--persistent --unit-dir /etc/systemd/system --enable
# Unmount everything (overlay + tmpfs + bind) in one go
sudo oci-packer umount /mnt/appSee docs/mount.md for the full description, flags and limitations.
| Library | Purpose |
|---|---|
containerd/containerd/v2 |
OCI Distribution API client |
opencontainers/image-spec |
OCI specs (descriptors, manifests) |
opencontainers/go-digest |
SHA256 digest computation |
containerd/platforms |
Platform string parsing and formatting |
moby/go-archive |
Tar archive handling |
spf13/cobra |
CLI framework |
sirupsen/logrus |
Structured logging |
docker/go-units |
File size formatting |
gopkg.in/yaml.v3 |
YAML parsing |
klauspost/compress |
Zstd compression |
- Artifact packaging (build pack)
- Copy between registries and OCI Layout
- Pack file validation
- OCI Layout support (with layer extraction)
- Structured logging
- Unit tests
- CLI commands:
proxy,copy,mount,umount,delete,list - E2E tests
- S3 source handler
- CLI command: list images and Pack components (
list) - CLI command: mount, umount
- CLI command: delete image from layout (
delete) - Progress bar
Apache License 2.0. See LICENSE for details.
Developed by the Arenadata team.