diff --git a/Backup.md b/Backup.md deleted file mode 100644 index 4eecf6b..0000000 --- a/Backup.md +++ /dev/null @@ -1,464 +0,0 @@ -# Backup y Restauración - -## ¿Qué se Respalda? - -NGINX Proxy Manager almacena datos en dos volúmenes Docker: - -### `npm_data` (`/data`) -- 📊 **Base de datos SQLite** (o configuración de DB externa) -- ⚙️ **Configuración de proxy hosts, redirects, streams** -- 🔑 **Access lists, usuarios, permisos** -- 📝 **Logs de acceso y errores** -- 🔧 **Configuraciones NGINX custom** - -### `npm_letsencrypt` (`/etc/letsencrypt`) -- 🔒 **Certificados SSL de Let's Encrypt** -- 🔑 **Claves privadas** -- 📜 **Configuración de renovación automática** - -⚠️ **Crítico**: Ambos volúmenes contienen información sensible. Protege los backups adecuadamente. - -## Backup Manual - -### Método 1: Backup de Volúmenes (Recomendado) - -```bash -# Detener NPM (opcional, para consistencia) -docker compose down - -# Backup de npm_data -docker run --rm \ - -v npm_data:/data:ro \ - -v $(pwd):/backup \ - alpine \ - tar czf /backup/npm_data-$(date +%Y%m%d-%H%M%S).tar.gz -C /data . - -# Backup de npm_letsencrypt -docker run --rm \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v $(pwd):/backup \ - alpine \ - tar czf /backup/npm_letsencrypt-$(date +%Y%m%d-%H%M%S).tar.gz -C /letsencrypt . - -# Reiniciar NPM -docker compose up -d -``` - -### Método 2: Backup en Caliente - -Sin detener el servicio: - -```bash -# Backup de npm_data (servicio corriendo) -docker run --rm \ - -v npm_data:/data:ro \ - -v $(pwd):/backup \ - alpine \ - tar czf /backup/npm_data-$(date +%Y%m%d-%H%M%S).tar.gz -C /data . - -# Backup de npm_letsencrypt -docker run --rm \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v $(pwd):/backup \ - alpine \ - tar czf /backup/npm_letsencrypt-$(date +%Y%m%d-%H%M%S).tar.gz -C /letsencrypt . -``` - -⚠️ **Nota**: Backups en caliente pueden tener inconsistencias en la base de datos si hay escrituras durante la copia. - -### Método 3: Backup de Carpetas Locales - -Si usas bind mounts en lugar de volúmenes: - -```yaml -# docker-compose.yaml con bind mounts -volumes: - - ./data:/data - - ./letsencrypt:/etc/letsencrypt -``` - -```bash -# Backup simple -tar czf npm-backup-$(date +%Y%m%d-%H%M%S).tar.gz data/ letsencrypt/ - -# O con rsync -rsync -av data/ /ruta/backup/npm/data/ -rsync -av letsencrypt/ /ruta/backup/npm/letsencrypt/ -``` - -## Restauración - -### Restaurar desde Backup - -```bash -# 1. Detener NPM si está corriendo -docker compose down - -# 2. Eliminar volúmenes existentes (⚠️ cuidado!) -docker volume rm npm_data npm_letsencrypt - -# 3. Crear volúmenes nuevos -docker volume create npm_data -docker volume create npm_letsencrypt - -# 4. Restaurar npm_data -docker run --rm \ - -v npm_data:/data \ - -v $(pwd):/backup \ - alpine \ - tar xzf /backup/npm_data-YYYYMMDD-HHMMSS.tar.gz -C /data - -# 5. Restaurar npm_letsencrypt -docker run --rm \ - -v npm_letsencrypt:/letsencrypt \ - -v $(pwd):/backup \ - alpine \ - tar xzf /backup/npm_letsencrypt-YYYYMMDD-HHMMSS.tar.gz -C /letsencrypt - -# 6. Verificar permisos -docker run --rm \ - -v npm_data:/data \ - alpine \ - chown -R root:root /data - -# 7. Reiniciar NPM -docker compose up -d -``` - -### Verificar Restauración - -```bash -# Ver logs -docker logs -f nginx-proxy-manager - -# Debería ver: -# [setup ] Starting backend -# [nginx ] Starting nginx - -# Acceder a UI -# http://IP:81 -``` - -## Backup Automatizado - -### Script de Backup - -Crear `backup-npm.sh`: - -```bash -#!/bin/bash - -# Configuración -BACKUP_DIR="/var/backups/nginx-proxy-manager" -RETENTION_DAYS=30 -TIMESTAMP=$(date +%Y%m%d-%H%M%S) - -# Crear directorio si no existe -mkdir -p "$BACKUP_DIR" - -echo "[$(date)] Iniciando backup de NGINX Proxy Manager..." - -# Backup de volúmenes -docker run --rm \ - -v npm_data:/data:ro \ - -v "$BACKUP_DIR":/backup \ - alpine \ - tar czf "/backup/npm_data-$TIMESTAMP.tar.gz" -C /data . - -docker run --rm \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v "$BACKUP_DIR":/backup \ - alpine \ - tar czf "/backup/npm_letsencrypt-$TIMESTAMP.tar.gz" -C /letsencrypt . - -# Verificar backups -if [ -f "$BACKUP_DIR/npm_data-$TIMESTAMP.tar.gz" ] && [ -f "$BACKUP_DIR/npm_letsencrypt-$TIMESTAMP.tar.gz" ]; then - SIZE_DATA=$(du -h "$BACKUP_DIR/npm_data-$TIMESTAMP.tar.gz" | cut -f1) - SIZE_LE=$(du -h "$BACKUP_DIR/npm_letsencrypt-$TIMESTAMP.tar.gz" | cut -f1) - echo "[$(date)] Backup completado:" - echo " - npm_data: $SIZE_DATA" - echo " - npm_letsencrypt: $SIZE_LE" -else - echo "[$(date)] ERROR: Backup falló" - exit 1 -fi - -# Limpiar backups antiguos -echo "[$(date)] Limpiando backups antiguos (>$RETENTION_DAYS días)..." -find "$BACKUP_DIR" -name "npm_*.tar.gz" -mtime +$RETENTION_DAYS -delete - -echo "[$(date)] Proceso completado" -``` - -Hacer ejecutable: - -```bash -chmod +x backup-npm.sh -./backup-npm.sh -``` - -### Programar con Cron - -Backup diario a las 3:00 AM: - -```bash -crontab -e - -# Añadir línea: -0 3 * * * /ruta/a/backup-npm.sh >> /var/log/npm-backup.log 2>&1 -``` - -Ver logs: - -```bash -tail -f /var/log/npm-backup.log -``` - -## Backup a Almacenamiento Remoto - -### rsync a Servidor Remoto - -```bash -#!/bin/bash -BACKUP_FILE="npm-backup-$(date +%Y%m%d-%H%M%S).tar.gz" - -# Crear backup local -docker run --rm \ - -v npm_data:/data:ro \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v $(pwd):/backup \ - alpine \ - sh -c "tar czf /backup/$BACKUP_FILE -C / data letsencrypt" - -# Copiar a servidor remoto -rsync -avz --progress "$BACKUP_FILE" usuario@servidor-backup:/backups/npm/ - -# Opcional: eliminar backup local -rm "$BACKUP_FILE" -``` - -### S3 / MinIO con rclone - -```bash -# Configurar rclone (una vez) -rclone config - -# Script de backup a S3 -BACKUP_FILE="npm-backup-$(date +%Y%m%d-%H%M%S).tar.gz" - -docker run --rm \ - -v npm_data:/data:ro \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v $(pwd):/backup \ - alpine \ - sh -c "tar czf /backup/$BACKUP_FILE -C / data letsencrypt" - -rclone copy "$BACKUP_FILE" s3-remote:bucket-name/npm-backups/ -rm "$BACKUP_FILE" -``` - -### Backup a NFS/CIFS - -```bash -# Montar share NFS -mount -t nfs servidor.local:/backups /mnt/backups - -# Backup directo a share -docker run --rm \ - -v npm_data:/data:ro \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v /mnt/backups:/backup \ - alpine \ - tar czf /backup/npm-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C / data letsencrypt -``` - -## Migración a Nuevo Servidor - -### En el Servidor Antiguo - -```bash -# Crear backup completo -docker run --rm \ - -v npm_data:/data:ro \ - -v npm_letsencrypt:/letsencrypt:ro \ - -v $(pwd):/backup \ - alpine \ - tar czf /backup/npm-migration.tar.gz -C / data letsencrypt - -# Copiar a nuevo servidor -scp npm-migration.tar.gz usuario@nuevo-servidor:/tmp/ -``` - -### En el Servidor Nuevo - -```bash -# 1. Clonar repositorio -git clone https://git.ictiberia.com/groales/npm -cd npm - -# 2. Crear volúmenes -docker volume create npm_data -docker volume create npm_letsencrypt - -# 3. Restaurar backup -docker run --rm \ - -v npm_data:/data \ - -v npm_letsencrypt:/letsencrypt \ - -v /tmp:/backup \ - alpine \ - tar xzf /backup/npm-migration.tar.gz -C / - -# 4. Iniciar NPM -docker compose up -d - -# 5. Verificar -docker logs -f nginx-proxy-manager -``` - -## Exportar/Importar Configuración - -### Solo Base de Datos (SQLite) - -```bash -# Exportar solo DB -docker exec nginx-proxy-manager \ - sqlite3 /data/database.sqlite .dump > npm-database-$(date +%Y%m%d).sql - -# Importar DB -cat npm-database-YYYYMMDD.sql | docker exec -i nginx-proxy-manager \ - sqlite3 /data/database.sqlite -``` - -## Reset de Contraseña Admin - -Si olvidaste la contraseña: - -```bash -# Método 1: Resetear a credenciales por defecto -docker compose down - -# Ejecutar container temporal con script reset -docker run --rm \ - -v npm_data:/data \ - jc21/nginx-proxy-manager:latest \ - npx knex migrate:latest --env production && npx knex seed:run --env production - -docker compose up -d - -# Login con: -# Email: admin@example.com -# Password: changeme -``` - -Método 2: SQL directo (solo SQLite): - -```bash -docker exec -it nginx-proxy-manager /bin/bash - -# Dentro del contenedor -sqlite3 /data/database.sqlite - --- Resetear password a 'changeme' -UPDATE auth SET secret = '$2a$10$YSwA4rB7M/xE8N1n8YCfCuYZ.9cNrwMr/L/PkZ.qXHfEqNkFN7XCy' WHERE id = 1; - -.exit -exit - -# Reiniciar -docker restart nginx-proxy-manager -``` - -## Verificación de Integridad - -### Test de Restauración - -```bash -# 1. Crear volúmenes de test -docker volume create npm_data_test -docker volume create npm_letsencrypt_test - -# 2. Restaurar en volúmenes test -docker run --rm \ - -v npm_data_test:/data \ - -v npm_letsencrypt_test:/letsencrypt \ - -v $(pwd):/backup \ - alpine \ - sh -c "tar xzf /backup/npm_data-BACKUP.tar.gz -C /data && tar xzf /backup/npm_letsencrypt-BACKUP.tar.gz -C /letsencrypt" - -# 3. Iniciar NPM temporal -docker run -d \ - -p 18081:81 \ - --name npm-test \ - -v npm_data_test:/data \ - -v npm_letsencrypt_test:/etc/letsencrypt \ - jc21/nginx-proxy-manager:latest - -# 4. Verificar en http://localhost:18081 - -# 5. Limpiar -docker stop npm-test -docker rm npm-test -docker volume rm npm_data_test npm_letsencrypt_test -``` - -### Validar Tar - -```bash -# Verificar integridad -tar tzf npm_data-YYYYMMDD-HHMMSS.tar.gz > /dev/null -echo $? # Debe devolver 0 - -# Ver contenido -tar tzf npm_data-YYYYMMDD-HHMMSS.tar.gz | head -20 -``` - -## Best Practices - -### Estrategia 3-2-1 - -- ✅ **3 copias** de datos (original + 2 backups) -- ✅ **2 tipos de medios** (local + remoto) -- ✅ **1 copia offsite** (cloud, otro datacenter) - -### Frecuencia Recomendada - -| Uso | Frecuencia | -|-----|------------| -| Producción crítica | Cada 6 horas | -| Producción | Diario | -| Personal/Home | Semanal | - -### Retención - -Ejemplo: -- Diarios: 7 días -- Semanales: 4 semanas -- Mensuales: 12 meses - -### Encriptación - -Para backups sensibles: - -```bash -# Backup encriptado con GPG -BACKUP_FILE="npm-backup-$(date +%Y%m%d-%H%M%S).tar.gz" - -# Crear backup -docker run --rm ... tar czf /backup/$BACKUP_FILE ... - -# Encriptar -gpg --symmetric --cipher-algo AES256 "$BACKUP_FILE" - -# Resultado: npm-backup-YYYYMMDD-HHMMSS.tar.gz.gpg -rm "$BACKUP_FILE" -``` - -Desencriptar: - -```bash -gpg --decrypt npm-backup-YYYYMMDD-HHMMSS.tar.gz.gpg > npm-backup.tar.gz -``` - ---- - -**Volver a**: [Página Principal](Home) | [Configuración Avanzada](Configuracion) diff --git a/Configuracion.md b/Configuracion.md index ec34d28..4a2fa6f 100644 --- a/Configuracion.md +++ b/Configuracion.md @@ -95,7 +95,7 @@ services: Crear red compartida: ```bash -docker network create proxy_network +docker network create proxy ``` NPM: @@ -103,13 +103,13 @@ NPM: services: app: networks: - - proxy_network - - npm_network + - proxy + - npm_internal networks: - npm_network: - name: npm_network - proxy_network: + npm_internal: + name: npm_internal + proxy: external: true ``` @@ -118,10 +118,10 @@ Otros servicios: services: mi_app: networks: - - proxy_network + - proxy networks: - proxy_network: + proxy: external: true ``` diff --git a/Home.md b/Home.md index 60b155c..376e746 100644 --- a/Home.md +++ b/Home.md @@ -56,7 +56,7 @@ Este repositorio despliega NPM con la siguiente configuración: - `npm_letsencrypt` → `/etc/letsencrypt` - Certificados SSL de Let's Encrypt ### Red -- `npm_network` - Red dedicada para el stack +- `proxy` - Red externa compartida con otros servicios ## Requisitos Previos @@ -152,10 +152,10 @@ Si tienes servicios corriendo en Docker en el mismo host: ```yaml # En el docker-compose.yaml de tu servicio networks: - - npm_network + - proxy networks: - npm_network: + proxy: external: true ``` @@ -217,8 +217,6 @@ Aplicar a Proxy Host: - 📖 [Configuración Avanzada](Configuracion) - MySQL, secrets, custom NGINX configs - 🔒 [Certificados SSL/TLS](SSL) - Wildcard, DNS challenge, certificados propios -- 💾 [Backup y Restauración](Backup) - Cómo respaldar y restaurar NPM -- ⚙️ [Configuración Avanzada de NGINX](Avanzado) - Custom configs, geoIP, rate limiting ## Troubleshooting Rápido @@ -226,7 +224,7 @@ Aplicar a Proxy Host: |----------|----------| | Puerto 80/443 ocupado | Ver proceso: `sudo netstat -tulpn \| grep :80`, cambiar puertos en compose | | No se genera certificado SSL | Verificar DNS apunta al servidor, puertos 80/443 abiertos en firewall | -| Olvido de contraseña | Ver [Backup](Backup#reset-password) para resetear | +| Olvido de contraseña | Resetear credenciales a valores por defecto (ver documentación oficial) | | Error "Address family not supported" | Añadir `DISABLE_IPV6: 'true'` en environment | | 502 Bad Gateway | Verificar que el backend esté corriendo y el puerto correcto |