Docker.Volume reference
Volume
Section titled “Volume”Source:
packages/docker/src/Volume.ts
A Docker volume managed through the active Docker context.
Pre-existing same-name volumes are treated as foreign until the engine is
allowed to adopt them with --adopt or adopt(true). This includes volumes
bearing this stack’s labels but a different alchemy::volume-instance
generation after state loss. The previous generation is trusted only when
the engine supplies its persisted attributes.
Each newly created volume receives an internal alchemy::volume-instance
label that identifies its resource generation. Alchemy verifies this identity,
the creation timestamp and the recorded Docker metadata before updating,
replacing or removing a tracked volume. Volumes adopted without this label
are checked against their previously observed identity instead.
An explicitly adopted volume that originated outside the current resource generation is not automatically deleted to apply changed immutable settings. Alchemy fails the plan instead, so data migration is a deliberate operation.
Docker removes volumes by name, not an immutable object ID: inspection
followed by removal is not atomic. Some Docker Engines report creation times
only to the second; a same-second replacement with copied labels may be
indistinguishable. Use RemovalPolicy.protect(), retain() and separate
backups for irreplaceable data.
Volume: Creating Volumes
Section titled “Volume: Creating Volumes”Basic volume
const data = yield* Docker.Volume("data", { name: "app-data",});PostgreSQL data volume
const data = yield* Docker.Volume("postgres-data");Driver options and labels
const data = yield* Docker.Volume("db-data", { driver: "local", driverOpts: { type: "nfs", o: "addr=10.0.0.1,rw", device: ":/path/to/dir", }, labels: { "com.example.usage": "database", },});Volume: Docker Context
Section titled “Volume: Docker Context”const data = yield* Docker.Volume("data", { name: "app-data", context: "remote-build",});Volume: Looking up an existing volume
Section titled “Volume: Looking up an existing volume”Volume.lookup references a volume Alchemy doesn’t manage (created with
the Docker CLI, Compose or another stack). It is read during plan/deploy,
never created, updated or removed.
const data = Docker.Volume.lookup({ name: "pgdata" });Volume: Adopting an existing volume
Section titled “Volume: Adopting an existing volume”A managed Docker.Volume with an existing name requires explicit adoption
when it belongs to another owner. Its existing labels, driver and contents
are preserved; adopting does not make immutable configuration changes safe.
import { adopt } from "alchemy/AdoptPolicy";
const data = yield* Docker.Volume("imported-data", { name: "legacy-data",}).pipe(adopt(true));Volume: Protecting data volumes
Section titled “Volume: Protecting data volumes”Changing the name, driver, driver options or labels of a volume created by
Alchemy normally replaces the volume. The default removal policy deletes
the previous physical volume. protect() blocks replacement or destruction;
retain() leaves the physical volume in place when its state is removed.
import * as RemovalPolicy from "alchemy/RemovalPolicy";
const data = yield* Docker.Volume("critical-data").pipe( RemovalPolicy.protect(),);Volume: Validation and ownership conflicts
Section titled “Volume: Validation and ownership conflicts”User-defined labels cannot start with alchemy::. Empty names/drivers and
invalid label or driver-option keys fail with InvalidVolumeOptions, which
reports the offending property path. For the built-in local driver, volume
names must begin with a letter or digit and contain only letters, digits,
_, . or -; invalid names fail during planning before delete-first
replacement. Third-party drivers may support other name formats.
When the observed volume no longer matches its recorded generation, Alchemy
reports OwnedBySomeoneElse instead of modifying or removing it.