Skip to content

Fly.Volume reference

Source: src/Fly/MountVolume.ts

Create a per-replica Fly Volume and mount it into a Service.

There is no standalone Volume resource. From a Machine, pass mounts: [{ path, sizeGb }] instead.

Yield MountVolume inside init. App and region come from the parent Service. Provide MountVolumeLive. At runtime you get disk.path.

A Volume attaches to one Machine. count: 3 creates three Volumes in one name-group, one per replica.

export default class Api extends Fly.Service<Api>()(
"Api",
{ app: Site, main: import.meta.url, region: "iad", count: 3, port: 3000 },
Effect.gen(function* () {
const disk = yield* Fly.MountVolume({ path: "/data", sizeGb: 1 });
const fs = yield* FileSystem.FileSystem;
return {
fetch: Effect.gen(function* () {
const text = yield* fs.readFileString(`${disk.path}/hello.txt`);
return HttpServerResponse.text(text);
}),
};
}).pipe(Effect.provide(Fly.MountVolumeLive)),
) {}

sizeGb can grow in place via extendVolume. Fly cannot shrink a Volume. Minimum size is 1 GB.

const disk = yield* Fly.MountVolume({ path: "/data", sizeGb: 10 });

encrypted encrypts the Volume at rest.

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
encrypted: true,
});

fstype is the filesystem (ext4, …).

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
fstype: "ext4",
});

Scheduled snapshots default on (autoBackupEnabled). snapshotRetention is days and updates in place. An on-demand snapshot is VolumeSnapshot.

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
autoBackupEnabled: true,
snapshotRetention: 5,
});

snapshotId restores into a new disk.

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
snapshotId: Nightly.snapshotId,
});

sourceVolumeId forks from an existing Volume.

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
sourceVolumeId: box.mounts[0].volumeId,
});

requireUniqueZone asks Fly to land the Volume in a unique zone.

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
requireUniqueZone: true,
});

name is the Fly volume-group name. If omitted, a unique name is generated from the host’s logical ID and path.

const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
name: "api_data",
});

Source: src/Fly/VolumeSnapshot.ts

A Fly.VolumeSnapshot is an on-demand snapshot of a mounted disk.

Create is fire-and-forget. Identity is the snapshot id from a subsequent list. Destroy is a no-op. Snapshots follow Volume retention. nuke skips this type.

Point it at a Volume id from the parent Machine or Service (mounts[0].volumeId).

const box = yield* Fly.Machine("Box", {
app: Site,
region: "iad",
image: "nginx:alpine",
mounts: [{ path: "/data", sizeGb: 1 }],
});
export const Nightly = Fly.VolumeSnapshot("Nightly", {
app: Site,
volumeId: box.mounts[0].volumeId,
});

Restore into a new disk with snapshotId on the mount. Create-only. The new Machine gets a copy. The original Volume is unchanged.

const restored = yield* Fly.Machine("Restored", {
app: Site,
region: "iad",
image: "nginx:alpine",
mounts: [{ path: "/data", sizeGb: 1, snapshotId: Nightly.snapshotId }],
});

Pass snapshotId on MountVolume. Same create-only rule.

export default class Api extends Fly.Service<Api>()(
"Api",
{ app: Site, main: import.meta.url, region: "iad", port: 3000 },
Effect.gen(function* () {
const disk = yield* Fly.MountVolume({
path: "/data",
sizeGb: 1,
snapshotId: Nightly.snapshotId,
});
return {
fetch: Effect.succeed(HttpServerResponse.text(disk.path)),
};
}).pipe(Effect.provide(Fly.MountVolumeLive)),
) {}