Summary
Replace the GCE production VM (nuspace-instance) with a Hetzner VPS around April 2027, when the current GCP commitment ends. Keep GCP managed services where it still makes sense (GCS, Pub/Sub, Cloud Run schedule-sync, Secret Manager, WIF) unless we explicitly decide to leave GCP entirely later.
Goal: cheaper compute without rewriting the product — mainly host identity, deploy path, DNS/firewall, and backups.
Context
- Today: single GCE VM runs the full Docker stack (fastapi, postgres, meili, nginx, wg-easy, monitoring).
- Deploy: GitHub Actions → WIF → IAP SSH → Ansible.
- Runtime ADC: containers rely on GCE metadata (
metadata.google.internal) for WAL-G/backups, host-side gcloud secrets, and Gemini enterprise.
- Cloudflare terminates public HTTP(S); VPN is WireGuard (
vpn.nuspace.kz).
Migration checklist
1. Host & networking
2. Deploy path (IAP → normal SSH)
3. Credentials: metadata → JSON via env/secrets
4. Backups (highest silent-failure risk)
5. App integrations that stay on GCP (for now)
6. Terraform / GCP cleanup
7. Cutover plan
Out of scope (unless we decide later)
- Leaving GCS / Pub/Sub / Secret Manager entirely
- Rewriting
google_bucket / signed URL stack for S3-compatible storage
- Multi-node / k8s — still one VM + Docker Compose
Success criteria
- Production serves on Hetzner behind Cloudflare with no IAP dependency.
- Backups land in GCS (or chosen store) for ≥7 consecutive days.
- Deploy from
dev/main works via SSH+Ansible.
- GCP compute VM can be powered off without user-facing impact.
Summary
Replace the GCE production VM (
nuspace-instance) with a Hetzner VPS around April 2027, when the current GCP commitment ends. Keep GCP managed services where it still makes sense (GCS, Pub/Sub, Cloud Run schedule-sync, Secret Manager, WIF) unless we explicitly decide to leave GCP entirely later.Goal: cheaper compute without rewriting the product — mainly host identity, deploy path, DNS/firewall, and backups.
Context
metadata.google.internal) for WAL-G/backups, host-sidegcloud secrets, and Gemini enterprise.vpn.nuspace.kz).Migration checklist
1. Host & networking
e2-standard-2baseline and leave headroom).nuspace.kz,vpn.nuspace.kz, related records) to the new origin IP.2. Deploy path (IAP → normal SSH)
.github/workflows/deploy.ymlwith SSH key (or Hetzner-compatible access).gcloud compute start-iap-tunnelProxyCommand / OS Login certs).ansible/roles/prerequisitesandsecretsso the host does not depend on GCE metadata ADC.docs/ssh-access.md,infra/wg-easy/README.md).3. Credentials: metadata → JSON via env/secrets
metadata.google.internalininfra/prod.docker-compose.yml(extra_hostson fastapi/postgres/backup/migrate).GOOGLE_APPLICATION_CREDENTIALS/ SA JSON for services that still talk to GCP (storage, backups, optional AI)..envon deploy (same pattern as today, but without VM SA metadata).GCP_SIGNING_SERVICE_ACCOUNT_KEY_JSON.4. Backups (highest silent-failure risk)
nuspace-backups-prod(or chosen bucket) after cutover.5. App integrations that stay on GCP (for now)
https://nuspace.kz/api/bucket/gcs-hookstill reaches the new origin after DNS cutover.PUSH_AUTH_*) unchanged and verified.6. Terraform / GCP cleanup
terraform/compute.tf+ VM-only firewall/IAP IAM after cutover.7. Cutover plan
Out of scope (unless we decide later)
google_bucket/ signed URL stack for S3-compatible storageSuccess criteria
dev/mainworks via SSH+Ansible.