#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
--tag value |
Image |
|---|---|
--tag, no value |
<image.tag>:latest |
--tag=1.3.4 |
<image.tag>:1.3.4 |
--tag=:1.3.4 |
<image.tag>:1.3.4 |
--tag=myorg/app:v2 |
myorg/app:v2, verbatim |
Every form but the last needs image.tag in the config.
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: {14 source: "https://github.com/myorg/myapp",15 licenses: "MIT",16 },17 },18});
| Setting | Meaning |
|---|---|
image.from |
Base image (default node:24-alpine, oven/bun:alpine) |
image.command |
Server command (default node or bun) |
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 |
Write the OCI labels below |
image.labels |
source, title, description, licenses |
With oci: true, each image.labels field becomes an org.opencontainers.image.* LABEL line in the generated Dockerfile (source is what links a GHCR package to its repository), and alepha image adds revision (the git commit), created and version (from the tag) at build time. Without oci, image.labels is ignored. The generated Dockerfile always labels the image dev.alepha.runtime, naming the slice it runs.
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.