This repository demonstrates modern, secure, reproducible container builds using both classic Dockerfile-based methods and the apko / melange toolchain (the foundation of Wolfi and Chainguard Images).
Traditional Dockerfiles are familiar but opaque:
- No true build provenance
- Hidden dependencies
- Uncontrolled package supply chain
- No out-of-the-box SBOM or SLSA provenance
The apko/melange approach:
- Builds every package from source with full traceability
- Generates and signs SBOMs
- Enables distroless images (minimal attack surface)
- Declarative, reproducible, automated — designed for modern supply chain requirements
| File/Folder | Purpose |
|---|---|
main.go |
Sample Go app |
go.mod, go.sum |
Go dependencies |
melange/melange.yaml |
melange build recipe (declarative package build) |
apko/apko-dev.yaml |
apko dev image spec (distroless image) |
apko/apko-prod.yaml |
Prod variant (hardened, minimal) |
dockerfiles/Dockerfile.ubuntu |
Classic Ubuntu-based Dockerfile |
dockerfiles/Dockerfile.ubuntu-ms |
Ubuntu + Multistaget best practices (multistage) |
dockerfiles/Dockerfile.debian-ms |
Debian + Multistaget best practices (multistage) |
dockerfiles/Dockerfile.alpine |
Alpine-based Dockerfile |
dockerfiles/Dockerfile.alpine-ms |
Alpine + Multistaget best practices (multistage) |
dockerfiles/Dockerfile.wolfi |
Wolfi-based Dockerfile (distroless, single-stage) |
dockerfiles/Dockerfile.wolfi-ms |
Wolfi-based multistage (build + minimal runtime) |
LICENSE |
Licensing info |
.gitignore |
Clean repo config |
For this workshop you will need following tooling installed:
- git
- Docker
- cosign (optional)
- melange (optinal)
- apko (optional)
- yq
- jq
Clone repo:
git clone git@github.com:maligin/partner-enablement-workshop.gitBuild all (lazy-style):
./build-all.sh allEach Dockerfile represents a different base OS and hardening level:
docker buildx build -t hello-go:ubuntu-latest -f dockerfiles/Dockerfile.ubuntu .docker buildx build -t hello-go:ubuntu-latest-ms -f dockerfiles/Dockerfile.ubuntu-ms .docker buildx build -t hello-go:debian-latest -f dockerfiles/Dockerfile.debian .docker buildx build -t hello-go:debian-latest-ms -f dockerfiles/Dockerfile.debian-ms .docker buildx build -t hello-go:alpine-latest -f dockerfiles/Dockerfile.alpine .docker buildx build -t hello-go:alpine-latest-ms -f dockerfiles/Dockerfile.alpine-ms .docker buildx build -t hello-go:wolfi-latest -f dockerfiles/Dockerfile.wolfi .docker buildx build -t hello-go:wolfi-latest-ms -f dockerfiles/Dockerfile.wolfi-ms .docker run --privileged --rm -v "${PWD}":/work \
cgr.dev/chainguard/melange:latest build melange.yaml \
--arch amd64,aarch64 \
--signing-key melange.rsamelange build melange.yaml --arch amd64,aarch64 --signing-key melange.rsadocker run --rm --workdir /work -v ${PWD}:/work cgr.dev/chainguard/apko:latest \
build apko-dev.yaml \
hello-go:wolfi-latest-apko-dev \
hello-go-dev.tar --arch hostdocker run --rm --workdir /work -v ${PWD}:/work cgr.dev/chainguard/apko:latest \
build apko-prod.yaml \
hello-go:wolfi-latest-apko-prod \
hello-go-prod.tar --arch hostapko build apko/apko-dev.yaml hello-go:wolfi-latest-apko-dev apko-images/hello-go-dev.tar --arch hostapko build apko/apko-prod.yaml hello-go:wolfi-latest-apko-prod apko-images/hello-go-prod.tar --arch hostdocker load < hello-go-dev.tardocker load < hello-go-prod.targrype <image:tag>trivy image <image:tag>cat apko-images/hello-go-dev-sbom-index.spdx.json | jq .cat apko-images/hello-go-prod-sbom-index.spdx.json | jq .docker run --rm -it -u root --entrypoint=sh hello-go:wolfi-latest-apko-dev-amd64 docker run --rm -it -u root --entrypoint=sh hello-go:wolfi-latest-apko-prod-amd64