Version: 0.3.0 Last Updated: 2026-03-22 Format: Man-page style reference Distributed as: Container image us-central1-docker.pkg.dev/clean-image-build/cleanimage001/cleanimg-customize:v0.3.0
NAME
cleanimg-customize — Declarative Dockerfile generator for container image customization using IncrementalSpec YAML
SYNOPSIS
cleanimg-customize generate [FLAGS] --base-image IMAGE --arch ARCH --variant VARIANT --output FILE [--package PACKAGE]...cleanimg-customize build --spec FILE --tag TAG [FLAGS]cleanimg-customize to-dockerfile --spec FILE [--output FILE]cleanimg-customize validate --spec FILEcleanimg-customize extract-sbom --image IMAGE --output FILE [--pull [BOOL]]cleanimg-customize inspect --image IMAGE [--pull [BOOL]]DESCRIPTION
cleanimg-customize v0.3.0 is a Rust-based CLI tool that translates a declarative YAML specification (IncrementalSpec) into a multi-stage Dockerfile, then optionally builds and pushes the resulting image. The tool generates Dockerfiles from YAML specs with full package manager, user, and multi-stage build support, builds images locally via Docker daemon or generates Dockerfiles for external CI/CD pipelines, validates all spec fields before generation, extracts SBOMs from built images, and inspects image metadata.
Unlike earlier versions, v0.3.0 does not add overlay layers; instead, it generates production-ready Dockerfiles with multi-stage compilation, user account management, and resource hints.
Distributed as: Container image at us-central1-docker.pkg.dev/clean-image-build/cleanimage001/cleanimg-customize:v0.3.0
GLOBAL FLAGS
Available for all commands:
--verbose, -v Enable info-level logging--debug, -d Enable debug-level logging (very verbose, includes Docker API calls)--help, -h Display help message and exit--version Display tool version and exitCOMMANDS
generate
Generate an IncrementalSpec YAML file from command-line flags.
Syntax:
cleanimg-customize generate [FLAGS] --base-image IMAGE --arch ARCH --variant VARIANT --output FILERequired Flags:
Flag | Type | Description |
|---|---|---|
| string | Base image reference (e.g., |
| string | Target architecture: |
| string | Build variant: |
| path | Output YAML file path (e.g., |
Optional Flags:
Flag | Type | Repeatable | Description |
|---|---|---|---|
| string | Yes | Package to install (e.g., |
| KEY=VALUE | Yes | Environment variable to set (e.g., |
| KEY=VALUE | Yes | OCI label to add (e.g., |
| path | No | Working directory (must be absolute; default varies by variant) |
| uid:gid or username | No | Container runtime user (e.g., |
| string | No | Explicit package manager: |
| bool | No | Force multi-stage build (default: auto-detect based on packages/users/variant) |
| string | No | Builder stage image (default: same as base_image). Used only if multistage=true. |
| SRC:DST | Yes | Copy artifacts from builder stage (e.g., |
| SOURCE:DESTINATION | Yes | Copy files from host into image (e.g., |
| USERNAME:UID:GID | Yes | Create user account (e.g., |
| GROUPNAME:GID | Yes | Create group (e.g., |
| bool | No | Enable CleanStart repository (auto-enabled for CleanStart base images if packages specified) |
| URL | Yes | Add custom APK repository mirror (e.g., |
| KEY=VALUE | Yes | Resource request hint (e.g., |
| KEY=VALUE | Yes | Resource limit hint (e.g., |
Limitation: The generate command does NOT accept --artifact, --script, or --run-command flags. For advanced artifact handling, multi-stage builds, or embedded scripts, edit the YAML manually after generation.
Examples:
# Minimal: Alpine with one packagecleanimg-customize generate \ --base-image alpine:3.19 \ --arch amd64 \ --variant prod \ --output spec.yaml # With packages and environmentcleanimg-customize generate \ --base-image ubuntu:22.04 \ --arch amd64 \ --variant prod \ --package curl --package git --package python3 \ --env LOG_LEVEL=info \ --env DATABASE_URL=postgresql://localhost/db \ --workdir /app \ --output spec.yaml # Multi-user with CleanStart reposcleanimg-customize generate \ --base-image us-central1-docker.pkg.dev/clean-image-build/cleanimage001/cleanstart:3.19 \ --arch amd64 \ --variant prod \ --package git --package build-essential \ --create-group appgroup:1000 \ --create-user appuser:1000:1000 \ --user 1000:1000 \ --cleanstart-repos \ --output spec.yaml # With resource hintscleanimg-customize generate \ --base-image distroless/base-debian12 \ --arch arm64 \ --variant prod \ --resource-request memory=256Mi,cpu=100m \ --resource-limit memory=1Gi,cpu=500m \ --output spec.yamlbuild
Build a Docker image from a spec YAML file.
Syntax:
cleanimg-customize build --spec FILE --tag TAG [FLAGS]Required Flags:
Flag | Type | Description |
|---|---|---|
| path | Path to IncrementalSpec YAML file |
| string | Docker image tag (e.g., |
Optional Flags:
Flag | Type | Default | Description |
|---|---|---|---|
| bool or [BOOL] | true | Pull base image before building. Accepts: |
| bool | false | Push resulting image to registry after successful build |
| path | (none) | Generate Dockerfile to file instead of building; do NOT invoke Docker |
Behavior: The tool requires Docker daemon to be running, generates a multi-stage Dockerfile internally and then runs docker build, returns exit code 2 if the Docker daemon is unreachable, exit code 4 if the build fails (in which case check Docker logs), and exit code 5 if the push fails when using the --push flag.
Examples:
# Build and tagcleanimg-customize build \ --spec spec.yaml \ --tag myapp:v1.0.0 # Build without pulling base (use locally cached image)cleanimg-customize build \ --spec spec.yaml \ --tag myapp:v1.0.0 \ --pull=false # Build and push to registrycleanimg-customize build \ --spec spec.yaml \ --tag gcr.io/myproject/myapp:v1.0.0 \ --push # Generate Dockerfile only (no Docker daemon needed)cleanimg-customize build \ --spec spec.yaml \ --tag myapp:v1.0.0 \ --dockerfile-only Dockerfile.generatedto-dockerfile
Generate a Dockerfile from a spec YAML and print to stdout or file. Does NOT require Docker daemon.
Syntax:
cleanimg-customize to-dockerfile --spec FILE [--output FILE]Required Flags:
Flag | Type | Description |
|---|---|---|
| path | Path to IncrementalSpec YAML file |
Optional Flags:
Flag | Type | Default | Description |
|---|---|---|---|
| path | stdout | Output file path. If absent, prints to stdout. |
Examples:
# Print to stdoutcleanimg-customize to-dockerfile --spec spec.yaml # Write to filecleanimg-customize to-dockerfile --spec spec.yaml --output Dockerfile # Pipe to Dockercleanimg-customize to-dockerfile --spec spec.yaml | docker build -t myapp:v1 -validate
Validate all fields in a spec YAML file without generating or building.
Syntax:
cleanimg-customize validate --spec FILEValidation Checks: The validation ensures that base_image is a non-empty string with a valid OCI image reference format, arch is one of amd64 or arm64, variant is one of prod or dev, user has proper formatting as either uid:gid or a named user and warns if the UID is 0 (root), workdir is an absolute path, all entries in writable_paths are absolute paths, all destination paths in copy_targets are absolute, UIDs and GIDs in users (UserAccount[]) are unique per user and group, Maven coordinates in artifacts follow the groupId:artifactId:version pattern, and the package manager selection is validated for compatibility with the base image.
Exit Code: The command returns exit code 0 if all validations passed, or exit code 1 if a validation error is found.
Examples:
cleanimg-customize validate --spec spec.yaml cleanimg-customize validate --spec /path/to/spec.yaml --debugextract-sbom
Extract Software Bill of Materials (SBOM) from a built image.
Syntax:
cleanimg-customize extract-sbom --image IMAGE --output FILE [--pull [BOOL]]Required Flags:
Flag | Type | Description |
|---|---|---|
| string | Image reference (e.g., |
| path | Output file path (e.g., |
Optional Flags:
Flag | Type | Default | Description |
|---|---|---|---|
| bool or [BOOL] | true | Pull image if not locally available. Accepts: |
SBOM Search Locations (in order):
/sbom.json/usr/share/doc/sbom.json/var/lib/sbom/sbom.json/.sbom/sbom.json
Exit Codes: The command returns exit code 0 if the SBOM is extracted successfully, exit code 1 if the image exists but no SBOM is found in any location, exit code 2 if the Docker daemon is unreachable, or exit code 3 if the image pull fails.
Examples:
# Extract SBOM from local imagecleanimg-customize extract-sbom \ --image myapp:v1.0.0 \ --output sbom.json # Extract SBOM with pullcleanimg-customize extract-sbom \ --image gcr.io/myproject/myapp:latest \ --output sbom.json \ --pull # Extract without pulling (fail if not local)cleanimg-customize extract-sbom \ --image myapp:v1.0.0 \ --output sbom.json \ --pull=falseinspect
Display image metadata without building or pulling (unless --pull specified).
Syntax:
cleanimg-customize inspect --image IMAGE [--pull [BOOL]]Required Flags:
Flag | Type | Description |
|---|---|---|
| string | Image reference |
Optional Flags:
Flag | Type | Default | Description |
|---|---|---|---|
| bool or [BOOL] | false | Pull image before inspection if not locally cached |
Output Fields: The command displays the fully qualified image reference, the image ID as a SHA256 digest, the container user in UID:GID and name format, the working directory, the count of environment variables, the count of labels, and the total size in human-readable format.
Examples:
cleanimg-customize inspect --image myapp:v1.0.0 cleanimg-customize inspect --image gcr.io/myproject/myapp:latest --pull cleanimg-customize inspect --image alpine:3.19SPEC YAML FIELD REFERENCE
Complete field reference for IncrementalSpec YAML files:
Core Fields
Field | Type | Required | Default | Description |
|---|---|---|---|---|
| string | Yes | — | Base image reference (OCI format) |
| string | Yes | — | Target architecture: |
| string | Yes | — | Build variant: |
Package Management
Field | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | auto-detect | Explicit manager: |
| string[] | No | [] | List of packages to install |
| bool | No | auto | Enable CleanStart repos (auto-true for CleanStart images with packages) |
| string[] | No | [] | Custom APK mirror URLs (only if package_manager is |
Environment & Configuration
Field | Type | Required | Default | Description |
|---|---|---|---|---|
| string[]/object | No | {} | Environment variables as map |
| object | No | {} | OCI labels as map |
| string[] | No | [] | RUN commands to execute during build |
Image Configuration
Field | Type | Required | Default | Description |
|---|---|---|---|---|
| string | No | depends on variant | Working directory (absolute path) |
| string | No | root:root | Runtime user; format: |
| string[] | No | [] | Container entrypoint (overrides base image) |
| string[] | No | [] | Default command arguments |
| string[] | No | auto-generated for prod | Paths with write permissions; auto-generated by variant |
| bool | No | true | Generate SBOM during build |
Multi-Stage Builds
Field | Type | Required | Default | Description |
|---|---|---|---|---|
| bool | No | auto-detect | Force multi-stage build (auto if packages/users/variant=prod) |
| string | No | same as base_image | Builder stage image (unused if multistage=false) |
| CopyFromBuilder[] | No | [] | Artifacts to copy from builder: |
Artifacts (Multi-Stage)
Field | Type | Description |
|---|---|---|
| Artifact[] | List of artifacts to include in final stage |
| string | Type: |
| string | Source location: local path (relative/absolute) or Maven coordinate |
| string | Destination in final image; auto-inferred from type if absent |
| string | (Legacy) use |
| bool | Replace existing file at destination (default: false) |
| string | Octal file permissions (e.g., |
Artifact Type Defaults:
Type | Default Destination |
|---|---|
|
|
|
|
|
|
|
|
|
|
File & Script Management
Field | Type | Description |
|---|---|---|
| CopyFile[] | Files to copy from host; format: |
| EmbeddedScript[] | Embedded scripts; format: |
User & Group Management
Field | Type | Description |
|---|---|---|
| GroupAccount[] | Groups to create; format: |
| UserAccount[] | Users to create; format: |
UserAccount Fields:
Field | Type | Required | Default |
|---|---|---|---|
| string | Yes | — |
| int | Yes | — |
| int | Yes | — |
| string | No |
|
| string | No |
|
Resource Hints
Field | Type | Description |
|---|---|---|
| object | Resource hints (stored as OCI labels) |
| object | Resource requests: |
| object | Resource limits: |
Example:
resource_hints: requests: memory: "256Mi" cpu: "100m" limits: memory: "1Gi" cpu: "500m"Architecture Overrides
Field | Type | Description |
|---|---|---|
| object | Architecture-specific config |
| ArchConfig | Overrides for amd64 (packages, env_vars) |
| ArchConfig | Overrides for arm64 (packages, env_vars) |
Example:
arch_overrides: amd64: packages: - intel-specific-package arm64: packages: - arm-specific-packageBuild Hooks
Field | Type | Description |
|---|---|---|
| object | Build lifecycle hooks |
| string[] | Commands to run before main build steps |
| string[] | Commands to run after main build steps |
Dependency Pinning
Field | Type | Default | Description |
|---|---|---|---|
| string |
| Package pinning: |
DECISION TREES
Multi-Stage Build Selection
Multi-stage build is enabled if any of these conditions are true:
IF (variant == "prod") AND ( packages.length > 0 OR users.length > 0 OR groups.length > 0 OR copy_from_builder.length > 0 OR multistage == true OR builder_image is set)THEN multi-stage enabledResult: Builder stage compiles/builds, final stage is minimal runtime image.
Package Manager Selection
IF package_manager is explicitly set THEN use specified managerELSE IF base_image contains ("alpine" OR "cleanstart" OR "apk") THEN use "apk"ELSE IF base_image contains ("debian" OR "ubuntu" OR "deb") THEN use "apt"ELSE ERROR: Unable to infer package manager; set --package-manager explicitlyCleanStart Repository Enablement
IF cleanstart_repos == true (explicit) THEN add CleanStart reposELSE IF base_image contains "cleanstart" AND packages.length > 0 THEN add CleanStart repos automaticallyELSE THEN no CleanStart reposEXIT CODES
Code | Meaning | Recovery |
|---|---|---|
0 | Success | N/A |
1 | Validation error / spec error | Check YAML syntax and field values |
2 | Docker daemon not reachable | Ensure Docker is running: |
3 | Image pull failed | Check image reference, registry auth, network |
4 | Build failed | Check Docker logs, Dockerfile generated |
5 | Push failed | Check registry auth, network, tag format |
ENVIRONMENT VARIABLES
Variable | Description | Example |
|---|---|---|
| Docker daemon socket |
|
| Docker config directory for auth |
|
| Enable BuildKit (recommended) |
|
FILES
File | Purpose |
|---|---|
| IncrementalSpec YAML file (generated or manual) |
| Generated multi-stage Dockerfile (ephemeral or saved via |
| Docker build context exclusions (inherited from base image) |
| SBOM location in built images (searched first) |
SEE ALSO
See the cleanimg-init-reference.md for information on the dynamic runtime configuration tool, cleanstart-base-images.md for CleanStart base image variants and manifests, and spec-yaml-guide.md for detailed IncrementalSpec authoring guidance.
NOTES
Multi-Architecture Considerations: Version 0.3.0 generates architecture-specific Dockerfiles based on the --arch flag, supports per-architecture package and environment variations through arch_overrides in YAML, and requires explicit platform specification for BuildKit's cross-platform builds.
Performance Notes: The generate command completes in less than 1 second, validation takes less than 100 milliseconds, simple builds take 10-30 seconds depending on base image size and packages, multi-stage builds take 30-120 seconds where the compile time depends on the toolchain, and SBOM extraction takes 2-5 seconds.
Production Deployment: Always validate specs before building using cleanimg-customize validate --spec spec.yaml, use --pull=false in CI/CD if base images are pre-cached to improve speed, archive generated Dockerfiles for reproducibility by running cleanimg-customize to-dockerfile --spec spec.yaml > Dockerfile.v0.3.0, and test multi-stage builds with --dockerfile-only before committing to a full build --push.
Limitations: The CLI generate command does not support --artifact, --script, or --run-command flags, so you must edit YAML manually for advanced builds. CleanStart repositories require valid APK credentials in the environment or Docker config. Symlinks in copy_files are copied as regular files rather than being resolved to their targets.
VERSION HISTORY
v0.3.0 (2026-03-22) represents a complete Rust rewrite focusing on declarative spec-based generation, includes multi-stage Dockerfile generation with builder image support, enables user and group account creation within the spec, provides artifact handling with Maven coordinate resolution, supports architecture-specific overrides for amd64 and arm64, includes resource hints and OCI label support, enables SBOM extraction from built images, and is distributed as a container image with digest pinning.
Digests (v0.3.0): Multi-arch digest is sha256:f5436acd3a99, amd64 digest is sha256:7d4a65a1052e, and arm64 digest is sha256:e88f932a01f2.
