Version: 1.0.196 Binary: cleanimg-init
What It Does
cleanimg-init is a shell-free init binary for distroless containers. It replaces shell scripts in ENTRYPOINT and CMD by providing built-in commands for container setup, then exec'ing your main process as PID 1.
Because CleanStart production images have no shell, you cannot use #!/bin/sh scripts or bash -c commands. cleanimg-init fills that gap with 16 native builtins, environment variable expansion, and command chaining -- all in a single static binary.
Usage
cleanimg-init [--check FILE] [--init CMD]... [--run CMD]... -- COMMAND [ARGS...]cleanimg-init [--check FILE] [--run CMD]...Two Execution Modes
Init-then-exec (PID 1 entrypoint): Runs init commands, then run commands, then exec()s your main process. The main process replaces cleanimg-init and becomes PID 1 directly.
cleanimg-init \ --init "mkdir -p /data/logs" \ --run "chmod 755 /data/logs" \ --run "envsubst -i /config/template.conf > /config/app.conf" \ -- /app/server --config /config/app.confRun-and-exit (Kubernetes initContainer): Runs setup commands, then exits 0. No exec() phase. Use this in initContainers to prepare shared volumes.
cleanimg-init \ --run "cp /templates/nginx.conf /shared/nginx.conf" \ --run "envsubst -i /shared/nginx.conf"Flags
Flag | Description |
|---|---|
| Command to run in init phase (repeatable, requires |
| Setup command to run after init commands (repeatable) |
| Skip init/run phases if FILE exists (idempotency guard) |
| Separator; everything after becomes the main command for exec() |
| Print version and exit |
| Print usage and exit |
Built-in Commands
These commands execute natively without a shell:
Command | Description |
|---|---|
| Copy files |
| Create directories (supports |
| Move/rename files |
| Remove files |
| Change permissions |
| Create links |
| Create/update file timestamps |
| Read file contents |
| Stream editor (basic substitution) |
| Print text |
| Substitute environment variables in files ( |
| Set environment variables for subsequent commands |
| Extract StatefulSet pod ordinal from hostname |
| List directory contents |
| Print environment |
| File status |
Operators
&&chains commands:"mkdir -p /data && chmod 755 /data">redirects output to a file:"echo hello > /data/greeting.txt"
Environment Variables
All commands support $VAR and ${VAR} expansion. Unset variables expand to empty string.
Ordinal Extraction
The ordinal builtin parses the Kubernetes HOSTNAME to extract the StatefulSet pod index:
cleanimg-init --run "ordinal" -- /app/kafka-serverFrom hostname kafka-2, this sets:
$ORDINAL=2$HOSTNAME_PREFIX=kafka
Subsequent commands can use these variables:
cleanimg-init \ --run "ordinal" \ --run "echo Broker ID is $ORDINAL" \ -- /app/kafka-server --broker.id=$ORDINALIdempotency with --check
The --check flag skips initialization if a marker file exists. Useful when a pod restarts but data volumes persist:
cleanimg-init \ --check /data/.initialized \ --run "mkdir -p /data/logs" \ --run "touch /data/.initialized" \ -- /app/serverOn first start, init runs and creates the marker. On restart, init is skipped entirely.
Debug Logging
Set CLEANIMG_INIT_DEBUG=1 to enable detailed logging to stderr:
[cleanimg-init] DEBUG: checking /data/.initialized[cleanimg-init] DEBUG: file not found, running init[cleanimg-init] DEBUG: RUN: mkdir -p /data/logs[cleanimg-init] DEBUG: exec: /app/serverExit Codes
Code | Meaning |
|---|---|
0 | Success (run-and-exit mode) |
1 | Command error or validation failure |
127 | exec() failed (main command not found) |
N | Exit code from failed external command |
Execution is fail-fast: the first error stops the pipeline immediately.
Dockerfile Example
FROM gcr.io/clean-image-build/redis:8.2.2-r0 ENTRYPOINT ["cleanimg-init", \ "--run", "mkdir -p /data", \ "--run", "chmod 755 /data", \ "--", \ "redis-server", "/etc/redis/redis.conf"]