Stack de self-hosting para un VPS pequeño: qué cabe en 2 GB y 4 GB de RAM
Un stack autoalojado inicial y realista en un VPS pequeño: Docker Compose, Caddy, Vaultwarden, Uptime Kuma y Forgejo, un presupuesto de RAM por servicio, copias de seguridad y seguridad básica.
Respuesta corta: un VPS de 2 GB ejecuta sin problemas un núcleo autoalojado formado por Caddy (reverse proxy HTTPS), Vaultwarden (contraseñas), Uptime Kuma (monitorización) y Forgejo (git) con Docker Compose, usando aproximadamente de 0,6 a 1 GB de RAM. Si añades Nextcloud, querrás 4 GB; si eliges herramientas más ligeras como Syncthing o File Browser, 2 GB siguen bastando.
Esta guía ofrece un archivo Compose funcional, un presupuesto de RAM por servicio y las dos cosas que la mayoría de las instalaciones autoalojadas se saltan hasta que es demasiado tarde: copias de seguridad externas y una superficie de red cerrada. Los comandos dan por hecho Debian 12/13 o Ubuntu 24.04 con Docker Engine y el plugin Compose instalados desde el repositorio oficial de Docker.
Presupuesto de RAM por servicio
Las cifras son la memoria residente típica en reposo o con uso ligero, para entre uno y cinco usuarios y con SQLite cuando es posible. Los picos durante actualizaciones, clonados de repositorios grandes o las vistas previas de Nextcloud pueden ser mayores, así que deja al menos un 20% de margen y añade un archivo de swap de 1 a 2 GB.
| Servicio | Función | RAM típica | Notas |
|---|---|---|---|
| SO + sshd + journald | Sistema base | 150–250 MB | Debian o Ubuntu mínimo |
| Docker Engine + containerd | Runtime de contenedores | 80–120 MB | Coste fijo de usar contenedores |
| Caddy | Reverse proxy, HTTPS automático | 20–50 MB | Un solo binario, sin base de datos |
| Vaultwarden | Servidor de contraseñas compatible con Bitwarden | 20–60 MB | Escrito en Rust, SQLite |
| Uptime Kuma | Monitorización de disponibilidad y certificados | 100–200 MB | Node.js; crece con el número de monitores |
| Forgejo | Hosting git, issues, hooks de CI | 150–300 MB | Go; SQLite basta para equipos pequeños |
| Nextcloud + MariaDB + Redis | Archivos, calendario, contactos | 600 MB–1,2 GB | Dominan los workers de PHP-FPM |
| Syncthing | Sincronización de archivos, sin suite web | 50–150 MB | Alternativa más ligera a Nextcloud |
| File Browser | Gestor de archivos web | 20–40 MB | Sube y comparte archivos por HTTPS |
| Radicale | CalDAV y CardDAV | 30–50 MB | Calendario y contactos sin Nextcloud |
Elegir el tamaño del VPS
El stack principal (Caddy, Vaultwarden, Uptime Kuma, Forgejo) más el sistema base ronda de 0,6 a 1 GB, lo que cabe en un servidor de 2 vCPU / 2 GB con espacio para Syncthing y Radicale. Nextcloud con MariaDB y Redis eleva el total a unos 1,5–2,2 GB, así que 4 GB es el mínimo realista si quieres la suite completa y todo lo demás. El disco también importa: los repositorios de Forgejo y los archivos sincronizados crecen, mientras que los servicios en sí solo necesitan unos pocos GB.
En NoctisNode, el plan Pulse (2 vCPU, 2 GB de RAM, 40 GB NVMe, $10 cada 28 días) admite el stack principal, y Umbra (4 vCPU, 4 GB, 60 GB NVMe, $15 cada 28 días) admite el principal más Nextcloud. Ambos son KVM con root completo y una IPv4 dedicada, y pueden pagarse en Monero u otras cripto. Nada en esta guía depende del proveedor.
Archivo Docker Compose
Solo Caddy publica puertos web; las aplicaciones solo son accesibles a través de la red interna de Compose. Forgejo publica además el puerto 2222 para git por SSH, de modo que el OpenSSH del host se queda en su propio puerto. Define `FORGEJO_TAG` en un archivo `.env` con la versión mayor actual de Forgejo y sustituye los dominios de ejemplo por tus propios registros DNS.
# /srv/stack/compose.yaml
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy/data:/data
- ./caddy/config:/config
vaultwarden:
image: vaultwarden/server:latest
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true" # set to "false" after creating your account
volumes:
- ./vaultwarden:/data
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./uptime-kuma:/app/data
forgejo:
image: codeberg.org/forgejo/forgejo:${FORGEJO_TAG}
restart: unless-stopped
environment:
USER_UID: "1000"
USER_GID: "1000"
FORGEJO__service__DISABLE_REGISTRATION: "true"
volumes:
- ./forgejo:/data
ports:
- "2222:22"
# /srv/stack/Caddyfile
# vault.example.com {
# reverse_proxy vaultwarden:80
# }
# status.example.com {
# reverse_proxy uptime-kuma:3001
# }
# git.example.com {
# reverse_proxy forgejo:3000
# }Ponerlo en marcha
- 01.Apunta los registros A (y AAAA) de `vault`, `status` y `git` a la IP del servidor, para que Caddy pueda obtener los certificados en el primer arranque.
- 02.Crea `/srv/stack`, coloca ahí `compose.yaml`, `Caddyfile` y `.env`, y ejecuta `docker compose up -d`.
- 03.Abre la URL de Forgejo y completa el instalador; la primera cuenta que crees con él será la de administrador, ya que el registro público está desactivado.
- 04.Crea tu cuenta de Vaultwarden, luego pon `SIGNUPS_ALLOWED` a `"false"` y vuelve a ejecutar `docker compose up -d`. Deja desactivado el panel de administración salvo que definas un `ADMIN_TOKEN` con hash Argon2.
- 05.Crea el usuario administrador de Uptime Kuma nada más arrancar, porque la página de configuración está abierta a cualquiera hasta que lo hagas.
- 06.Añade monitores para cada servicio y para la caducidad de los certificados, idealmente desde una segunda ubicación, ya que un monitor en el mismo servidor no puede avisar de su propia caída.
Note · Caddy gestiona HTTPS automáticamente. Para cabeceras, límites de tasa y enrutados más complejos, consulta la guía de reverse proxy con Caddy.
Copias de seguridad que de verdad se restauran
Todo lo que merece la pena conservar está en `/srv/stack`: bases de datos SQLite, repositorios de Forgejo, certificados de Caddy y tu configuración. No confíes en las instantáneas del proveedor; guarda tu propia copia cifrada y externa con restic, como se describe en la guía de copias con restic.
Los archivos SQLite copiados mientras un servicio escribe pueden quedar inconsistentes. La forma segura más sencilla en un servidor pequeño es detener el stack durante el minuto que dura la copia. Si añades Nextcloud con MariaDB, vuelca la base de datos con `mariadb-dump` antes de ejecutar restic. Prueba al menos una vez a restaurar en un directorio temporal; una copia que nunca has restaurado es una suposición.
#!/bin/sh
# /usr/local/sbin/stack-backup (run nightly from cron or a systemd timer)
# needs RESTIC_REPOSITORY and RESTIC_PASSWORD_FILE in the environment
cd /srv/stack || exit 1
docker compose stop
rc=0
restic backup /srv/stack --tag stack || rc=$?
docker compose start
[ "$rc" -eq 0 ] || exit "$rc"
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --pruneSeguridad básica
- ▹SSH: solo claves, sin inicio de sesión de root con contraseña y, opcionalmente, un puerto no estándar; consulta [la guía de hardening de SSH](/guides/ssh-hardening).
- ▹Advertencia sobre el firewall: los puertos publicados por Docker se saltan las reglas de `ufw`, porque Docker escribe sus propias cadenas de iptables/nftables. Publica solo lo que tenga que ser público (80, 443, 2222) y nunca publiques puertos de bases de datos ni de administración.
- ▹Actualizaciones: activa `unattended-upgrades` en el host y ejecuta `docker compose pull && docker compose up -d` con una periodicidad que realmente cumplas.
- ▹Registro: mantén desactivado el registro público en Vaultwarden y Forgejo; invita a los usuarios en su lugar.
- ▹Cifrado del disco: pon `/srv` en un [root cifrado](/guides/luks-encrypted-root) para que una imagen de disco copiada no revele nada; en un servidor remoto usa el [desbloqueo remoto de LUKS por SSH](/guides/luks-remote-unlock-ssh) y prefiere el formato LUKS2 explicado en [LUKS2 frente a LUKS1](/guides/luks2-vs-luks1).
- ▹Secretos: `.env` y el directorio de datos de Vaultwarden solo deben ser legibles por root (`chmod 600`/`700`).
Preguntas frecuentes
Q¿Cuánta RAM necesito para self-hosting?
AUn stack autoalojado básico con Caddy, Vaultwarden, Uptime Kuma y Forgejo funciona con unos 0,6 a 1 GB incluidos el SO y Docker, así que un VPS de 2 GB es suficiente. Añadir Nextcloud con MariaDB y Redis hace de 4 GB el mínimo práctico.
Q¿Puedo ejecutar Nextcloud en un VPS de 2 GB?
AFunciona, pero junto a otros servicios deja poco margen y se vuelve lento con las vistas previas o los picos de sincronización. Con 2 GB, Syncthing más File Browser y Radicale cubren archivos, calendario y contactos con una fracción de la memoria.
Q¿Es seguro autoalojar Vaultwarden?
AVaultwarden solo guarda datos de la bóveda cifrados de extremo a extremo, así que comprometer el servidor no expone directamente las contraseñas en claro. Mantén desactivado el registro, deja el panel de administración desactivado o protegido con un token con hash, actualiza con regularidad y haz copia de su directorio de datos.
Q¿Cuál es el mejor reverse proxy para un stack Docker autoalojado?
ACaddy es el más sencillo para instalaciones pequeñas porque obtiene y renueva los certificados HTTPS automáticamente con unas pocas líneas de configuración. Nginx y Traefik también funcionan, pero requieren más configuración.
Q¿ufw protege los contenedores Docker?
ANo por defecto. Los puertos publicados con la opción `ports:` de Docker se saltan ufw porque Docker inserta sus propias reglas de firewall, así que publica solo los puertos que deban ser públicos.