Container
Source:
src/Docker/Container.ts
A Docker container managed through the active Docker context.
This resource creates, starts, stops, inspects, and removes containers through
the Docker CLI. It is not interchangeable with Cloudflare.Container, which
manages Cloudflare’s container platform; use pushed image references to bridge
Docker-built images into cloud container runtimes.
Running Containers
Section titled “Running Containers”const nginx = yield* Docker.Container("nginx", { image: "nginx:alpine", ports: [{ external: 8080, internal: 80 }], start: true,});Secret Environment
Section titled “Secret Environment”const password = yield* Config.Redacted("POSTGRES_PASSWORD");const db = yield* Docker.Container("postgres", { image: "postgres:18-alpine", environment: { POSTGRES_PASSWORD: password, }, start: true,});Networks and Volumes
Section titled “Networks and Volumes”const network = yield* Docker.Network("app-network");const data = yield* Docker.Volume("postgres-data");const postgresName = "app-postgres";yield* Docker.Container("postgres", { name: postgresName, image: "postgres:18-alpine", ports: [{ external: 15432, internal: 5432 }], volumes: [{ hostPath: data.name, containerPath: "/var/lib/postgresql/data" }], networks: [{ name: network.name, aliases: ["postgres"] }], start: true,});const runtime = yield* Docker.inspectContainer(postgresName);Host Access
Section titled “Host Access”extraHosts writes lines into the container’s /etc/hosts; it changes name
resolution and nothing else. Docker’s host-gateway alias resolves to the
host machine, which is how a container reaches a service on the developer’s
loopback.
On Linux host-gateway is the Docker bridge gateway (typically
172.17.0.1), so a container’s packets to it arrive on the host’s INPUT
chain. Under a default-deny firewall — ufw ships
DEFAULT_INPUT_POLICY="DROP" — the hostname resolves correctly and the
connection then times out, which reads like an application bug rather than a
firewall one. Allow the bridge subnet to fix it:
sudo ufw allow from 172.16.0.0/12.
Reach a service on the developer’s machine
const api = yield* Docker.Container("api", { image: "ghcr.io/acme/api:latest", // `host-gateway` resolves to the host machine, so a database listening // on the developer's loopback is reachable from inside the container. extraHosts: ["host.docker.internal:host-gateway"], environment: { DATABASE_URL: "postgres://postgres@host.docker.internal:5432/app", }, start: true,});Pin a hostname to a fixed address
const api = yield* Docker.Container("api", { image: "ghcr.io/acme/api:latest", // Any `hostname:address` pair — host access is just the common case. extraHosts: ["payments.internal:10.1.2.3"], start: true,});Publish on any free host port
const api = yield* Docker.Container("api", { image: "ghcr.io/acme/api:latest", // `external: 0` lets Docker choose; the assigned port is reported back. ports: [{ external: 0, internal: 3000 }], start: true,});const hostPort = api.ports["3000/tcp"];Traefik
Section titled “Traefik”Route a container through Traefik
const api = yield* Docker.Container("api", { image: "ghcr.io/acme/api:latest", networks: [{ name: "traefik" }], labels: { "traefik.enable": "true", "traefik.http.routers.api.rule": "Host(`api.example.com`)", "traefik.http.services.api.loadbalancer.server.port": "3000", }, stopTimeout: "30 seconds", start: true,});Use a Docker.Context resource
const remote = yield* Docker.Context("remote", { name: "remote-build", docker: "host=ssh://docker@example.com",});
const api = yield* Docker.Container("api", { image: "nginx:alpine", context: remote,});