chore(release): v1.0.0 — primer despliegue a producción

project.linkedcorp.net operativo en https://project.linkedcorp.net (servidor
192.168.222.3, BD 192.168.222.32, NPM con SSL forzado). Documenta la
topología real y el flujo de deploy en PRODUCCION.md/DEPLOY_WEB.md, y
actualiza AGENTS.md/ESTADO.md/README.md con el estado actual.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-09-05 22:47:43 -05:00
parent c7b270e6ea
commit 556bbc7314
9 changed files with 424 additions and 67 deletions
+244
View File
@@ -0,0 +1,244 @@
# Deploy Web - project.linkedcorp.net
Arquetipo B (dos servicios separados). Primer deploy realizado el 2026-09-06.
---
## Primer despliegue en producción (ya ejecutado — referencia)
### 1. Entrar al servidor
```bash
ssh deploy@192.168.222.3 -p 2203
```
### 2. Crear estructura de directorios
```bash
sudo mkdir -p /opt/apps/project.linkedcorp.net/{source,backend,frontend,storage,logs}
sudo chown -R deploy:deploy /opt/apps/project.linkedcorp.net
```
### 3. Clonar el repositorio
```bash
cd /opt/apps/project.linkedcorp.net/source
git clone http://[gitea_user]:[token]@gitea.linkedcorp.net/mgonzalez/project.linkedcorp.net.git .
git remote set-url origin http://gitea.linkedcorp.net/mgonzalez/project.linkedcorp.net.git # sin token en claro
```
### 4. Crear el `.env` de producción
```bash
nano /opt/apps/project.linkedcorp.net/backend/.env
```
Variables reales (valores sensibles solo en el archivo del servidor, nunca en git):
```env
PORT=4019
NODE_ENV=production
DB_HOST=192.168.222.32
DB_PORT=3306
DB_NAME=project_linkedcorp
DB_USER=project_linkedcorp
DB_PASSWORD=[generada por crear-db-prod.sh]
JWT_SECRET=[openssl rand -hex 32]
JWT_EXPIRES=8h
CORS_ORIGIN=https://project.linkedcorp.net
STORAGE_ROOT=/opt/apps/project.linkedcorp.net/storage
```
**Nunca copiar el `.env` de desarrollo.**
### 5. Instalar dependencias del backend
```bash
cd /opt/apps/project.linkedcorp.net/source/backend
npm install --omit=dev
cp -r node_modules /opt/apps/project.linkedcorp.net/backend/
```
### 6. Compilar el frontend y publicar el runtime
El frontend es un proceso separado (`serve` sirviendo el build). Runtime propio en `frontend/`
con un `package.json` minimo (solo depende de `serve`) — evita copiar todo `node_modules` de Vite:
```bash
cd /opt/apps/project.linkedcorp.net/source/frontend
npm install
npm run build
cp -r dist /opt/apps/project.linkedcorp.net/frontend/dist
cat > /opt/apps/project.linkedcorp.net/frontend/package.json <<'EOF'
{ "name": "project-linkedcorp-frontend-runtime", "private": true, "version": "1.0.0",
"dependencies": { "serve": "^14.2.6" } }
EOF
cd /opt/apps/project.linkedcorp.net/frontend && npm install --omit=dev
```
> En un redeploy solo hace falta reemplazar `frontend/dist` (borrar y volver a copiar) — el
> `node_modules` del runtime frontend no cambia salvo que cambie la version de `serve`.
### 7. Ejecutar migración de base de datos
```bash
cd /opt/apps/project.linkedcorp.net/source/backend
set -a && source /opt/apps/project.linkedcorp.net/backend/.env && set +a
node src/scripts/migrate-db.js
```
### 8. Inicializar datos
```bash
# Catalogos base (roles, prioridades, estados, tipos de proyecto) — sin datos de ejemplo en produccion:
node src/scripts/seed-db.js
# Usuario Administrador inicial (clave fuerte generada, se muestra UNA sola vez):
node src/scripts/create-admin.js "Nombre Apellido" correo@linkedcorp.net
```
### 9. Crear el servicio systemd del backend
```ini
# /etc/systemd/system/project-linkedcorp-backend.service
[Unit]
Description=project.linkedcorp.net backend
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/opt/apps/project.linkedcorp.net/source/backend
ExecStart=/usr/bin/node src/server.js
EnvironmentFile=/opt/apps/project.linkedcorp.net/backend/.env
Restart=on-failure
RestartSec=5
StandardOutput=append:/opt/apps/project.linkedcorp.net/logs/backend.log
StandardError=append:/opt/apps/project.linkedcorp.net/logs/backend-error.log
[Install]
WantedBy=multi-user.target
```
### 10. Crear el servicio systemd del frontend
```ini
# /etc/systemd/system/project-linkedcorp-frontend.service
[Unit]
Description=project.linkedcorp.net frontend
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/opt/apps/project.linkedcorp.net/frontend
ExecStart=/usr/bin/node node_modules/.bin/serve -s dist -l 5196
Restart=on-failure
RestartSec=5
StandardOutput=append:/opt/apps/project.linkedcorp.net/logs/frontend.log
StandardError=append:/opt/apps/project.linkedcorp.net/logs/frontend-error.log
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable project-linkedcorp-backend project-linkedcorp-frontend
sudo systemctl start project-linkedcorp-backend project-linkedcorp-frontend
sudo systemctl status project-linkedcorp-backend project-linkedcorp-frontend
```
### 11. Configurar Nginx Proxy Manager
Proxy Host:
| Campo | Valor |
|-------|-------|
| Domain | `project.linkedcorp.net` |
| Forward Hostname/IP | `192.168.222.3` |
| Forward Port | `5196` (frontend) |
| Scheme | `http` |
| SSL | Let's Encrypt, Force SSL |
Custom Location:
| Campo | Valor |
|-------|-------|
| Location | `/api` |
| Forward Hostname/IP | `192.168.222.3` |
| Forward Port | `4019` (backend) |
| Scheme | `http` |
### 12. Verificar
```bash
curl http://127.0.0.1:4019/health
curl -o /dev/null -w "%{http_code}\n" http://127.0.0.1:5196/
curl https://project.linkedcorp.net/api/auth/login -X POST -H 'Content-Type: application/json' -d '{...}'
```
### 13. Limpiar archivos `.md` del source
```bash
find /opt/apps/project.linkedcorp.net/source -type f -iname '*.md' -delete
```
> Pendiente al 2026-09-06: no ejecutado en el primer deploy (bloqueado por el entorno del agente
> que hizo el despliegue). Ejecutar manualmente o en el proximo deploy.
---
## Actualizaciones (deploys posteriores)
1. Cambios en desarrollo, `npm run build` local OK.
2. Si corresponde, subir version (`VERSIONADO.md`): actualizar `VERSION` y `CHANGELOG.md`.
3. `git add . && git commit -m "..." && git push origin main`.
4. `ssh deploy@192.168.222.3 -p 2203`
5. `cd /opt/apps/project.linkedcorp.net/source && git fetch origin main && git reset --hard origin/main`
6. Si cambio el backend:
```bash
cd backend && npm install --omit=dev
cp -r node_modules /opt/apps/project.linkedcorp.net/backend/
```
7. Si cambio el frontend:
```bash
cd ../frontend && npm install && npm run build
rm -rf /opt/apps/project.linkedcorp.net/frontend/dist
cp -r dist /opt/apps/project.linkedcorp.net/frontend/dist
```
8. Si cambio el schema de BD:
```bash
cd ../backend
set -a && source /opt/apps/project.linkedcorp.net/backend/.env && set +a
node src/scripts/migrate-db.js
```
9. Confirmar `DB_HOST=192.168.222.32` en el `.env` de produccion antes de reiniciar.
10. Reiniciar servicios:
```bash
sudo systemctl restart project-linkedcorp-backend
sudo systemctl restart project-linkedcorp-frontend
```
11. **Confirmar cambio de PID** (si cambio el backend):
```bash
ps -ef | grep 'node src/server.js' | grep -v grep
```
12. Verificar: `curl http://127.0.0.1:4019/health`.
13. Limpiar `.md`: `find /opt/apps/project.linkedcorp.net/source -type f -iname '*.md' -delete`.
---
## No tocar durante deploy
- `/opt/apps/project.linkedcorp.net/backend/.env`
- `/opt/apps/project.linkedcorp.net/storage/`
- `/opt/apps/project.linkedcorp.net/logs/`
## Notas
- `.env` de produccion nunca se versiona ni se copia desde desarrollo.
- BD de produccion siempre `192.168.222.32`; desarrollo siempre `192.168.222.20`. Confirmar antes
de cada deploy.
- `create-admin.js` es idempotente por email (`ON DUPLICATE KEY UPDATE`) — reutilizable para
resetear la clave del admin si hace falta (genera una nueva clave fuerte cada vez que se corre).