Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Containers

The perry/container and perry/compose modules manage OCI containers and multi-container stacks directly from Perry programs — same model as docker compose up, but with the spec as a TS object literal and the orchestration engine running natively in-process (no shell-out to docker-compose).

For the full container subsystem documentation see the dedicated Containers section:

  • Overview — module layout, backend auto-detection, and the canonical lifecycle pattern.
  • Single-Container Lifecycleperry/container: run, inspect, logs, exec, image management.
  • Compose Orchestrationperry/compose: up, down, ps, healthcheck-gated depends_on, env-var interpolation.
  • Networking — internal-only networks, port maps, and the cross-service-DNS workaround.
  • Volumes — named vs. bind mounts and preservation semantics on down().
  • Security — capability isolation, cosign image verification, workload-graph policy tiers.
  • Production Patterns — full Forgejo deployment case study with the patterns it surfaced.

Quick start

import { up } from "perry/compose";

async function bringUpSimpleStack(): Promise<void> {
    const stack = await up({
        version: "3.8",
        services: {
            cache: {
                image: "redis:7-alpine",
                ports: ["6379:6379"],
                networks: ["app-net"],
                healthcheck: {
                    test: ["CMD", "redis-cli", "PING"],
                    interval: "5s",
                    timeout: "3s",
                    retries: 6,
                },
            },
        },
        networks: {
            "app-net": { driver: "bridge" },
        },
    });
    // `stack` is an opaque handle (NaN-boxed integer) — pass it as
    // the first arg to `down` / `ps` / `logs` / `exec`.
    console.log(`stack handle: ${String(stack)}`);
}
import { down } from "perry/compose";

async function tearDown(stack: number): Promise<void> {
    // Default: containers + networks removed; named volumes preserved
    // so a subsequent `up()` against the same spec resumes from
    // committed state.
    await down(stack);

    // Pass `volumes: true` to also drop named volumes — DESTROYS DATA.
    // Useful for test teardown or for a "rip and replace" redeploy.
    await down(stack, { volumes: true });
}

See the linked pages above for the full API surface, production patterns, and case studies.