CapRover PaaS — Setup Guide

CULTIVA IA — Infraestructura Autoalojada

Guía completa de instalación y configuración de CapRover en VPS Hetzner para el stack de producción de CULTIVA IA.

● Servidor activo Ubuntu 22.04 LTS Hetzner CX32 — 195.201.45.88 *.apps.cultivaia.com Docker 25.x CapRover 1.14
5
Apps desplegadas
● Todas operativas
HTTPS
Let's Encrypt
Auto-renovación activa
4 vCPU
8 GB RAM / 80 GB SSD
Hetzner CX32 — 10.90€/mes
0
Incidencias abiertas
Uptime 99.97% (30d)
📦
Apps desplegadas
cultivaia-api
api.cultivaia.com
Node.js 20 Express 2 instancias 512 MB
cultivaia-web
cultivaia.com
Astro 4 Static 1 instancia 256 MB
n8n
automatizacion.apps.cultivaia.com
One-Click Persistent 1 instancia
postgres
postgres.apps.cultivaia.com
PostgreSQL 16 One-Click 20 GB vol.
redis
redis.apps.cultivaia.com
Redis 7 One-Click 256 MB
plausible
analytics.cultivaia.com
Planificado One-Click
🚀
Instalación paso a paso
1
Preparar el VPS
Ubuntu 22.04 limpio con Docker instalado y puertos 80/443/3000 abiertos.
bash — VPS inicial bash
# Instalar Docker CE
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

# Abrir puertos en UFW
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 3000/tcp  # Panel CapRover
ufw allow 2377/tcp  # Docker Swarm (cluster futuro)
ufw reload
2
Lanzar CapRover
Wildcard DNS ya apuntado: *.apps.cultivaia.com → 195.201.45.88
bash — Arranque CapRover bash
docker run -p 80:80 -p 443:443 -p 3000:3000 \
  -e ACCEPTED_TERMS=true \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /captain:/captain \
  caprover/caprover

# Panel disponible en: http://195.201.45.88:3000
# Password inicial: captain42
3
Configurar dominio y CLI
Vincular el dominio raíz y obtener SSL automático para el panel.
bash — CLI setup bash
# Instalar CLI globalmente
npm install -g caprover

# Configurar servidor (interactivo)
caprover serversetup
# → IP del servidor: 195.201.45.88
# → Dominio raíz: apps.cultivaia.com
# → Email SSL: devops@cultivaia.com
# → Nueva password: ************

# Panel ahora en: https://captain.apps.cultivaia.com
caprover login
# → URL: https://captain.apps.cultivaia.com
4
Desplegar apps con captain-definition
Cada repositorio incluye su fichero de configuración de despliegue.
📄
captain-definition por app
captain-definition — cultivaia-api json
{
  "schemaVersion": 2,
  "dockerfilePath": "./Dockerfile"
}
Dockerfile — cultivaia-api dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3001
CMD ["node", "src/index.js"]
captain-definition — cultivaia-web json
{
  "schemaVersion": 2,
  "dockerfilePath": "./Dockerfile"
}
Dockerfile — cultivaia-web (Astro) dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
🔐
Variables de entorno — cultivaia-api
⚠️ Nunca hardcodear secretos en el código. Configurar desde el panel CapRover → App Configs → Environment Variables.
Variable Valor (ejemplo) App Tipo
NODE_ENV production cultivaia-api config
PORT 3001 cultivaia-api config
DATABASE_URL postgresql://cultivaia:***@postgres.apps.cultivaia.com:5432/cultivaia_prod cultivaia-api secreto
REDIS_URL redis://redis.apps.cultivaia.com:6379 cultivaia-api config
JWT_SECRET eyJhbGciOiJSUzI1NiJ9... cultivaia-api secreto
OPENAI_API_KEY sk-proj-*** cultivaia-api secreto
LEMON_SQUEEZY_SECRET ls_webhook_*** cultivaia-api secreto
N8N_BASIC_AUTH_PASSWORD *** n8n secreto
⚙️
Script de automatización — API CapRover
Usar el cliente TypeScript para CI/CD: crear apps, escalar instancias y rotar env vars desde GitHub Actions sin acceder al panel.
scripts/caprover-deploy.ts TypeScript
const CAPROVER_URL = "https://captain.apps.cultivaia.com";

async function caproverApi(path: string, data?: unknown) {
  const token = process.env.CAPROVER_TOKEN!;
  const res = await fetch(`${CAPROVER_URL}/api/v2${path}`, {
    method: data ? "POST" : "GET",
    headers: {
      "Content-Type": "application/json",
      "x-captain-auth": token,
    },
    body: data ? JSON.stringify(data) : undefined,
  });
  const result = await res.json();
  if (result.status !== 100) throw new Error(result.description);
  return result.data;
}

// Escalar cultivaia-api a 3 instancias tras deploy exitoso
await caproverApi("/user/apps/appDefinitions/update", {
  appName: "cultivaia-api",
  instanceCount: 3,
});

// Rotar JWT_SECRET sin downtime
await caproverApi("/user/apps/appDefinitions/update", {
  appName: "cultivaia-api",
  envVars: [
    { key: "JWT_SECRET", value: process.env.NEW_JWT_SECRET },
  ],
});

// Añadir dominio personalizado cultivaia.com
await caproverApi("/user/apps/appDefinitions/customdomain", {
  appName: "cultivaia-web",
  customDomain: "cultivaia.com",
});
Buenas practicas de produccion
# Practica Aplicacion CULTIVA IA Estado
1 Wildcard DNS primero — configurar antes de instalar *.apps.cultivaia.com → 195.201.45.88 ✓ Listo
2 captain-definition versionado con el codigo En cada repo Git (api, web) ✓ Listo
3 HTTPS everywhere — Let's Encrypt por app Activado en todas las apps publicas ✓ Listo
4 Persistent dirs para bases de datos /var/lib/postgresql/data, /home/node/.n8n ✓ Listo
5 Resource limits por app API: 512 MB RAM; Web: 256 MB RAM ✓ Listo
6 One-click apps para infra (no manual) Postgres 16, Redis 7, n8n via one-click ✓ Listo
7 Backups automaticos — cron diario pg_dump + rsync a Hetzner Storage Box ⏳ Pendiente
8 Monitorizar con NetData integrado captain.apps.cultivaia.com:19999 ✓ Activo
🖱️
One-Click Apps disponibles
ℹ️ Accede desde el panel → One-Click Apps / Databases para desplegar software con un clic sin configurar nada manualmente. Ideal para la infra interna de CULTIVA IA.
CategoriaApp
Bases de datosPostgreSQL, MySQL, MongoDB, Redis
CMSWordPress, Ghost, Strapi, Directus
Automatizacionn8n, Temporal, Windmill
DevOpsGitLab, Drone CI, Portainer
CategoriaApp
MonitorizacionGrafana, Prometheus, Uptime Kuma
AnalyticsPlausible, Matomo, PostHog, Umami
StorageMinIO, Nextcloud, Filebrowser
ComunicacionMattermost, Rocket.Chat