VPS Hermes — Portfolio y servicios en Oracle Cloud Free Tier
DestacadoVPS gratuito en Oracle Cloud (Ampere A1, 4 cores, 24 GB RAM) para portfolio y servicios auto-gestionados. 0 €/mes, 99.9% uptime en un año.
El problema
Necesitaba un sitio para mi portfolio que estuviera siempre disponible, con SSL válido, y que no costara dinero. Las opciones típicas:
- Hosting compartido (~5 €/mes): limitado, sin control real del servidor
- GitHub Pages / Vercel: gratis pero sin control sobre Nginx, SSL, o headers de seguridad
- VPS de pago (~5-10 €/mes): control total pero coste recurrente
Ninguna me daba control total sin pagar cada mes. Quería un servidor que pudiera tocar — instalar lo que necesitara, configurar seguridad a mi gusto, y tenerlo corriendo sin preocuparme de la factura.
La decisión — Oracle Cloud Free Tier
Oracle ofrece el programa “Always Free” que no caduca. Para un portfolio estático y servicios ligeros, los límites son más que suficientes:
- 1 VM Ampere A1 (4 cores ARM, 24 GB RAM)
- 200 GB de almacenamiento en bloque
- 1 TB de transferencia al mes
- 10 TB de transferencia saliente
No es un trial. Es gratis para siempre mientras no superes los límites. La contrapartida: la UI de Oracle Cloud es terrible — cambia sin avisar, el panel de redes es confuso, y crear una VM ARM requiere una secuencia específica que no está documentada en un solo sitio. Pero una vez configurado, funciona sin intervención.
Implementación
Arquitectura
Internet → DuckDNS → Nginx (443) → Docker Network → [Portfolio, Backend API]
↓
Let's Encrypt (auto-renew via certbot)
↓
UFW (solo 22, 80, 443)
↓
Fail2ban (2 intentos fallidos = ban 1h)
El VPS corre Ubuntu Server. Todo lo que no es sistema base va en contenedores Docker: el portfolio (Astro build → Nginx estático), la API de contacto (Fastify + PostgreSQL), y servicios auxiliares.
Seguridad — no es opcional
- UFW: solo puertos 22 (SSH con key), 80, 443. Nada más abierto.
- Fail2ban: 2 intentos fallidos en /admin = ban 1 hora. No hay tercer intento.
- SSL: Let’s Encrypt con certbot, renovación automática cada 90 días.
- Docker: los contenedores corren en su propia red interna. Nginx es el único punto de entrada.
- server_tokens off: Nginx no revela versión en las respuestas.
En las primeras 24 horas del VPS tuve más de 50 intentos de acceso SSH desde IPs chinas y rusas. Con fail2ban, esos intentos se banean en segundos y no vuelven a aparecer.
Métricas (junio 2026)
| Métrica | Valor |
|---|---|
| Uptime | 99.9% (reinicios solo por actualizaciones del kernel) |
| Tráfico | ~200 visitas/mes (orgánico + referencias) |
| Coste | 0 €/mes |
| Contenedores | 3 (portfolio, API de contacto, admin) |
| Certificados SSL | 2 dominios, renovación automática |
| Baneos fail2ban | ~15-20/mes (bots escaneando /wp-admin, /admin, etc.) |
Qué cambiaría
DuckDNS + Let’s Encrypt desde el día uno. Configuré el cron de renovación después de varios días de tener el VPS funcionando. Durante ese tiempo el portfolio estaba accesible solo por HTTP. Sin incidentes, pero no volvería a hacerlo.
El tier gratuito es real, pero limitado. Los 4 cores ARM comparten recursos con otros tenants de Oracle. No esperes rendimiento de servidor dedicado. Para un portfolio y servicios ligeros, sobra. Para cargas pesadas, mejor mirar otro lado.
Automatizar el deploy antes. Originalmente desplegaba con un proceso manual: build local, rsync al servidor, docker-compose up. Hoy uso build directo en el VPS con docker-compose up -d --build desde el repositorio clonado. CI/CD con GitHub Actions está en backlog, y debería haberlo montado antes.