Appearance
SIVA — Guía de Despliegue en Servidor
Documentación técnica interna. Los scripts y la configuración viven en
deploy/docker/del repositorio. Índice general:docs/README.md.
Arquitectura de despliegue
┌──────────────────────────────────────────────────────────────┐
│ Servidor Debian 12 (192.168.1.80) │
│ │
│ /home/siva/siva-app/ │
│ ├── backend/ (Dockerfile → prod) │
│ ├── frontend/ (Dockerfile → nginx) │
│ └── deploy/docker/ │
│ ├── docker-compose.yml (orquestacion) │
│ ├── .env.prod (variables de entorno) │
│ ├── data/ (SQLite, persistente) │
│ ├── storage/ (uploads, persistente) │
│ └── public/ (assets estaticos) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Frontend │ │ Backend │ │ Mailpit │ │
│ │ :80 │→│ :3000 │ │ :1025 │ │
│ │ (nginx) │ │ (Node) │ │ :8025 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ┌───────────────┐ ┌──────────────────┐ │
│ │ Doc usuario │ │ Doc sistema │ │
│ │ :8080 (nginx)│ │ :8081 (nginx) │ │
│ └───────────────┘ └──────────────────┘ │
│ ↑ ↑ ↑ │
│ :80 :3000 :1025, :8025 │
│ :8080 :8081 (documentación) │
└───────┼────────────┼─────────────┼──────────────────────────┘
│ │ │
Usuario Swagger/API Mailpit UI
(web) (docs) (debug email)La aplicación corre en 5 contenedores Docker interconectados por una red bridge interna (siva-network):
| Contenedor | Imagen | Puerto host | Descripción |
|---|---|---|---|
siva-frontend | inap/siva-frontend:latest | 80 | Vue 3 compilado servido por Nginx |
siva-backend | inap/siva-backend:latest | 3000 | API REST Node.js + Express |
siva-mailpit | axllent/mailpit:latest | 1025, 8025 | Captura de emails para desarrollo |
siva-doc-user | inap/siva-doc-user:latest | 8080 | Manual de usuario (VitePress + Nginx) |
siva-doc-system | inap/siva-doc-system:latest | 8081 | Documentación de sistema (VitePress + Nginx) |
Todos los contenedores usan restart: unless-stopped, lo que significa que:
- Se inician automáticamente al arrancar el servidor (tras un reboot)
- Se reinician automáticamente si crashean
- Solo se detienen si ejecutas manualmente
docker compose down
Los datos (base de datos SQLite y archivos subidos) se almacenan en volúmenes montados en el host (deploy/docker/data/, storage/, public/), por lo que sobreviven a reconstrucciones y reinicios de los contenedores.
Prerrequisitos
En el servidor (Debian 12)
Docker Engine instalado. Si no lo tienes:
bash# Instalar Docker en Debian 12 sudo apt update sudo apt install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-pluginTu usuario (
siva) debe pertenecer al grupodocker:bashsudo usermod -aG docker siva # Cierra sesión SSH y vuelve a entrar para que el cambio surta efectoPuertos abiertos en el firewall (si usas
ufwoiptables):bashsudo ufw allow 80/tcp # Frontend sudo ufw allow 3000/tcp # API / Swagger sudo ufw allow 8025/tcp # Mailpit (opcional)
En tu máquina local
- Acceso SSH a
siva@192.168.1.80(sin contraseña o con clave SSH configurada) rsyncinstalado
Despliegue inicial
1. Primer despliegue
Desde la carpeta deploy/docker/ del proyecto:
bash
cd deploy/docker
chmod +x desplegar_en_servidor.sh
./desplegar_en_servidor.shℹ️ Antes del primer despliegue crea el
.env.prodlocal a partir de la plantilla:cp .env.prod.example .env.prod(ajusta secretos yCORS_ORIGIN).
El script hará automáticamente:
- Verificar conexión SSH y Docker en el servidor
- Sincronizar el código fuente a
/home/siva/siva-app/ - Crear directorios de datos (
deploy/docker/data/,storage/,public/) - Generar
.env.prodcon unJWT_SECRETaleatorio (solo la primera vez) - Construir las imágenes Docker y levantar los contenedores
- Verificar que la API responde correctamente
2. Personalizar la configuración
Si necesitas cambiar la IP del servidor o el directorio de despliegue, usa variables de entorno al ejecutar el script:
bash
SERVER_IP="10.0.0.50" ./desplegar_en_servidor.sh
CORS_ORIGIN="http://midominio.com" ./desplegar_en_servidor.sh3. Verificar el despliegue
Abre en tu navegador:
- Frontend:
http://192.168.1.80 - Swagger API docs:
http://192.168.1.80:3000/api/docs - Mailpit (emails):
http://192.168.1.80:8025 - Documentación de usuario:
http://192.168.1.80:8080 - Documentación de sistema:
http://192.168.1.80:8081
Login por defecto:
superadmin@inap.es/superadmin1234Cambia la contraseña del superadmin inmediatamente tras el primer acceso.
Actualizar un despliegue existente
Cada vez que hagas cambios en el código y quieras redesplegar:
bash
cd deploy/docker
./desplegar_en_servidor.shEl script:
- Sincroniza los archivos modificados al servidor
- Preserva
.env.prod,data/,storage/ypublic/existentes - Reconstruye las imágenes Docker
- Reinicia los contenedores con el nuevo código
- Los datos (SQLite, archivos subidos) se mantienen intactos
Comandos útiles
Ejecuta estos comandos desde tu máquina local:
bash
# Ver logs de todos los contenedores
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose logs -f'
# Ver logs solo del backend
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose logs -f backend'
# Reiniciar todos los servicios
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose restart'
# Detener los servicios (los contenedores se quedarán abajo)
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose down'
# Levantar servicios previamente detenidos
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose up -d'
# Ver estado de los contenedores
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose ps'
# Health check manual
curl http://192.168.1.80:3000/api/healthEstructura en el servidor
/home/siva/siva-app/
├── backend/ # Código fuente del backend
│ ├── Dockerfile
│ ├── package.json
│ └── src/
├── frontend/ # Código fuente del frontend
│ ├── Dockerfile
│ ├── nginx.conf
│ ├── package.json
│ └── src/
├── documentation/ # Documentación VitePress (user/ y system/)
│ ├── Dockerfile # Imagen de producción (ARG SITE)
│ ├── nginx.conf
│ ├── scripts/ # Generación de "última actualización"
│ ├── user/ # Manual de usuario
│ └── system/ # Documentación de sistema
├── docs/ # Documentación técnica interna (esta guía)
├── deploy/podman/ # Configuración Podman (original)
├── deploy/docker/ # ★ Configuración de despliegue Docker
│ ├── docker-compose.yml # Orquestación Docker
│ ├── .env.prod # Variables de entorno de producción
│ ├── desplegar_en_servidor.sh # Script de despliegue
│ ├── README.md # Aviso: guía en docs/operacion/
│ ├── data/ # Persistente — base de datos SQLite
│ │ └── siva.db
│ ├── storage/ # Persistente — archivos subidos (avatars, etc.)
│ └── public/ # Assets estáticos del backend
│ └── images/
└── ...Backup y restauración
Hacer backup
bash
# Desde tu máquina local
ssh siva@192.168.1.80 'tar czf /tmp/siva-backup-$(date +%Y%m%d).tar.gz -C /home/siva/siva-app/deploy/docker data storage .env.prod'
scp siva@192.168.1.80:/tmp/siva-backup-*.tar.gz .Restaurar backup
bash
# Detener servicios primero
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose down'
# Restaurar datos
scp siva-backup-YYYYMMDD.tar.gz siva@192.168.1.80:/tmp/
ssh siva@192.168.1.80 'tar xzf /tmp/siva-backup-YYYYMMDD.tar.gz -C /home/siva/siva-app/deploy/docker/'
# Volver a levantar
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose up -d'Variables de entorno (.env.prod)
| Variable | Descripción | Valor por defecto |
|---|---|---|
PORT | Puerto del backend dentro del contenedor | 3000 |
NODE_ENV | Entorno de ejecución | production |
API_PREFIX | Prefijo de las rutas API | /api |
DB_PATH | Ruta del archivo SQLite | ./data/siva.db |
JWT_SECRET | Clave secreta para tokens JWT | Generado aleatoriamente |
JWT_ACCESS_EXPIRATION | Duración del token de acceso | 1h |
JWT_REFRESH_EXPIRATION | Duración del token de refresco | 7d |
SUPERADMIN_EMAIL | Email del superadmin por defecto | superadmin@inap.es |
SUPERADMIN_PASSWORD | Contraseña inicial del superadmin | superadmin1234 |
SMTP_HOST | Servidor SMTP | mailpit |
SMTP_PORT | Puerto SMTP | 1025 |
SMTP_FROM | Remitente de los emails | noreply@siva.local |
CORS_ORIGIN | Origen CORS permitido | http://192.168.1.80 |
RATE_LIMIT_WINDOW_MS | Ventana de rate limiting | 900000 (15 min) |
RATE_LIMIT_MAX | Peticiones máximas por ventana | 3000 |
Solución de problemas
Error: "Permission denied" al ejecutar Docker
El usuario siva no está en el grupo docker. Solución:
bash
ssh siva@192.168.1.80 'sudo usermod -aG docker siva'
# Cerrar sesión SSH y volver a entrarError: "port is already allocated" (puerto 80 ocupado)
Otro servicio (Apache, otro Nginx) está usando el puerto 80. Opciones:
- Detener el otro servicio:
sudo systemctl stop apache2onginx - Cambiar el puerto: edita
docker-compose.ymlen el servidor (/home/siva/siva-app/deploy/docker/docker-compose.yml) y cambia"80:80"por"8080:80". Luego ejecutadocker compose up -d.
La API no arranca
Revisa los logs del backend:
bash
ssh siva@192.168.1.80 'cd /home/siva/siva-app/deploy/docker && docker compose logs backend'Causas comunes:
DB_PATHincorrecto (debe ser./data/siva.db)JWT_SECRETvacío o muy corto- Puerto 3000 ya en uso
No puedo iniciar sesión
El token JWT se genera con el secreto de .env.prod. Si cambiaste JWT_SECRET después de haber creado usuarios, los tokens existentes quedarán invalidados. Vuelve a iniciar sesión con el superadmin por defecto.
Mailpit no recibe correos en producción
Por ahora Mailpit captura todos los correos. Para usar un SMTP real en producción, edita .env.prod en el servidor:
bash
ssh siva@192.168.1.80
vi /home/siva/siva-app/deploy/docker/.env.prod
# Cambiar SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS
# Luego:
cd /home/siva/siva-app/deploy/docker && docker compose up -d