Cómo el ecosistema Go nos permitió reemplazar un backend hosted por una infraestructura self-hosted elegante, mantenible y completamente gratuita.
Hace unos meses tomamos una decisión que parecía arriesgada: migrar una aplicación desde Supabase hosted hacia una arquitectura completamente self-hosted. El resultado fue inesperadamente hermoso.
El contexto
Teníamos una instancia Supabase para autenticación y base de datos. Funcionaba bien, pero dependíamos de sus restricciones y limitaciones para seguir creando features. Cuando el proyecto escaló, se hizo cada vez más difícil mantenerlo y añadir nuevos features debido al mismo diseño de supabase. Por esto, decidimos tomar control total de nuestra infraestructura.
Lo que no esperábamos era descubrir que todo el ecosistema que necesitábamos estaba escrito en Go.
La arquitectura resultante
┌─────────────────────────────────────────┐
│ GCP Compute Engine VM │
│ │
Internet ───────┤ Caddy ──▶ go-app ──▶ Cloud SQL Proxy │──▶ PostgreSQL
│ │ │ │
│ └─────▶ GoTrue ──────────┘ │
│ │
│ Alloy ──▶ Grafana Cloud │
└─────────────────────────────────────────┘
Cinco servicios. Todos escritos en Go.
| Servicio | Propósito | Creador |
|---|---|---|
| go-app | Nuestra API REST | Nosotros |
| Caddy | Reverse proxy + TLS automático | Matt Holt |
| GoTrue | Autenticación (signup, login, OAuth) | Supabase |
| Alloy | Métricas y logs | Grafana Labs |
| Cloud SQL Proxy | Conexión segura a Cloud SQL |
¿Por qué esto es especial?
1. Binarios estáticos
Cada uno de estos servicios compila a un único binario sin dependencias externas. No hay runtime que instalar, no hay versiones de Node que gestionar, no hay virtualenvs. Un binario, un proceso.
# Así de simple es desplegar Caddy
wget https://github.com/caddyserver/caddy/releases/download/v2.8.4/caddy_2.8.4_linux_amd64.tar.gz
tar -xzf caddy_2.8.4_linux_amd64.tar.gz
./caddy run
2. Consumo de recursos mínimo
Nuestra VM de staging corre los 5 servicios con 2GB de RAM. En idle, el consumo total no supera los 400MB. Comparen eso con correr un cluster de Node.js + Redis + Nginx.
3. Configuración declarativa
Caddy, GoTrue y Alloy usan archivos de configuración simples y legibles:
# Caddyfile - 40 líneas para TLS + reverse proxy + CORS
api.dominio.com {
handle /auth/v1/* {
reverse_proxy gotrue:9999
}
handle {
reverse_proxy api:8080
}
}
4. El mismo idioma mental
Cuando debuggeas un problema, saltas entre servicios pero te mantienes en el mismo paradigma. Context propagation, structured logging, graceful shutdown - todos siguen los mismos patrones porque todos son Go.
GoTrue: El corazón de la autenticación
GoTrue es el servicio de autenticación de Supabase, pero es completamente standalone. Lo puedes correr con Docker:
# docker-compose.yml
auth:
image: supabase/auth:v2.184.0
environment:
GOTRUE_DB_DATABASE_URL: postgres://user:pass@db:5432/mydb?search_path=auth
GOTRUE_JWT_SECRET: ${JWT_SECRET}
GOTRUE_SITE_URL: https://miapp.com
command: ["sh", "-c", "gotrue migrate && gotrue serve"]
Y obtienes:
- Signup/login con email y password
- Magic links
- OAuth (Google, Apple, GitHub, etc.)
- Refresh tokens
- JWT estándar compatible con cualquier middleware
Lo mejor: es el mismo servicio que usa Supabase en producción. No es una versión recortada.
Caddy: TLS sin dolor
Si nunca han usado Caddy, prepárense para olvidar todo lo que saben sobre configurar certificados SSL.
api.miapp.com {
reverse_proxy localhost:8080
}
Eso es todo. Caddy obtiene certificados de Let's Encrypt automáticamente, los renueva, y configura HTTPS con los headers de seguridad correctos. Cero configuración adicional.
Alloy: Observabilidad moderna
Grafana Alloy (antes Grafana Agent) recolecta métricas y logs y los envía a Grafana Cloud (que tiene un tier gratuito generoso).
// Recolectar logs de todos los containers Docker
loki.source.docker "containers" {
host = "unix:///var/run/docker.sock"
targets = discovery.docker.containers.targets
}
Con 20 líneas de configuración tienes logs centralizados de todos tus servicios, con labels automáticos por container.
El flujo de autenticación
Usuario Frontend Caddy GoTrue GoApp
│ │ │ │ │
│──── Login ──────────────▶│ │ │ │
│ │─── POST /auth/v1/token ▶│ │ │
│ │ │──── proxy ─────────────▶│ │
│ │ │ │── validate credentials ─│
│ │ │◀─── JWT ────────────────│ │
│ │◀── { access_token } ────│ │ │
│◀─── Logged in ───────────│ │ │ │
│ │ │ │ │
│──── Get entity ─────────▶│ │ │ │
│ │── GET /api/entity ─────▶│ │ │
│ │ Authorization: Bearer │──── proxy ──────────────────────────────────────▶│
│ │ │ │ │── validate JWT
│ │ │ │ │── query DB
│ │◀──────────────────────────────────────────────────── { entity } ───────────│
│◀─── entity ──────────────│ │ │ │
entity: cualquiera sea el recurso de tu db que quieras consumir.
El JWT que emite GoTrue es validado por nuestro middleware en go-app. Mismo secreto, mismo formato, cero fricción.
Costos
| Recurso | Costo mensual |
|---|---|
| VM e2-small (staging) | ~$15 USD |
| Cloud SQL (db-f1-micro) | ~$10 USD |
| Grafana Cloud | $0 (tier gratuito) |
| Caddy, GoTrue, Alloy | $0 (open source) |
| Total staging | ~$25 USD |
Para producción duplicamos los recursos, pero seguimos muy por debajo de lo que pagábamos por Supabase Pro.
Lo que aprendimos
1. Self-hosted no significa complejo
Con las herramientas correctas, self-hosted puede ser más simple que managed. Un docker-compose up -d y tienes todo corriendo.
2. Go es infraestructura
El ecosistema Go para herramientas de infraestructura es impresionante: Docker, Kubernetes, Terraform, Prometheus, Grafana, Caddy, Traefik, Hugo... La lista es interminable.
3. Supabase hizo bien su trabajo
GoTrue es un proyecto de calidad. Está bien documentado, es estable, y hace una cosa bien. Que sea open source y self-hosteable habla bien de Supabase como empresa.
4. La cohesión tiene valor
Hay algo satisfactorio en ver docker ps y saber que todos esos procesos comparten el mismo ADN. Cuando algo falla, el debugging sigue los mismos patrones.
Recursos
- GoTrue GitHub
- Caddy Server
- Grafana Alloy
- Huma v2 - Framework HTTP para Go que usamos en la go-app
Conclusión
Si están considerando migrar de un servicio hosted a self-hosted, el ecosistema Go les tiene cubiertos. No necesitan reinventar la rueda - solo necesitan ensamblar las piezas correctas.
Y si ya programan en Go, van a sentirse como en casa. Es Go todo el camino hacia abajo.
¿Preguntas sobre la migración o la arquitectura? Déjenlas en los comentarios o encuéntrenme en la comunidad de Golang Chile.
Top comments (0)