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
cultivaia-web
cultivaia.com
n8n
automatizacion.apps.cultivaia.com
postgres
postgres.apps.cultivaia.com
redis
redis.apps.cultivaia.com
plausible
analytics.cultivaia.com
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.
| Categoria | App |
|---|---|
| Bases de datos | PostgreSQL, MySQL, MongoDB, Redis |
| CMS | WordPress, Ghost, Strapi, Directus |
| Automatizacion | n8n, Temporal, Windmill |
| DevOps | GitLab, Drone CI, Portainer |
| Categoria | App |
|---|---|
| Monitorizacion | Grafana, Prometheus, Uptime Kuma |
| Analytics | Plausible, Matomo, PostHog, Umami |
| Storage | MinIO, Nextcloud, Filebrowser |
| Comunicacion | Mattermost, Rocket.Chat |