Esta guía pertenece a una versión anterior. Consulte el manual vigente: Manual de instalación y uso.
Documentación técnica

Guía de Instalación Completa

Stack completo: Claude AI · Gemini · N8N · PostgreSQL · Redis · Nginx. Dos rutas de despliegue: contenedores Docker o servidor bare-metal. Elige la que mejor se adapte a tu entorno.

📅 Versión 1.0 — Marzo 2026 ~45 min Docker · ~90 min Bare-metal 💻 Ubuntu 22.04 / Debian 12

📖 Visión general

Esta guía te lleva desde un servidor vacío hasta un sistema completamente funcional con automatización de IA. El stack que vas a instalar incluye:

  • 🤖Claude (Anthropic) + Gemini (Google) — modelos de IA integrados vía API para razonamiento y procesamiento multimodal
  • 🔀N8N — orquestador de flujos self-hosted que conecta todo sin depender de plataformas externas
  • 🐘PostgreSQL 16 — base de datos principal con soporte para pgvector (embeddings de IA)
  • 🔴Redis 7 — caché, sesiones de usuario y colas de mensajes asíncronos
  • 🌐Nginx — reverse proxy con SSL automático, rate limiting y caché HTTP
  • 🐳Docker Compose (opción A) — todos los servicios en contenedores aislados y reproducibles
  • 🖥️Bare-metal con PM2 (opción B) — instalación directa en el servidor para máximo control

⚖️ Docker vs Bare-metal

Ambas rutas llegan al mismo resultado. La diferencia está en el nivel de control, facilidad de mantenimiento y requisitos del entorno.

Aspecto 🐳 Docker 🖥️ Bare-metal
Facilidad de instalación✓ Alta — un solo comando⚠ Media — paso a paso
Aislamiento de servicios✓ Total⚠ Parcial (systemd)
Performance⚠ Overhead mínimo✓ Máximo
Reproducibilidad✓ Exacta en cualquier servidor✗ Depende del OS
Actualizaciones✓ Fácil — rebuild imagen⚠ Manual por servicio
Debugging⚠ Requiere conocer Docker✓ Directo en el sistema
Recomendado paraEquipos, múltiples ambientes, CI/CDServidor dedicado de producción
💡

Recomendación FMV InfraSec: Empieza con Docker para desarrollo y staging. Migra a bare-metal solo si necesitas exprimir el hardware al máximo en producción con mucho tráfico.


✅ Prerrequisitos

Antes de elegir tu ruta, asegúrate de tener lo siguiente:

Servidor recomendado

  • 💾RAM: mínimo 4 GB (recomendado 8 GB para N8N + IA)
  • 💻CPU: 2 vCPUs mínimo, 4 recomendado
  • 🗄️Disco: 40 GB SSD mínimo
  • 🌐OS: Ubuntu 22.04 LTS o Debian 12
  • 🔓Puertos abiertos: 22 (SSH), 80 (HTTP), 443 (HTTPS)
  • 🔑API Keys: Anthropic (Claude) y Google AI Studio (Gemini)
  • 🌍Dominio: con DNS apuntando al servidor (para SSL)

Acceso inicial al servidor

bash
# Conectarse por SSH
ssh root@TU_IP_SERVIDOR

# Actualizar el sistema
apt update && apt upgrade -y

# Instalar herramientas básicas
apt install -y curl wget git ufw fail2ban unzip
bash — Configurar firewall
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
ufw status

🐳 Ruta A — Docker Compose

Todos los servicios corren en contenedores aislados. Un único archivo docker-compose.yml define y orquesta toda la infraestructura.

Estructura del proyecto

fmv-infrasec/ ├── nginx/ │ ├── nginx.conf # Config principal │ └── sites/ │ └── app.conf # Virtual host ├── backend/ │ ├── Dockerfile │ ├── package.json │ └── src/ │ └── index.js # API principal ├── postgres/ │ └── init.sql # Schema inicial ├── .env # Variables de entorno ├── .env.example └── docker-compose.yml

docker-compose.yml

yaml
version: '3.9'

networks:
  fmv-net:
    driver: bridge

volumes:
  postgres_data:
  redis_data:
  n8n_data:
  nginx_certs:

services:

  # ─── PostgreSQL ───────────────────────────
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks: [fmv-net]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      retries: 5

  # ─── Redis ────────────────────────────────
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    networks: [fmv-net]

  # ─── Backend API ──────────────────────────
  backend:
    build: ./backend
    restart: unless-stopped
    env_file: .env
    depends_on:
      postgres: { condition: service_healthy }
      redis: { condition: service_started }
    networks: [fmv-net]
    expose: ["3000"]

  # ─── N8N ──────────────────────────────────
  n8n:
    image: n8nio/n8n:latest
    restart: unless-stopped
    environment:
      N8N_HOST: ${N8N_HOST}
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      N8N_BASIC_AUTH_ACTIVE: true
      N8N_BASIC_AUTH_USER: ${N8N_USER}
      N8N_BASIC_AUTH_PASSWORD: ${N8N_PASSWORD}
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: ${DB_NAME}
      DB_POSTGRESDB_USER: ${DB_USER}
      DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD}
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PASSWORD: ${REDIS_PASSWORD}
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on: [postgres, redis]
    networks: [fmv-net]
    expose: ["5678"]

  # ─── Nginx ────────────────────────────────
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/sites:/etc/nginx/conf.d
      - nginx_certs:/etc/letsencrypt
    depends_on: [backend, n8n]
    networks: [fmv-net]

Variables de entorno (.env)

.env
# ── Base de datos ──────────────────────
DB_NAME=fmvinfrasec
DB_USER=fmvadmin
DB_PASSWORD=CAMBIA_ESTA_CONTRASENA_SEGURA

# ── Redis ──────────────────────────────
REDIS_PASSWORD=CAMBIA_REDIS_PASSWORD

# ── N8N ────────────────────────────────
N8N_HOST=n8n.tudominio.com
N8N_USER=admin
N8N_PASSWORD=CAMBIA_N8N_PASSWORD

# ── IA APIs ────────────────────────────
ANTHROPIC_API_KEY=sk-ant-XXXXXXXXXXXXXXXXXXXX
GOOGLE_AI_API_KEY=AIzaSyXXXXXXXXXXXXXXXXXXX

# ── App ────────────────────────────────
APP_URL=https://tudominio.com
NODE_ENV=production
JWT_SECRET=GENERA_UN_SECRET_LARGO_Y_ALEATORIO
🚨

Nunca subas el .env a Git. Asegúrate de que .env esté en tu .gitignore. Usa un gestor de secretos (Vault, AWS Secrets Manager) en producción.

Configuración de Nginx

nginx — nginx/sites/app.conf
# Redirección HTTP → HTTPS
server {
    listen 80;
    server_name tudominio.com n8n.tudominio.com;
    return 301 https://$host$request_uri;
}

# App principal
server {
    listen 443 ssl http2;
    server_name tudominio.com;

    ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Headers de seguridad
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header Strict-Transport-Security "max-age=31536000";
    add_header Content-Security-Policy "default-src 'self'";

    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;

    location / {
        proxy_pass http://backend:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        limit_req zone=api burst=10 nodelay;
    }
}

# N8N
server {
    listen 443 ssl http2;
    server_name n8n.tudominio.com;

    ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;

    location / {
        proxy_pass http://n8n:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

Despliegue

1

Instalar Docker y Docker Compose

bash
curl -fsSL https://get.docker.com | sh
systemctl enable docker && systemctl start docker
docker --version && docker compose version
2

Clonar el repositorio y configurar

bash
git clone https://github.com/tuusuario/fmv-infrasec.git
cd fmv-infrasec
cp .env.example .env
nano .env   # Completar con tus valores reales
3

Levantar todos los servicios

bash
docker compose up -d --build
docker compose ps        # verificar estado
docker compose logs -f   # ver logs en tiempo real
4

SSL con Let's Encrypt (Certbot)

bash
apt install certbot -y

# Detener Nginx temporalmente para el challenge
docker compose stop nginx

certbot certonly --standalone \
  -d tudominio.com \
  -d n8n.tudominio.com \
  --email admin@tudominio.com \
  --agree-tos --non-interactive

# Reiniciar todo
docker compose start nginx

# Renovación automática
echo "0 0 1 * * certbot renew --quiet && docker compose restart nginx" | crontab -

🖥️ Ruta B — Bare-metal

Instalación directa en el sistema operativo. Mayor control y performance, sin overhead de contenedores. Requiere más pasos pero es ideal para servidores dedicados.

Instalar Node.js 20 LTS

bash
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
node --version && npm --version

PostgreSQL 16

1

Instalar PostgreSQL

bash
apt install -y postgresql postgresql-contrib
systemctl enable postgresql && systemctl start postgresql
psql --version
2

Crear base de datos y usuario

sql
sudo -u postgres psql

CREATE USER fmvadmin WITH PASSWORD 'CONTRASENA_SEGURA';
CREATE DATABASE fmvinfrasec OWNER fmvadmin;
GRANT ALL PRIVILEGES ON DATABASE fmvinfrasec TO fmvadmin;

-- Instalar extensión para embeddings de IA
\c fmvinfrasec
CREATE EXTENSION IF NOT EXISTS vector;
\q

Redis 7

bash
apt install -y redis-server
systemctl enable redis-server

# Configurar contraseña y bind
sed -i 's/# requirepass.*/requirepass TU_REDIS_PASSWORD/' /etc/redis/redis.conf
sed -i 's/bind 127.0.0.1.*/bind 127.0.0.1/' /etc/redis/redis.conf

systemctl restart redis-server
redis-cli -a TU_REDIS_PASSWORD ping  # → PONG

N8N

bash
# Instalar N8N globalmente
npm install -g n8n

# Crear usuario del sistema para N8N
useradd -r -s /bin/false n8nuser
mkdir -p /home/n8nuser/.n8n
chown -R n8nuser:n8nuser /home/n8nuser

# Crear servicio systemd
cat > /etc/systemd/system/n8n.service << 'EOF'
[Unit]
Description=N8N Workflow Automation
After=network.target postgresql.service redis-server.service

[Service]
Type=simple
User=n8nuser
WorkingDirectory=/home/n8nuser
Environment=N8N_HOST=n8n.tudominio.com
Environment=N8N_PORT=5678
Environment=N8N_PROTOCOL=https
Environment=N8N_BASIC_AUTH_ACTIVE=true
Environment=N8N_BASIC_AUTH_USER=admin
Environment=N8N_BASIC_AUTH_PASSWORD=TU_N8N_PASSWORD
Environment=DB_TYPE=postgresdb
Environment=DB_POSTGRESDB_HOST=localhost
Environment=DB_POSTGRESDB_DATABASE=fmvinfrasec
Environment=DB_POSTGRESDB_USER=fmvadmin
Environment=DB_POSTGRESDB_PASSWORD=TU_DB_PASSWORD
ExecStart=/usr/bin/n8n start
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable n8n && systemctl start n8n
systemctl status n8n

Backend (API Node.js)

bash
cd /opt
git clone https://github.com/tuusuario/fmv-backend.git
cd fmv-backend
npm install --production
cp .env.example .env && nano .env

PM2 — Gestor de procesos

bash
npm install -g pm2

cd /opt/fmv-backend
pm2 start src/index.js --name "fmv-api" --instances 2 --exec-mode cluster

# Persistir entre reinicios
pm2 save
pm2 startup systemd
# Ejecuta el comando que PM2 te indique

pm2 status    # ver estado
pm2 logs      # ver logs
pm2 monit     # monitor en tiempo real

Nginx en bare-metal

bash
apt install -y nginx certbot python3-certbot-nginx

# Obtener SSL
certbot --nginx -d tudominio.com -d n8n.tudominio.com \
  --email admin@tudominio.com --agree-tos --non-interactive

# Crear virtual host
cat > /etc/nginx/sites-available/fmv << 'EOF'
server {
    listen 443 ssl http2;
    server_name tudominio.com;

    ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;

    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header Strict-Transport-Security "max-age=31536000";

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

server {
    listen 443 ssl http2;
    server_name n8n.tudominio.com;
    ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
EOF

ln -s /etc/nginx/sites-available/fmv /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

🤖 Integración de IA

Claude AI (Anthropic)

Integración vía SDK oficial de Anthropic. Instala en tu backend:

bash
npm install @anthropic-ai/sdk
javascript — src/services/claude.js
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

// Función reutilizable para tu web
export async function askClaude(userMessage, systemPrompt = '') {
  const response = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    system: systemPrompt,
    messages: [{ role: 'user', content: userMessage }],
  });
  return response.content[0].text;
}

// Endpoint REST para tu frontend
// POST /api/ai/claude
export async function claudeEndpoint(req, res) {
  try {
    const { message, context } = req.body;
    const reply = await askClaude(message, context);
    res.json({ reply, model: 'claude-sonnet-4-6' });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
}

Gemini (Google AI)

bash
npm install @google/generative-ai
javascript — src/services/gemini.js
import { GoogleGenerativeAI } from '@google/generative-ai';

const genAI = new GoogleGenerativeAI(process.env.GOOGLE_AI_API_KEY);

export async function askGemini(prompt) {
  const model = genAI.getGenerativeModel({ model: 'gemini-1.5-pro' });
  const result = await model.generateContent(prompt);
  return result.response.text();
}

Flujos N8N para automatizar tu web

💡

N8N se accede en https://n8n.tudominio.com. Inicia sesión con las credenciales configuradas en tu .env y crea flujos desde la interfaz visual.

Flujos recomendados para automatizar tu web FMV InfraSec:

  • 🔔Formulario de contacto → Claude → Email: cuando un usuario llena el formulario, Claude analiza el mensaje, lo clasifica (soporte, ventas, auditoría) y genera una respuesta inicial automática
  • 📊Webhook → Análisis de logs → Alerta: recibe eventos de seguridad, Claude los analiza y si detecta anomalías envía alerta por Slack o email
  • 🤖Chatbot de la web → Claude API → Redis caché: el chatbot del sitio consulta a Claude, Redis cachea respuestas frecuentes para reducir costos de API
  • 📝CRM → Gemini → Reporte semanal: cada lunes, extrae datos del CRM y Gemini genera un resumen ejecutivo automático para el equipo

🛡️ Post-instalación: Hardening

Configuración de Fail2ban

bash
apt install -y fail2ban

cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5

[sshd]
enabled = true

[nginx-http-auth]
enabled = true
EOF

systemctl enable fail2ban && systemctl restart fail2ban

Monitoreo básico

bash
# Instalar Netdata para métricas en tiempo real
wget -O /tmp/netdata-kickstart.sh https://get.netdata.cloud/kickstart.sh
bash /tmp/netdata-kickstart.sh

# Ver estado de todos los servicios
systemctl status postgresql redis-server nginx n8n

# Docker: ver uso de recursos
docker stats

Backups automáticos de PostgreSQL

bash
# Script de backup
cat > /opt/backup-db.sh << 'EOF'
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR=/var/backups/postgres
mkdir -p $BACKUP_DIR

# Docker
docker exec postgres pg_dump -U fmvadmin fmvinfrasec | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Bare-metal
# pg_dump -U fmvadmin fmvinfrasec | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Eliminar backups más viejos de 30 días
find $BACKUP_DIR -name "*.gz" -mtime +30 -delete
echo "Backup $DATE completado"
EOF

chmod +x /opt/backup-db.sh

# Ejecutar cada día a las 3 AM
echo "0 3 * * * /opt/backup-db.sh >> /var/log/backup.log 2>&1" | crontab -

Checklist final: Firewall activo · SSL instalado · Fail2ban corriendo · Backups programados · Logs rotando · Variables de entorno seguras · API keys con permisos mínimos.

¿Necesitas ayuda con la implementación?

El equipo de FMV InfraSec puede hacer la instalación, configuración y hardening por ti.

Contactar al equipo →