GREEN PACKAGE SKILL · DIGITALOCEAN · DBOS

DBOS Package Skill

A reproducible, production-oriented DBOS durable-workflow service on one DigitalOcean Droplet, with a TypeScript reference API, colocated PostgreSQL, Cloudflare HTTPS, R2 backups, and restart acceptance.

Durability is tested across a host reboot. The reference workflow records its first failed activity attempt, sleeps durably, and completes after the Droplet returns.

Quick start

npx skills add getcolors/dbos
cp .agents/skills/package-dbos-green/green ./green
chmod +x green
./green build
./green create --dry-run

build renders the deployment without credentials. The dry-run walks the complete workflow while skipping side effects. A real create, acceptance run, or deletion touches live infrastructure and requires separate authorization.

Architecture

Compute

OpenTofu discovers the configured region’s default VPC, then creates one Ubuntu Droplet, firewall, and operator SSH key. It does not create a VPC or require a VPC UUID in desired state.

Runtime

ONCE installs Docker and Caddy and runs the pinned DBOS TypeScript application. PostgreSQL 17 and DBOS share the application container, but PostgreSQL binds only to loopback.

Public boundary

Cloudflare publishes one apex A record. HTTP, HTTPS, and restricted key-only SSH are the only admitted ports; PostgreSQL and internal DBOS interfaces are never public.

Sizing

The benchmark uses four shared vCPUs and 8 GiB RAM, leaving room for Node, PostgreSQL, Docker/Caddy, image replacement, and concurrent acceptance checks.

DBOS SDK 4.25.14 is pinned exactly. This is intentionally a single-node design: process and host restarts recover, but a Droplet, disk, or regional failure causes downtime and there is no automatic failover.

Reference workflow

GET  /health
POST /workflows  {"workflowID":"caller-id","input":"value","delaySeconds":60}
GET  /workflows/:workflowID

The workflow durably sleeps and invokes a retryable activity. The activity records and fails its first attempt, succeeds on its second, and returns a deterministic SHA-256 result over the workflow ID and input. Reusing an ID returns the existing DBOS execution instead of starting duplicate work.

Desired state and credentials

colors.yml is the only desired-state file. It selects the profile, DigitalOcean region and size, restricted SSH sources, DNS, backend, application host, backup destination, and retention. See the configuration reference for every key.

Acceptance and operations

./green create
./scripts/acceptance.sh
ssh dbos-digitalocean 'docker ps'
ssh dbos-digitalocean 'journalctl -u docker -u caddy --since=-1h'

Acceptance checks HTTPS, exactly two activity attempts, deterministic output, and duplicate-ID behavior. It then starts a delayed workflow, reboots the benchmark Droplet, waits for HTTPS recovery, and verifies the original workflow’s result. Because that script performs a real reboot, run it only against an authorized deployment.

Backups, restoration, and upgrades

A daily custom-format pg_dump is uploaded over HTTPS to the configured R2 bucket and prefix, with retention enforced by the container. Test recovery on an isolated replacement: restore into an empty compatible PostgreSQL database, verify DBOS workflow state and activity attempts, then exercise health and workflow retrieval before changing DNS. Never test restoration over the live database.

For upgrades, move the exact DBOS version and source together, review workflow compatibility guidance, inspect generated and golden diffs, take a verified backup, and confirm old pending workflows before retiring old code. PostgreSQL major upgrades require a separately tested dump/restore or pg_upgrade plan.

Prevent-destroy is not a backup. Deleting compute does not authorize deleting R2 objects, the discovered default VPC, unrelated DNS, or any other provider resource.

Development and source

bb test
bb golden
./scripts/launcher.sh
npm --prefix application run typecheck
npm --prefix application run build
npm --prefix application test

Source on GitHub. Inspect every golden change; never accept generated output merely to make the suite pass.