Legendary Arena Lab

Droplet Snapshots

wiki

Droplet Snapshots

Migration in progress. api.legendary-arena.com and its PostgreSQL are moving off Render onto a self-hosted DigitalOcean Ubuntu droplet fronted by Cloudflare, per docs/PLAN.md . Until decommission, Render stays warm as the rollback target.

Summary

DigitalOcean snapshots are whole-host disk images used as fast rollback points during the migration and as the “rebuild the box” leg of disaster recovery. This page explains how snapshots differ from DigitalOcean’s automated Backups, where the plan’s named milestone snapshots (pre-hardening-baseline, post-bootstrap-hardened) fit, and — critically for this single-box design — why a snapshot is not a substitute for the tested pg_dump → Cloudflare R2 restore that governs database recovery. Snapshots protect the whole OS + app + DB state; R2 protects the database content with a rehearsed restore (docs/PLAN.md ; Render-to-DigitalOcean Migration ).

Mechanics

Snapshots vs automated Backups

DigitalOcean offers two disk-image features (vendor behavior below is current as of mid-2026 — confirm specifics in the DigitalOcean snapshots docs, since pricing and retention change):

AspectSnapshotsAutomated Backups
TriggerOn-demand (manual or scripted)Automatic on a schedule
FrequencyWhenever you chooseConfigurable (e.g. daily / weekly)
RetentionUntil you delete themFixed window (or usage-based)
PricingPer compressed used size (≈$0.06/GB-month)A percentage of droplet cost (basic plans), or usage-based
ConsistencyBest powered-off; live possible (crash-consistent)Crash-consistent, taken live
Survives droplet deletionYesNo (unless converted to a snapshot)
Cross-regionTransferable to other regionsSame datacenter only
ScopeRoot disk (attached volumes snapshot separately)Root disk only

Snapshots are the flexible, long-lived tool; Backups are the set-and-forget safety net. For this migration the primary use is named milestone snapshots taken by hand at clean lifecycle points.

Milestone snapshots in the migration lifecycle

The plan names two snapshots explicitly (docs/PLAN.md §5.1 ); the others below are the same pattern applied at each risk boundary:

WhenSnapshot nameSource
Right after cloud-init first-boot validationpre-hardening-baselinePLAN §5.1 CProvision Droplet
After SSH hardening, UFW, fail2ban, unattended-upgradespost-bootstrap-hardenedPLAN §5.1 I / PLAN §5
After Node + Nginx + TLS + Postgres are up(optional intermediate)pattern, not a named plan gate
Before a risky change or the cutover(named pre-change snapshot)pattern

These give fast whole-host rollback points that do not depend on the application-level R2 dumps.

Taking a snapshot

Powered-off gives the most consistent image; a live snapshot is crash-consistent only. At the pre-hardening-baseline point there is no database yet, so a live snapshot is fine. Once PostgreSQL is on the box, prefer power-off (or at least quiesce the DB) for any snapshot you might restore:

# powered-off (preferred once Postgres is co-located):
sudo shutdown -h now          # then snapshot from the DO control panel or doctl, and power back on

# scripted / on-demand via doctl:
doctl compute droplet-action snapshot <droplet-id> --snapshot-name "pre-hardening-baseline"

A simple retention script keeping the last N scripted snapshots and deleting older ones can complement or partly replace automated Backups while giving you control over timing and naming.

Snapshot vs the R2 restore path — the boundary that matters

Because the plan co-locates the boardgame.io server and PostgreSQL on one box (docs/PLAN.md §1 ):

  • The authoritative database recovery path is the planned pg_dump -Fc → Cloudflare R2 flow with a tested restore (docs/PLAN.md §1 ; scripts 50-backup.ps1 / 51-restore.ps1 are planned, not yet in infra/ ). A restore you have not tested is not a backup (Render-to-DigitalOcean Migration § Edge Cases ).
  • A pure snapshot restore brings back an old database frozen at snapshot time; it buys whole-host rollback and the “rebuild from docs + image” DR exercise, not point-in-time or cross-host database recovery.
  • Snapshots are secondary insurance layered on top of R2 — not a replacement for it.

Interactions

  • Provision Droplet — takes the first milestone snapshot, pre-hardening-baseline, right after first-boot validation.
  • Ubuntu Droplet Setup — the bring-up sequence whose risk boundaries are the natural snapshot points (post-bootstrap-hardened after Phase 1).
  • Migration Checklist — lists the post-bootstrap-hardened snapshot as a near-term bring-up item.
  • Render-to-DigitalOcean Migration — the single-box SPOF and the tested-R2-restore mitigation that fixes the boundary between snapshots and database backups.

Edge Cases

  • A snapshot is not a database backup. Restoring a snapshot rolls the whole box — including the database — back to snapshot time; use the R2 pg_dump path for authoritative or point-in-time DB recovery.
  • Live snapshots of a running Postgres can be inconsistent. Once the DB is on the box, power off or quiesce before a snapshot you intend to rely on; unflushed data or WAL may be captured inconsistently otherwise.
  • Snapshots exclude metadata. Reserved/public IP, cloud firewall rules, tags, and other control-plane state are not in the disk image; a rebuild re-applies those separately. Use a Reserved IP if you need a stable address across a region migration.
  • No file-level restore. You must boot a droplet (or volume) from the snapshot and copy out what you need; there is no partial restore.
  • You cannot downsize from a snapshot. A snapshot of a larger droplet will not create a smaller droplet.
  • Cost creep. Snapshots are billed by compressed used size and persist until deleted — prune ones you no longer need; convert a valuable automated Backup to a snapshot only if you need it beyond its retention window.

Execute

There is no owning script — snapshots are taken from the DigitalOcean control panel or doctl. The migration-relevant actions:

  1. After Provision Droplet first-login validation, snapshot pre-hardening-baseline.
  2. After Phase 1 hardening + base services, snapshot post-bootstrap-hardened (PLAN §5.1 I ).
  3. Before any risky change or the cutover, take a named pre-change snapshot (quiesce Postgres first if it is running).
  4. After a proven-good change, prune stale snapshots to control cost.

References