Skip to main content
CleanStart

Knowledge Hub

cleanimg-customize CLI Reference

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 exit

COMMANDS

generate

Generate an IncrementalSpec YAML file from command-line flags.

Syntax:

cleanimg-customize generate [FLAGS] --base-image IMAGE --arch ARCH --variant VARIANT --output FILE

Required Flags:

Flag

Type

Description

--base-image, -b

string

Base image reference (e.g., alpine:3.19, ubuntu:22.04, gcr.io/distroless/base-debian12)

--arch, -a

string

Target architecture: amd64 or arm64

--variant

string

Build variant: prod or dev. Determines multi-stage strategy and writable paths.

--output, -o

path

Output YAML file path (e.g., spec.yaml, /tmp/image-spec.yaml)

Optional Flags:

Flag

Type

Repeatable

Description

--package, -p

string

Yes

Package to install (e.g., curl, git, python3)

--env, -e

KEY=VALUE

Yes

Environment variable to set (e.g., LOG_LEVEL=info)

--label, -l

KEY=VALUE

Yes

OCI label to add (e.g., version=1.0.0)

--workdir, -w

path

No

Working directory (must be absolute; default varies by variant)

--user, -u

uid:gid or username

No

Container runtime user (e.g., 1000:1000, appuser)

--package-manager

string

No

Explicit package manager: apk (Alpine), apt (Debian/Ubuntu), auto-detected if absent

--multistage

bool

No

Force multi-stage build (default: auto-detect based on packages/users/variant)

--builder-image

string

No

Builder stage image (default: same as base_image). Used only if multistage=true.

--copy-from-builder

SRC:DST

Yes

Copy artifacts from builder stage (e.g., /app/build:/app). Requires multistage=true.

--copy-file

SOURCE:DESTINATION

Yes

Copy files from host into image (e.g., /local/config.yaml:/etc/config.yaml)

--create-user

USERNAME:UID:GID

Yes

Create user account (e.g., appuser:1000:1000). GID must exist or use --create-group

--create-group

GROUPNAME:GID

Yes

Create group (e.g., appgroup:1000)

--cleanstart-repos

bool

No

Enable CleanStart repository (auto-enabled for CleanStart base images if packages specified)

--apk-repo

URL

Yes

Add custom APK repository mirror (e.g., https://mirrors.aliyun.com/alpine/)

--resource-request

KEY=VALUE

Yes

Resource request hint (e.g., memory=512Mi, cpu=500m)

--resource-limit

KEY=VALUE

Yes

Resource limit hint (e.g., memory=2Gi, cpu=2)

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.yaml

build

Build a Docker image from a spec YAML file.

Syntax:

cleanimg-customize build --spec FILE --tag TAG [FLAGS]

Required Flags:

Flag

Type

Description

--spec, -s

path

Path to IncrementalSpec YAML file

--tag, -t

string

Docker image tag (e.g., myapp:v1.0.0, gcr.io/myproject/myapp:latest)

Optional Flags:

Flag

Type

Default

Description

--pull

bool or [BOOL]

true

Pull base image before building. Accepts: --pull, --pull=true, --pull false, --pull=false

--push

bool

false

Push resulting image to registry after successful build

--dockerfile-only

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.generated

to-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

--spec

path

Path to IncrementalSpec YAML file

Optional Flags:

Flag

Type

Default

Description

--output

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 FILE

Validation 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 --debug

extract-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

--image

string

Image reference (e.g., myapp:v1.0.0, gcr.io/myproject/myapp:latest)

--output

path

Output file path (e.g., sbom.json, /tmp/sbom.spdx.json)

Optional Flags:

Flag

Type

Default

Description

--pull

bool or [BOOL]

true

Pull image if not locally available. Accepts: --pull, --pull=true, --pull false

SBOM Search Locations (in order):

  1. /sbom.json
  2. /usr/share/doc/sbom.json
  3. /var/lib/sbom/sbom.json
  4. /.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=false

inspect

Display image metadata without building or pulling (unless --pull specified).

Syntax:

cleanimg-customize inspect --image IMAGE [--pull [BOOL]]

Required Flags:

Flag

Type

Description

--image

string

Image reference

Optional Flags:

Flag

Type

Default

Description

--pull

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.19

SPEC YAML FIELD REFERENCE

Complete field reference for IncrementalSpec YAML files:

Core Fields

Field

Type

Required

Default

Description

base_image

string

Yes

Base image reference (OCI format)

arch

string

Yes

Target architecture: amd64, arm64

variant

string

Yes

Build variant: prod or dev

Package Management

Field

Type

Required

Default

Description

package_manager

string

No

auto-detect

Explicit manager: apk, apt. Auto-detected from base image if absent.

packages

string[]

No

[]

List of packages to install

cleanstart_repos

bool

No

auto

Enable CleanStart repos (auto-true for CleanStart images with packages)

apk_repositories

string[]

No

[]

Custom APK mirror URLs (only if package_manager is apk)

Environment & Configuration

Field

Type

Required

Default

Description

env_vars

string[]/object

No

{}

Environment variables as map {KEY: VALUE} or list [KEY=VALUE]

labels

object

No

{}

OCI labels as map {KEY: VALUE}

run_commands

string[]

No

[]

RUN commands to execute during build

Image Configuration

Field

Type

Required

Default

Description

workdir

string

No

depends on variant

Working directory (absolute path)

user

string

No

root:root

Runtime user; format: uid:gid or named user

entrypoint

string[]

No

[]

Container entrypoint (overrides base image)

cmd

string[]

No

[]

Default command arguments

writable_paths

string[]

No

auto-generated for prod

Paths with write permissions; auto-generated by variant

generate_sbom

bool

No

true

Generate SBOM during build

Multi-Stage Builds

Field

Type

Required

Default

Description

multistage

bool

No

auto-detect

Force multi-stage build (auto if packages/users/variant=prod)

builder_image

string

No

same as base_image

Builder stage image (unused if multistage=false)

copy_from_builder

CopyFromBuilder[]

No

[]

Artifacts to copy from builder: {src, dst, chown?}

Artifacts (Multi-Stage)

Field

Type

Description

artifacts

Artifact[]

List of artifacts to include in final stage

type

string

Type: jar, shared_lib, wheel, node_module, file

source

string

Source location: local path (relative/absolute) or Maven coordinate groupId:artifactId:version

destination

string

Destination in final image; auto-inferred from type if absent

target_dir

string

(Legacy) use destination instead

replace

bool

Replace existing file at destination (default: false)

permissions

string

Octal file permissions (e.g., 0755)

Artifact Type Defaults:

Type

Default Destination

jar

/usr/lib/app/libs/

shared_lib

/usr/lib/

wheel

/usr/lib/python3/site-packages/

node_module

/usr/lib/node_modules/

file

/tmp/

File & Script Management

Field

Type

Description

copy_files

CopyFile[]

Files to copy from host; format: {source, destination, permissions?}

scripts

EmbeddedScript[]

Embedded scripts; format: {path, content, mode?, description?}

User & Group Management

Field

Type

Description

groups

GroupAccount[]

Groups to create; format: {groupname, gid}

users

UserAccount[]

Users to create; format: {username, uid, gid, home?, shell?}

UserAccount Fields:

Field

Type

Required

Default

username

string

Yes

uid

int

Yes

gid

int

Yes

home

string

No

/home/{username}

shell

string

No

/sbin/nologin

Resource Hints

Field

Type

Description

resource_hints

object

Resource hints (stored as OCI labels)

requests

object

Resource requests: {memory, cpu}

limits

object

Resource limits: {memory, cpu}

Example:

resource_hints:  requests:    memory: "256Mi"    cpu: "100m"  limits:    memory: "1Gi"    cpu: "500m"

Architecture Overrides

Field

Type

Description

arch_overrides

object

Architecture-specific config

amd64

ArchConfig

Overrides for amd64 (packages, env_vars)

arm64

ArchConfig

Overrides for arm64 (packages, env_vars)

Example:

arch_overrides:  amd64:    packages:      - intel-specific-package  arm64:    packages:      - arm-specific-package

Build Hooks

Field

Type

Description

hooks

object

Build lifecycle hooks

pre_build

string[]

Commands to run before main build steps

post_build

string[]

Commands to run after main build steps

Dependency Pinning

Field

Type

Default

Description

pin_style

string

none

Package pinning: exact (pin versions), major-minor (pin major.minor), none (no 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 enabled

Result: 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 explicitly

CleanStart 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 repos

EXIT 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: docker ps

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_HOST

Docker daemon socket

unix:///var/run/docker.sock (Linux), npipe:////./pipe/docker_engine (Windows)

DOCKER_CONFIG

Docker config directory for auth

$HOME/.docker

DOCKER_BUILDKIT

Enable BuildKit (recommended)

DOCKER_BUILDKIT=1

FILES

File

Purpose

spec.yaml

IncrementalSpec YAML file (generated or manual)

Dockerfile

Generated multi-stage Dockerfile (ephemeral or saved via --dockerfile-only)

.dockerignore

Docker build context exclusions (inherited from base image)

/sbom.json

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.