deploy/infra — OpenTofu (mokkenstorm DO account) #
Provisions the at-record alpha's DigitalOcean side: a ~2GB droplet with
Docker (via cloud-init). Postgres runs as a container on that same droplet
(see ../docker-compose.yml's db service) rather than a separate managed
DO database cluster — a single-instance deploy with no replicas planned has
no need for a managed multi-tenant DB service, and it cuts the recurring
managed-cluster cost. Cloudflare (tunnel, DNS, WAF) is provisioned separately;
this module is DO-only.
Auth #
The digitalocean provider reads DIGITALOCEAN_TOKEN from the environment: a
personal access token on the mokkenstorm.dev DO account (not riotbyte).
export DIGITALOCEAN_TOKEN=dop_v1_...
State is local (terraform.tfstate), gitignored. Move it to a Spaces/R2
backend before this is anything but an alpha.
Use #
cd deploy/infra
tofu init
tofu apply -var "ssh_public_key=$(cat ~/.ssh/id_ed25519.pub)"
tofu output -raw droplet_ip # SSH + deploy target
DB_PASSWORD (the self-hosted Postgres container's password) is a plain
secret generated once (openssl rand -base64 24) and stored in the 1Password
item read by ../gen-env.sh — it isn't a Tofu output, since the container is
provisioned by docker-compose, not this module.
What it does not do #
- No Cloudflare tunnel/DNS/WAF (separate, needs a Cloudflare token).
- No image build/push (ghcr, manual or CI).
- No app rollout (SSH +
docker compose upafter the droplet exists).