ContainerApplication
Source:
src/Cloudflare/Container/ContainerApplication.ts
A Cloudflare Container Application — the deployed, scalable unit that runs a
containerized program on Cloudflare’s compute platform. Alchemy bundles the
main entrypoint, builds a Docker image, pushes it to the Cloudflare
registry, and reconciles the application’s scaling and runtime configuration.
This is the lower-level resource backing the {@link Container} platform
binding; in application code you typically extend Cloudflare.Container to
define and bind a container to a Durable Object rather than referencing this
resource directly. The same props shape (main, instanceType, instances,
etc.) is accepted by the Cloudflare.Container(...) class form shown below.
Defining a Container Application
Section titled “Defining a Container Application”Point main at the container’s entrypoint file; Alchemy bundles it and uses
it as the image’s entrypoint. The application name is derived deterministically
from the stack, stage, and logical ID unless you set an explicit name, and
handler selects which export to run when it isn’t the default.
Minimal container
import * as Cloudflare from "alchemy/Cloudflare";
export class Sandbox extends Cloudflare.Container<Sandbox>()("Sandbox", { main: import.meta.filename,}) {}The single main prop is enough to ship a container: Alchemy bundles the
entrypoint, builds and pushes the image, and provisions an application with
one instance. Reach for the other props only when you need to scale, expose
ports, or customize the build.
Named container with a non-default handler export
export class Worker extends Cloudflare.Container<Worker>()("Worker", { main: import.meta.filename, handler: "runWorker", name: "background-worker",}) {}name pins a stable application name (instead of the generated one), which is
useful for adopting an existing application, while handler runs the named
runWorker export rather than the module’s default.
Bundling & Dependencies
Section titled “Bundling & Dependencies”By default the entrypoint is bundled for the bun runtime. Use runtime to
switch to Node, external to keep native/precompiled packages out of the
bundle (auto-installed in the image unless autoInstallExternals is false),
a custom dockerfile as the image base, and registryId to override the
registry host.
Node runtime with external native deps
export class ImageApi extends Cloudflare.Container<ImageApi>()("ImageApi", { main: import.meta.filename, runtime: "node", external: ["sharp"], autoInstallExternals: true,}) {}Marking sharp as external stops Rolldown from bundling the native module;
because autoInstallExternals is true, Alchemy runs npm install sharp
inside the image so the dependency is present at runtime.
Custom Dockerfile base and registry
export class Custom extends Cloudflare.Container<Custom>()("Custom", { main: import.meta.filename, dockerfile: "FROM oven/bun:1\nRUN apt-get update && apt-get install -y ffmpeg", autoInstallExternals: false, registryId: "registry.cloudflare.com",}) {}Alchemy appends the program-copy and entrypoint steps to your dockerfile,
so you control the base image and any system packages; autoInstallExternals: false skips the redundant install step when your Dockerfile already provides
those packages.
Scaling & Instance Types
Section titled “Scaling & Instance Types”Control the desired and maximum instance counts with instances/maxInstances
and pick a compute size with instanceType. For finer control, override
vcpu, memory, and disk directly.
Autoscaling with a larger instance type
export class Sandbox extends Cloudflare.Container<Sandbox>()("Sandbox", { main: import.meta.filename, instanceType: "standard-1", instances: 1, maxInstances: 5,}) {}The application keeps one instance running and may scale out to five under
load, each on the standard-1 size. Use a larger instanceType (or the
explicit overrides below) when the default dev size is too small.
Explicit CPU, memory, and disk overrides
export class Heavy extends Cloudflare.Container<Heavy>()("Heavy", { main: import.meta.filename, vcpu: 2, memory: "4GB", disk: { size: "10GB" },}) {}These props override the per-instance resource allocation independently of
instanceType, which is handy when a workload needs, say, extra disk for
scratch space without bumping every other dimension.
Runtime Configuration
Section titled “Runtime Configuration”Inject configuration with environmentVariables (plain values) and secrets
(references to stored secrets), and override the image’s command or
entrypoint. labels attach metadata to the deployment.
Environment variables, secrets, and a command override
export class Api extends Cloudflare.Container<Api>()("Api", { main: import.meta.filename, environmentVariables: [{ name: "LOG_LEVEL", value: "info" }], secrets: [{ name: "API_KEY", type: "env", secret: "my-stored-secret" }], command: ["bun", "run", "start"], labels: [{ name: "team", value: "payments" }],}) {}environmentVariables are visible plain values, while secrets map a stored
secret into the runtime as an env var without exposing it in config; command
overrides the container’s startup command and labels tag the deployment for
organization.
Passing env and selecting runtime exports
export class Job extends Cloudflare.Container<Job>()("Job", { main: import.meta.filename, env: { REGION: "wnam", FEATURE_FLAG: "on" }, exports: ["default"],}) {}env injects values into the bundled program’s runtime context (as opposed to
the deployment-level environmentVariables), and exports declares which
symbols from the entrypoint module the runtime should wire up.
Networking & Health Checks
Section titled “Networking & Health Checks”Configure outbound/inbound networking with network and dns, expose
ports, and gate readiness with checks.
export class Web extends Cloudflare.Container<Web>()("Web", { main: import.meta.filename, ports: [{ name: "http", port: 8080 }], network: { assignIpv4: "predefined", mode: "public" }, dns: { servers: ["1.1.1.1"], searches: ["internal"] }, checks: [{ name: "ready", type: "http", port: "8080", tls: false }],}) {}ports publishes the named port the program listens on, network controls IP
assignment and public/private reachability, dns overrides resolver settings,
and checks tells Cloudflare how to probe the container before routing
traffic to it.
Observability & Access
Section titled “Observability & Access”Turn on log shipping with observability and install sshPublicKeyIds for
interactive access to running instances.
export class Api extends Cloudflare.Container<Api>()("Api", { main: import.meta.filename, observability: { logs: { enabled: true } }, sshPublicKeyIds: ["ssh-key-id-123"],}) {}observability.logs.enabled streams the container’s logs into Cloudflare’s
telemetry pipeline (queryable via the resource’s logs/tail operations),
and sshPublicKeyIds authorizes the listed keys to connect to instances for
debugging.
Scheduling & Placement
Section titled “Scheduling & Placement”Influence where and how Cloudflare schedules instances with schedulingPolicy,
constraints, and affinities.
export class Edge extends Cloudflare.Container<Edge>()("Edge", { main: import.meta.filename, schedulingPolicy: "regional", constraints: { tier: 1 }, affinities: { colocation: "datacenter" },}) {}schedulingPolicy selects the control-plane placement strategy,
constraints.tier restricts which capacity tier instances may land on, and
affinities.colocation keeps related instances in the same datacenter to
reduce inter-instance latency.
Rollouts
Section titled “Rollouts”When an update changes the configuration, rollout controls how the new
version is rolled out across instances.
export class Api extends Cloudflare.Container<Api>()("Api", { main: import.meta.filename, instances: 4, maxInstances: 4, rollout: { strategy: "rolling", stepPercentage: 25 },}) {}A rolling strategy with stepPercentage: 25 replaces instances in 25%
increments so the application stays available during the update; the default
immediate strategy swaps everything at once.