- Document pypi.ct, swift.ct in ct_infra_hosts output. - Update README table and follow-ups for the new publish registries (verdaccio, pypi via pypiserver, swift via forgejo) on the forge droplet. - All under TF IaC (cloud-init compose, dns, firewall).
6.9 KiB
DO store tier — IaC + live state
DigitalOcean store/backend tier that replaces the dead homelan host black.
Adult content is served only from 1984.is / vps-0; DO holds durable state
and never has a public hostname for the content surface. Full rationale +
homelan→cloud mapping: ../../../.claude/plans / the recovery plan
and ../../../docs/EDGE_ISLAND_MODE.md.
Account / project
- DO account:
ct— TransQuinnFTW@pm.me (active, verified). PAT at~/.vault/do-pat-ct.token. (Separatemcaccount/PAT also exists:~/.vault/do-pat-mc.token-style — do not mix.) - Project:
ct:prod(ed8cdfb7-f6eb-4f92-a44e-2a03627d5baa). All rebuild resources are grouped here. - Region:
nyc3(operator NYC-local). GDPR residency caveat for EU-subject PII is open — see the plan.
Live now (ct-forge / cocotte-forge droplet — now under Terraform)
The cocotte-forge droplet (aliased lilith-forge) that hosts Forgejo (the new git origin) + Verdaccio (the private @lilith/* npm registry, required for publishing updated versions of things like @lilith/mac-sync-client with phone/call support) is now a managed digitalocean_droplet.forge resource.
DNS (forge.ct.uvlava.com, npm.ct.uvlava.com, apex) is driven from its IPv4 address.
If the droplet already exists from the out-of-band provisioning, import it (and optionally the matching cloud firewall):
terraform import digitalocean_droplet.forge <id-from-do-console-or-state> # e.g. 580675125
# Optional: terraform import digitalocean_firewall.forge lilith-forge-fw
After import + apply, the DNS records (forge.ct, npm.ct, apex) will be driven from the resource IP, and the firewall resource will manage the rules. The existing cloud fw (if not imported) may need manual cleanup or rename to avoid conflicts.
(See the "Live now" table in the previous version of this README for the id 580675125 and current IP if you need to cross-reference before import.)
| Thing | Value |
|---|---|
| Droplet (TF resource) | cocotte-forge (digitalocean_droplet.forge), s-1vcpu-2gb, nyc3 |
| Public IP | digitalocean_droplet.forge.ipv4_address (was 134.199.243.61) |
Forgejo (git, new origin) |
http://:3000 (or forge.ct.uvlava.com once Caddy) · git-ssh :2222 |
Verdaccio (@lilith/* npm) |
http://:4873 (or https://npm.ct.uvlava.com once TLS) |
| PyPI (Python packages, new service) | http://:8080 (or https://pypi.ct.uvlava.com once TLS) — pypiserver |
| Swift (Swift packages via Forgejo registry, new) | https://forge.ct.uvlava.com/api/packages//swift (or https://swift.ct.uvlava.com once TLS) |
| Cloud firewall | digitalocean_firewall.forge (lilith-forge-fw) — inbound 22/2222/3000/4873/8080/8081 from admin_ips + vps-0/plum |
| Forgejo admin | user quinn — password at ~/.vault/forge-admin-quinn.password |
| Forgejo API token | ~/.vault/forge-admin-quinn.api-token |
| Repo | quinn/lilith-platform.live (private) |
Git remote on plum: forge →
ssh://git@134.199.243.61:2222/quinn/lilith-platform.live.git (push with
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519_1984").
Cloud-init that builds this box: cloud-init/forge.yaml
(keep it pure-ASCII — em-dashes break cloud-init's early YAML parse). The
droplet resource now uses it directly.
Follow-ups for the forge box
- TLS (Caddy) in front of Forgejo/Verdaccio/PyPI (see the yaml comment); then move git to HTTPS or keep SSH. swift.ct proxies to Forgejo.
- Join it to the wg1 mesh (update cloud-init or post-provision) and drop the public 3000/4873/8080 exposure (use the backend mesh + firewall).
- Repoint repo
origin+ registry refs +@lilith.npmrc/ PyPI config to the ct-forge services (Verdaccio for npm, pypiserver for PyPI, Forgejo for Swift). Update consumers and publish flows (from ct-forge CI runners on DO). - Bring the
lilith-forge-fwunder TF asdigitalocean_firewall.forge(inbound rules for 22/2222/3000/4873/8080/8081 from admin IPs + vps-0 + plum). - (Optional) make the forge droplet join the same VPC as backend for private paths.
- Add
forge:setup-registriesor post-up hook in cocottetech scripts if needed for service bootstrap (compose now includes them via TF cloud-init).
Terraform (store tier — written, NOT yet applied)
The .tf files describe the full store tier (Managed PG + Spaces + backend
droplet + WG peer + GPU). They are intentionally un-applied until the GDPR
region call and PG sizing are settled. Apply gates on a verified account (done)
and registered SSH keys.
cd ~/Code/@projects/uvlava/terraform/do # IaC moved out of the v2 tree into the uvlava infranet repo
export TF_VAR_do_token="$(cat ~/.vault/do-pat-ct.token)"
export TF_VAR_spaces_access_id="…" # API → Spaces Keys
export TF_VAR_spaces_secret_key="…"
cp terraform.tfvars.example terraform.tfvars # fill ssh_key_fingerprints, admin_ips
terraform init
terraform plan
| File | What |
|---|---|
versions.tf |
provider pin + (commented) Spaces remote backend |
variables.tf |
all inputs; GPU vars gated (account not GPU-allowlisted yet) |
network.tf |
VPC, project, firewall (WG+SSH only), reserved IP |
database.tf |
Managed PG (private VPC, trusted-sources = droplet only) |
spaces.tf |
private media bucket + deny-public policy + CDN |
droplet.tf |
backend droplet + optional GPU droplet |
cloud-init/backend.yaml |
backend bootstrap (WG self-keygen, ufw, pgBouncer) |
outputs.tf |
private PG URI, Spaces endpoint, WG address (sensitive) |
GPU note: this account returns zero gpu-* sizes — DO gates GPU droplets
behind an access request. gpu_enabled=false until granted (hybrid inference
12b/12c). Serverless inference (12a) is unaffected.
Forge/Verdaccio/PyPI/Swift (ct-forge) transition (2026-06-28): The cocotte-forge droplet (now digitalocean_droplet.forge in this TF) hosts Forgejo + Verdaccio + pypiserver (new PyPI service) + Swift registry support (via Forgejo packages) live at the bare IP. uvlava.com DNS (forge.ct.uvlava.com, npm.ct.uvlava.com, pypi.ct.uvlava.com, swift.ct.uvlava.com) + A records are in dns.tf (and the forge droplet + firewall resources added), but the domains are NOT LIVE YET (registrar joker.com NS delegation for uvlava.com to DO nameservers is pending). Old forge.black.lan / npm.black.lan are dead. Use the IP for git pushes, publishing to the new services (Verdaccio 4873 for npm @lilith/*, pypiserver 8080 for PyPI, Forgejo API for Swift), until delegation + Caddy/LE TLS is live on the ct domains (see cloud-init/forge.yaml which now includes pypiserver and updated Caddy). Update scripts/.npmrc/pypirc etc once live. The push scripts and platform infra handle the current IP. New services on the forge droplet for publishing packages (no more black).
Secrets
None live in this tree. All under ~/.vault/ (0600). .gitignore blocks
*.tfstate, *.tfvars, .terraform/.