Skip to content

Docker.Volume reference

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.

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",
},
});
const data = yield* Docker.Volume("data", {
name: "app-data",
context: "remote-build",
});

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" });

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));

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.