#Docker Deployment
Build a runtime artifact, then turn it into a container image:
alepha build --runtime node
alepha image --tag
manifest.json requires manifestVersion: 2. Rebuild an older artifact before deploying it. Lore, Bay and other artifact consumers must accept this major; additive fields do not change it.
alepha image reads manifest.json from build.output.dist (default dist/) and packages the first declared runtime slice. Building needs an image name: image.tag in the config (see below), unless --tag is a complete name:tag. A workerd or static primary slice is refused because it cannot start a container process. The docker CLI is required; this command belongs to a local machine or CI runner.
#Dockerfile ownership
With no Dockerfile in the app directory, Alepha generates one beside alepha.config.ts. Commit and edit that file. An existing Dockerfile is reused unchanged, with a warning if the manifest facts recorded in its header have moved. The build context is dist/, not the app directory.
alepha image --dockerfile # generate without building an image
alepha image --tag=1.3.4 # configured name, version 1.3.4
alepha image --tag=myorg/app:v2 # complete tag override
The artifact has an index.<runtime>.js wrapper, server/<runtime>/ chunks, public/ assets, its manifest and package metadata. Migrations are copied into the image context when present. There is no generated Dockerfile inside dist/.
#Configuration
Image settings are top-level image, separate from build:
1import { defineConfig } from "alepha/cli/config"; 2 3export default defineConfig({ 4 build: { runtime: ["node"] }, 5 image: { 6 env: { 7 DATA_DIR: "/data", 8 DATABASE_URL: "sqlite:///data/app.db", 9 },10 volumes: ["/data"],11 tag: "ghcr.io/myorg/myapp",12 oci: true,13 labels: { source: "https://github.com/myorg/myapp" },14 },15});
| Setting | Meaning |
|---|---|
image.from |
Base image override |
image.command |
Server command override |
image.install |
Extra packages for the generated standard image |
image.env |
Baked defaults, overridden by runtime environment values |
image.volumes |
Volume mount points |
image.user |
Container user override (standard default: uid 1000) |
image.tag |
Default image name |
image.args |
Docker build arguments as a string array |
image.oci |
Revision, timestamp and version labels |
image.labels.source |
Repository URL label, set explicitly |
The generated standard image uses a Node or Bun base and installs runtime dependencies only when the artifact declares them. Each declared volume is prepared before its VOLUME line. Named volumes inherit those permissions; bind mounts retain the host directory's permissions. Baked values are public image defaults, so deliver secrets at runtime.
#Compiled image
alepha build --runtime bun
alepha image --compile --tag
This compiles the Bun slice first, then packages the binary on gcr.io/distroless/cc-debian12 by default. --compile my-app names the binary. The base determines the Linux Bun target triple: a Bun binary needs libc and supporting libraries, so scratch and distroless/static are refused. A compiled image has no default user; set image.user when needed. Runtime dependencies must be bundled, and image.install is ignored in this mode.
For a binary without an image, use alepha compile. For the complete image contract, see alepha image.
#Running
docker run -p 3000:3000 --env-file .env.production ghcr.io/myorg/myapp:latest
The generated image sets SERVER_HOST=0.0.0.0; supply SERVER_PORT to change the listening port. Both standard and compiled apps serve their client assets and apply the artifact's _headers file. See Static File Headers.
Container images are an artifact format. alepha deploy drives configured infrastructure adapters; it does not turn a Docker image into an implicit provider deployment.