Skip to content

feat(build): orcinus image build — daemonless OCI/Docker image builds - #4

Open
anak10thn wants to merge 2 commits into
mainfrom
feat/orcinus-image-build
Open

feat(build): orcinus image build — daemonless OCI/Docker image builds#4
anak10thn wants to merge 2 commits into
mainfrom
feat/orcinus-image-build

Conversation

@anak10thn

Copy link
Copy Markdown
Member

Summary

Adds orcinus image (build / inspect / push / ls) plus a top-level orcinus build alias that produce OCI / Docker-compatible images with no Docker daemon, taking the same inputs as docker build and docker compose build.

Two engines behind one API (both converge on a go-containerregistry v1.Image, so output/push code is shared and Docker-compatible):

Engine Runtime needed Handles Platform
native (default) none at all FROM/COPY/ADD/ENV/WORKDIR/CMD/ENTRYPOINT/EXPOSE/LABEL/USER/VOLUME/ARG/… any (build linux from macOS)
buildah (opt-in tag) OCI runtime, or none with --isolation chroot everything above + RUN + multi-stage — full docker build Linux
  • native: pure-Go, CGO-free. Parses the Dockerfile and replays every non-executing instruction as layer/config mutations in-process — no runtime of any kind.
  • buildah: imported as a library under the opt-in orcinus_buildah build tag (Linux), keeping the default cross-platform CGO-free binary lean (same pattern as the standalone runtime). Self-contained — generates registries.conf + policy.json at runtime, so no /etc/containers/* setup. Non-buildah builds get a stub that fails fast with guidance instead of producing a wrong image.

Compose mode reads each service's build: block (context/dockerfile/args/labels/target/platforms/tags), mirroring docker compose build.

Outputs: OCI image layout dir (-o), docker/OCI tar (--tar, docker load-able), registry (--push).

Usage

# docker build style
orcinus build ./app -t myapp:v1 -o ./out/oci --tar myapp.tar
orcinus image build ./app --dockerfile Dockerfile.prod -t app:v1 -o ./out

# docker compose build style
orcinus build -f orcinus.yml --tar images.tar
orcinus build -f orcinus.yml web api

# RUN steps, no OCI runtime / network backend needed
orcinus image build ./app -t app:v1 --isolation chroot -o ./out

# work with the artifact — no daemon
orcinus image inspect ./out/oci
orcinus image push ./out/oci registry.example.com/app:v1
orcinus image ls ./out/oci

Testing

  • Default build (CGO_ENABLED=0, linux+darwin): green; unit tests pass (native build incl. a regression guard that config diff_ids match layers).
  • e2e verified on Linux (Ubuntu 24.04, kernel 6.8): the buildah-tag binary compiles, and a Dockerfile with RUN apk add curl builds via --isolation chroot with no Docker daemon, OCI runtime, or netavark — confirmed the RUN output (/built.txt, usr/bin/curl) is baked into the image layers.

Enabling buildah (Linux build host)

go get go.podman.io/buildah@latest
go build -tags "orcinus_buildah containers_image_openpgp exclude_graphdriver_btrfs exclude_graphdriver_devicemapper" ./cmd/orcinus

Docs

  • docs/BUILD.md — engines, isolation modes + host requirements, compose keys, enabling buildah.
  • docs/USAGE.md §5.6.

Add `orcinus image` (build/inspect/push/ls) plus a top-level `orcinus build`
alias that produce OCI/Docker-compatible images with no Docker daemon, taking
the same inputs as `docker build` and `docker compose build`.

Two engines behind one API (both converge on a ggcr v1.Image so output/push
code is shared):

- native (default): pure-Go, CGO-free, cross-platform. Parses the Dockerfile
  and replays every non-executing instruction (FROM/COPY/ADD/ENV/WORKDIR/CMD/
  ENTRYPOINT/EXPOSE/LABEL/USER/VOLUME/ARG/…) as layer/config mutations in
  process — no runtime of any kind, so it can build linux images from macOS.
- buildah (opt-in `orcinus_buildah` tag, Linux): imported as a library for
  RUN/multi-stage. Self-contained (generates registries.conf + policy.json at
  runtime); `--isolation chroot` runs RUN with no OCI runtime or network
  backend. Non-buildah builds get a stub that fails fast with guidance.

Compose mode reads service `build:` blocks (context/dockerfile/args/labels/
target/platforms/tags), mirroring `docker compose build`.

Outputs: OCI image layout dir (-o), docker/OCI tar (--tar), registry (--push).

Verified end-to-end on Linux: a Dockerfile with `RUN apk add curl` builds via
--isolation chroot with no Docker daemon, OCI runtime, or netavark.

Docs: docs/BUILD.md, USAGE.md §5.6.
…kend

The buildah backend needs CGO_ENABLED=1 to work at runtime (a CGO-free build
compiles but fails with `parsing PID ""` in storage/reexec), so it cannot fold
into the lean, static, cross-platform `orcinus` binary. Ship it as a dedicated
linux/amd64 flavor instead — mirroring `orcinus-standalone`:

- Makefile: `make build-buildah` → bin/orcinus-buildah (CGO=1, buildah tags).
- goreleaser: `orcinus-buildah` build + archive (linux/amd64, CGO=1).
- docs/BUILD.md: explain why it's a separate flavor and how to get it.

Verified on Linux: `make build-buildah` produces a working binary that runs
Dockerfile RUN via `--isolation chroot`. `goreleaser check` passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant