Bazel rules for converting OCI container images to SOCI (Seekable OCI) images (SOCI Index Manifest v2) with lazy-loading indices.
- Bazel 8.5.0+
- Bzlmod enabled
- containerd installed and running (for image conversion)
- Linux host (SOCI is Linux-only)
Add to your MODULE.bazel:
bazel_dep(name = "rules_soci", version = "0.1.0")
# Configure SOCI extension
soci = use_extension("@rules_soci//soci:extensions.bzl", "soci")
soci.toolchain(
soci_version = "0.12.1", # Optional, defaults to 0.12.1
crane_version = "0.20.7", # Optional, defaults to 0.20.7
)
use_repo(soci, "soci_toolchains")
# Register toolchains
register_toolchains("@soci_toolchains//:all")load("@rules_oci//oci:defs.bzl", "oci_image")
load("@rules_soci//soci:defs.bzl", "soci_image", "soci_push")
# Build OCI image
oci_image(
name = "app",
base = "@distroless_base",
entrypoint = ["/app"],
cmd = ["--port=8080"],
)
oci_load(
name = "app_load",
image = ":app",
repo_tags = ["myapp:latest"],
)
filegroup(
name = "app_tarball",
srcs = [":app_load"],
output_group = "tarball",
)
# Convert to SOCI format
soci_image(
name = "app_soci",
image = ":app_tarball",
repo_tags = [
"docker.io/myuser/app:latest",
"docker.io/myuser/app:v1.0.0",
],
)
# Push to registry
soci_push(
name = "soci_push",
soci_image = ":app_soci",
# repo_tags automatically inherited from app_soci
)# Convert image to SOCI format
bazel build //:app_soci
# Push to registry (requires docker login)
docker login docker.io
bazel run //:soci_pushConverts an OCI image tarball to SOCI format.
Attributes:
image(required): OCI image tarball fromoci_loadrepo_tags(optional): List of repository tags (e.g.,["docker.io/user/app:v1.0.0", "docker.io/user/app:latest"])min_layer_size(optional, default: 10MB): Minimum layer size in bytes to create SOCI index forspan_size(optional, default: 4MB): Span size in bytes for ztoc generation
Example:
soci_image(
name = "app_soci",
image = ":app_tarball",
repo_tags = ["docker.io/myuser/app:latest"],
min_layer_size = 10485760, # 10MB
span_size = 4194304, # 4MB
)Pushes SOCI-enabled images to a container registry.
Attributes:
soci_image(required): SOCI marker file fromsoci_imagerulerepo_tags(optional): List of image references to push. If not specified, inherits fromsoci_image
Example:
soci_push(
name = "push",
soci_image = ":app_soci",
)
# Override with specific tags
soci_push(
name = "push_prod",
soci_image = ":app_soci",
repo_tags = ["docker.io/myuser/app:prod"],
)Create and push multiple tags in one go:
soci_image(
name = "app_soci",
image = ":app_tarball",
repo_tags = [
"docker.io/myuser/app:latest",
"docker.io/myuser/app:v1.0.0",
"docker.io/myuser/app:stable",
],
)
soci_push(
name = "push_all",
soci_image = ":app_soci",
# Pushes all three tags
)For large images (1GB+), adjust layer size thresholds:
soci_image(
name = "large_app_soci",
image = ":large_app_tarball",
min_layer_size = 52428800, # 50MB - skip smaller layers
span_size = 8388608, # 8MB - larger spans for big layers
)For more granular lazy loading:
soci_image(
name = "fine_grained_soci",
image = ":app_tarball",
min_layer_size = 5242880, # 5MB - index more layers
span_size = 1048576, # 1MB - smaller spans
)-
Image Conversion:
soci_imageloads your OCI tarball into containerd and runssoci convertto create SOCI indices (ztoc files) for layers larger thanmin_layer_size -
Multi-tagging: Additional tags specified in
repo_tagsare created in containerd -
Push:
soci_pushexports the SOCI-enabled image from containerd and usescraneto push it to the registry with authentication from~/.docker/config.json
Error: containerd not found
Install containerd:
- Ubuntu/Debian:
sudo apt install containerd - macOS:
brew install containerd(note: SOCI only works on Linux) - Or download from: https://github.com/containerd/containerd/releases
Error: unexpected status code 401 Unauthorized
Login to your registry first:
docker login docker.io
# or
docker login ghcr.ioWarning: No layers met size threshold
All layers in your image are smaller than min_layer_size. Either:
- Lower
min_layer_sizevalue - This is expected for small images - SOCI benefits larger images more
Generate API documentation:
# Update all docs
bazel run //docs:update
# Test docs are up-to-date
bazel test //docs:allContributions welcome! Please:
- Run tests:
bazel test //... - Update docs:
bazel run //docs:update
- SOCI Snapshotter by AWS
- crane by Google
- rules_oci for OCI image building