#Image Command
Build a container image from ./dist.
#Quick Start
alepha build
alepha image --tag
# → <image.tag>:latest
⚠️ It needs the docker CLI. It shells out to docker build, so it is a local and CI command and cannot run in an in-process build path.
#A Dockerfile you own
No Dockerfile in the app directory: one is generated there, beside alepha.config.ts. One already present: it is used untouched.
⚠️ It lands in the app directory, not in dist/, and that is not a preference: alepha build wipes dist/ on every run, so a file living there could never be committed or edited. The build context is still dist/, so the Dockerfile's COPY . . keeps meaning the built output rather than dragging src/ and node_modules/ in.
The generated header records the manifest facts it came from:
# Generated by `alepha image`, from this build's manifest:
# runtime: node
# entry: index.node.js
# It is yours now. Edit it freely; `alepha image` reuses it untouched
# and only warns when the facts above stop matching a later build.
A later run warns when they no longer match, and never fails. The file is yours after generation, so a hard failure would make an intentional edit feel like a bug; the warning exists only so the drift is not silent.
#Which slice it runs
The primary: the first declared runtime, read from the manifest. An image runs one process from one entry point, and this is the same rule every deployer follows.
A static artifact is refused (it runs no process, so there is nothing to start) and so is a workerd one (only Cloudflare runs it).
#A binary and nothing else
alepha image --compile --tag
Compiles the bun slice first and ships an image holding the binary, on gcr.io/distroless/cc-debian12. Measured on a real app: 197 MB against 279 MB, and 49 MB against 67 MB compressed.
#⚠️ The libc, which is where this goes wrong
A Bun --compile binary is not static, under any triple:
$ file dist/app
ELF 64-bit LSB executable, dynamically linked,
interpreter /lib/ld-musl-aarch64.so.1
$ ldd dist/app
Error loading shared library libstdc++.so.6: No such file or directory
Error loading shared library libgcc_s.so.1: No such file or directory
It needs an interpreter, libstdc++ and libgcc. Put it on a base that has none and you do not get a build failure: you get exec /app/app: no such file or directory, naming a file that is plainly there, from a container that simply stops.
So alepha image derives the triple from the base rather than inheriting whatever the host would default to, and refuses a base with no libc (scratch, distroless/static) rather than building one, because no triple fixes it.
The compiled variant stays root: the base has no shell, so a declared volume cannot be prepared at build time.
#Options
| Flag | Description |
|---|---|
--tag, -t |
--tag uses latest, --tag=1.3.4 that version with the configured name, --tag=other/img:v1 verbatim |
--compile, -c |
Compile the bun slice first and ship an image holding the binary. --compile name names it |
--dockerfile |
Write the Dockerfile and stop, without building an image |
#Configuration
image: is a top-level key in alepha.config.ts, not build.docker: config follows the command that reads it.
1import { defineConfig } from "alepha/cli/config"; 2 3export default defineConfig({ 4 image: { 5 from: "node:26-alpine", 6 volumes: ["/data"], 7 env: { DATA_DIR: "/data" }, 8 image: { tag: "ghcr.io/myorg/app", oci: true }, 9 },10});
build.cloudflare correctly stays under build, because wrangler.jsonc really is written by the build.