oci
OCI container registry operations. Pull, push, copy, tag, and mutate images across registries. No
require() needed — available as a global builtin.
Image operations
-
oci.copy(src, dst, opts?)→ true — Copy an image between registries. Pulls each layer one at a time fromsrcand pushes todst; peak memory is the size of the largest single layer.optsaccepts{src_auth, dst_auth}where each auth table is{username, password}. -
oci.tag(src, new_tag, opts?)→ true — Re-tag an image within the same registry+repository by pulling the manifest and pushing it undernew_tag. No layer data is copied — the new tag points at the existing blobs.optsaccepts{auth = {username, password}}. For cross-registry tagging, useoci.copy. -
oci.mutate(src, dst, files, opts?)→ true — Copysrctodstand append a new tar.gz layer containingfiles(a table of{path = content}). The image config is updated sorootfs.diff_idsincludes the new layer, matchingcrane mutatesemantics.optsaccepts{src_auth, dst_auth}.
Example:
-- Copy between registries (streams layer-by-layer)
oci.copy(
"registry.gitlab.com/group/project/image:abc123",
"770508136720.dkr.ecr.us-east-1.amazonaws.com/app:abc123",
{
src_auth = { username = env.get("CI_REGISTRY_USER"), password = env.get("CI_REGISTRY_PASSWORD") },
dst_auth = { username = "AWS", password = ecr_token },
}
)
-- Re-tag within the same repository (cheap manifest-only push)
oci.tag(
"770508136720.dkr.ecr.us-east-1.amazonaws.com/app:abc123",
"latest",
{ auth = { username = "AWS", password = ecr_token } }
)
-- Append a config file as a new layer
oci.mutate(
"registry.gitlab.com/group/project/base:abc123",
"770508136720.dkr.ecr.us-east-1.amazonaws.com/app:patched",
{ ["app/config.json"] = '{"env":"production"}' },
{
src_auth = { username = env.get("CI_REGISTRY_USER"), password = env.get("CI_REGISTRY_PASSWORD") },
dst_auth = { username = "AWS", password = ecr_token },
}
)