Skip to main content
CleanStart

Knowledge Hub

cleanimg-init Reference

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

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

--init <CMD>

Command to run in init phase (repeatable, requires -- separator)

--run <CMD>

Setup command to run after init commands (repeatable)

--check <FILE>

Skip init/run phases if FILE exists (idempotency guard)

--

Separator; everything after becomes the main command for exec()

--version

Print version and exit

--help

Print usage and exit

Built-in Commands

These commands execute natively without a shell:

Command

Description

cp

Copy files

mkdir

Create directories (supports -p)

mv

Move/rename files

rm

Remove files

chmod

Change permissions

ln

Create links

touch

Create/update file timestamps

cat

Read file contents

sed

Stream editor (basic substitution)

echo

Print text

envsubst

Substitute environment variables in files (-i for in-place)

setenv

Set environment variables for subsequent commands

ordinal

Extract StatefulSet pod ordinal from hostname

ls

List directory contents

env

Print environment

stat

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

From 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=$ORDINAL

Idempotency 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/server

On 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/server

Exit 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"]