alepha@docs:~/docs/.content/release/docs/guides/deployment$
cat 5-docker.md | pretty
3 min read
Last commit:

#Docker Deployment

Build a runtime artifact, then turn it into a container image:

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

bash
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:

typescript
 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

bash
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

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