CreaRack-SL

Server Management — Hetzner + Ubuntu

Server Management — Hetzner + Ubuntu

Última actualización: 01-05-2026 (sesión 46 · apt upgrade desde PowerShell + microcódigo CPU)

Servidores

EntornoHostnameIPTipoSpecs
Produccióncrearack.com116.203.31.166CCX (dedicado)4 vCPU AMD, 16GB RAM, 160GB NVMe
Staging—178.104.131.173CX23 (compartido)1 vCPU, 4GB RAM, 40GB NVMe

OS: Ubuntu 24.04 LTS


Conexion SSH

# Producción
ssh root@crearack.com
# o por IP directa
ssh root@116.203.31.166

# Staging
ssh root@178.104.131.173
  • Usa SSH key (~/.ssh/id_ed25519), sin contraseña
  • Ver HETZNER_SSH_SETUP.md para configurar un nuevo ordenador

Firewall

Hetzner Cloud Firewall (capa externa)

PuertoProtocoloDescripción
22TCPSSH
80TCPHTTP (redirige a HTTPS via Traefik)
443TCPHTTPS

iptables DOCKER-USER (reglas locales en el servidor)

Las reglas locales complementan el firewall de Hetzner y controlan el acceso a servicios internos de Docker:

  • Dokploy (puerto 3000): accesible solo desde IPs de GitHub webhook y la IP del administrador
  • GitHub webhook IPs: 4 subredes de GitHub añadidas explícitamente para el webhook de auto-deploy

Persistencia en reboot

El script /root/restore-firewall.sh restaura las reglas de iptables automáticamente al arrancar el servidor, gestionado por un servicio systemd.

# Verificar que el servicio está activo
systemctl status restore-firewall

# Restaurar manualmente si hace falta
/root/restore-firewall.sh

Monitorización

UptimeRobot (externo)

  • Monitor: GET https://crearack.com/health cada 5 minutos
  • Alertas: email automático si el sitio cae o tarda más de 30s
  • Dashboard: uptimerobot.com (cuenta edudomo@gmail.com)

Health endpoint

# Verificar manualmente (verifica DB + Cache)
curl https://crearack.com/health
# Respuesta esperada: {"status": "ok"}

Backups Automatizados

Crons en producción

CronScriptQué hace
0 3 * * */opt/backups/pg_backup.shpg_dump → local (retención 14d) + Hetzner Object Storage (retención 30d)
*/15 * * * */opt/backups/wal_sync.shWAL archives → Hetzner Object Storage
0 4 * * 0/opt/backups/pg_basebackup.shBase backup físico (domingos 4:00 AM) → Object Storage

Object Storage

  • Bucket: crearack-backups-lock (región nbg1), desde el 24-09-2026. Creado con bloqueo de borrado (Object Lock) en modo COMPLIANCE, retención por defecto 30 días: ninguna llave puede borrar de verdad una copia durante 30 días, ni acortar el plazo. Versionado activo; regla de ciclo de vida purgar-versiones-viejas (NoncurrentVersionExpiration 7 días). Los rclone delete --min-age 30d de los scripts solo ponen marcas de borrado; la purga real la hace el depósito → retención efectiva ~37 días. Simulacro del camino de fallo hecho el 24-09: borrado definitivo con la llave de PROD → AccessDenied: forbidden by object lock, también con --bypass-governance-retention.
  • Prefijos: postgres/ (pg_dump diario) · wal/ (cada 15 min) · basebackup/ (domingos).
  • Herramienta: /opt/backups/s3api.sh (AWS CLI en contenedor efímero con la llave de rclone, sin sacarla del servidor) para versiones, retención y recuperación de versiones borradas.
  • Depósito anterior crearack-backups (sin bloqueo): conserva la historia hasta el 24-09 y se vacía hacia el 24-10-2026 (tarea-aviso). Scripts previos al cambio en /opt/backups/pre-bloqueo-2026-09-24/.
  • Retención local: 14 días (pg_dump).
  • Segundo depósito con bloqueo crearack-dr-lock (mismo bloqueo y regla de purga, 24-09-2026): recibe desde STAGE la copia diaria del workspace (workspace/), el volcado semanal de Forgejo (forgejo/) y la historia abril-junio que solo estaba en Google Drive (workspace-historico-drive/). Script /opt/dr-backups/cron-dr-lock-sync.sh en STAGE.

Acceso de la ronda semanal a PROD (solo lectura, 24-09-2026)

La llave ia-edu-ronda@pc-ia-claude (ronda desatendida de la estación, domingos) está atada en /root/.ssh/authorized_keys a /usr/local/bin/ronda-sonda.sh. Solo admite docker exec -i crearack-pro-zcmvsl-web-1 python manage.py shell y ... manage.py mapa_superficie; el guardián las lanza con --env-file /etc/ronda-sonda.envfile (root 600): rol de BD ronda_readonly (default_transaction_read_only=on, app.current_org_id=0, SELECT sobre todas las tablas y privilegios por defecto para las futuras de crearack_app) y credenciales de caché, correo, IA y servicios internos vaciadas. Probado: lectura OK, UPDATE → read-only transaction, caché → AuthenticationError, cualquier otra orden → rechazo con salida 126. Registro: journalctl -t ronda-sonda. Para ampliar lo que puede hacer la ronda, se edita el case del guardián (con GO), nunca se quita la restricción de la llave. El mismo 24-09 se dio a dani_readonly lectura sobre las 8 tablas que no veía y sobre las futuras.

Snapshots Hetzner

  • Automáticos semanales: activados en Hetzner Console (servidor de producción)
  • Manuales: antes de actualizaciones críticas (Dokploy, kernel, migraciones DB)
  • Coste: ~€1.76/mes para disco de 160GB

Verificar backups

# Listar backups locales
ls -lh /opt/backups/dumps/

# Ver últimos logs de backup
tail -50 /var/log/pg_backup.log

# Verificar WAL archives
ls -lh /var/lib/postgresql/wal_archive/ | tail -20

Seguridad SSH

MedidaEstadoConfig
Root SSHDesactivadoPermitRootLogin no
Password authDesactivadoPasswordAuthentication no
fail2banActivo3 intentos → ban 10 min
Usuario adminedu con sudoRequiere password para sudo

Verificar estado

# Intentos bloqueados
sudo fail2ban-client status sshd

# Config SSH activa
sudo sshd -T | grep -E "permitrootlogin|passwordauthentication"

# Ultimos intentos de login
sudo journalctl -u ssh --since "1 hour ago" | tail -20

Actualizaciones del Sistema

Rutina semanal (~2 minutos)

Sesión interactiva (mejor si quieres ver cada paquete):

sudo apt update && sudo apt upgrade -y

One-liner desde PowerShell (sin entrar en sesión):

ssh root@crearack.com "apt update && DEBIAN_FRONTEND=noninteractive apt upgrade -y"

DEBIAN_FRONTEND=noninteractive evita prompts sobre archivos de configuración (típicos en updates de grub, openssh-server). Mantiene la versión local por defecto. Si sospechas que ha tocado un config crítico, repasar /etc/<paquete>/*.dpkg-dist después.

Si ves “System restart required” despues de actualizar:

sudo reboot
# o desde PowerShell:
ssh root@crearack.com "reboot"

El servidor se reinicia en ~30 segundos. Dokploy y todos los contenedores arrancan automaticamente.

Que se actualiza

TipoEjemploRiesgoReboot necesario
Kernel LinuxParches de seguridadBajoSí, para que entre el kernel nuevo
amd64-microcodeActualización microcódigo CPUBajoSí, para que el CPU lo cargue
Librerias del sistemagcc, openssl, glibcBajoSolo si afecta a procesos persistentes
Herramientascurl, git, opensshBajoNo
Paquetes grub-*BootloaderBajoNo (se aplica al siguiente arranque solo)

Heurística rápida: si ls /var/run/reboot-required existe → reboot recomendado. Si no, esperar a la próxima ventana.

Estas actualizaciones son del servidor Ubuntu (el host). La app Django vive dentro de Docker y se actualiza con git push.

Automatizar (opcional)

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
# Seleccionar "Yes"

Solo instala parches de seguridad automaticamente. Seguro dejarlo activado.

Verificar estado de updates desde PowerShell

# Cuántos paquetes upgradables hay
ssh root@crearack.com "apt list --upgradable 2>/dev/null | tail -n +2 | wc -l"

# Lista completa
ssh root@crearack.com "apt list --upgradable 2>/dev/null"

# Reboot pendiente?
ssh root@crearack.com "ls /var/run/reboot-required 2>/dev/null && cat /var/run/reboot-required.pkgs 2>/dev/null || echo 'No reboot required'"

Calendario de Mantenimiento

TareaFrecuenciaComando / Acción
Actualizaciones UbuntuSemanalsudo apt update && sudo apt upgrade -y
Revisar fail2banMensualsudo fail2ban-client status sshd
Limpieza DockerCada 1-2 mesesdocker image prune -a --filter "until=168h"
Verificar discoMensualdf -h
Reboot si lo pideCuando aparezcasudo reboot
Snapshot HetznerAntes de updates críticosVer sección Snapshots
Limpieza snapshotsMensualHetzner Console → eliminar >1 mes
Verificar backups pg_dumpSemanalls -lh /opt/backups/dumps/ + revisar log
Verificar WAL syncSemanalComprobar timestamps en Object Storage
Verificar UptimeRobotMensualDashboard uptimerobot.com — uptime 30d

Monitorear Espacio en Disco

El servidor tiene 160GB NVMe.

UsoEstadoAccion
< 60%NormalNada
60-80%AtencionLimpiar imagenes Docker
> 80%UrgenteLimpieza completa + revisar logs
# Ver espacio
df -h

# Que ocupa mas en Docker
docker system df

Snapshots (Hetzner)

Los snapshots son copias instantáneas del disco del servidor. Imprescindibles antes de actualizaciones arriesgadas (Dokploy, kernel, etc.).

Coste: €0.011/GB/mes (~€1.76/mes para 160GB)

Crear un snapshot seguro

  1. Conectar al servidor:

    ssh root@crearack.com
  2. Parar DB y cache (garantiza consistencia de datos):

    docker stop crearack-pro-zcmvsl-db-1 crearack-pro-zcmvsl-cache-1
  3. Verificar que están parados:

    docker ps --format '{{.Names}} {{.Status}}' | grep -E 'db-1|cache-1'

    Si no aparecen → están parados. La web seguirá respondiendo pero dará errores de DB (normal, dura ~1 min).

  4. Tomar snapshot en Hetzner Console:

    • console.hetzner.cloud → tu servidor → pestaña Snapshots → Create Snapshot
    • Nombrar descriptivamente: pre-dokploy-update-2026-03-13
  5. Reiniciar los contenedores:

    docker start crearack-pro-zcmvsl-db-1 crearack-pro-zcmvsl-cache-1
  6. Verificar que todo funciona:

    docker ps --format '{{.Names}} {{.Status}}'

Nota: NO es necesario apagar el servidor entero. Solo parar DB y cache es suficiente para garantizar consistencia de PostgreSQL y Valkey.

Restaurar un snapshot

  1. Hetzner Console → Snapshots → seleccionar → Rebuild from Snapshot
  2. El servidor se recrea con el estado exacto del momento del snapshot
  3. Todos los contenedores, datos y configuración se restauran automáticamente

Cuándo tomar snapshots

SituaciónSnapshot?
Antes de actualizar DokploySí
Antes de actualizar kernel/UbuntuSí
Antes de migración DB grandeSí
Deploy normal de la app (git push)No (revertible con git)
Cambios de configuración DockerRecomendable

Limpieza

Los snapshots consumen espacio facturado. Eliminar snapshots antiguos (>1 mes) que ya no sean necesarios desde Hetzner Console.


Recuperacion de Acceso

Si pierdes acceso SSH

  1. Entra a Hetzner Console → tu servidor → pestaña Rescue
  2. Activa modo rescate → te da una password temporal de root
  3. Reinicia el servidor → arranca en Linux de rescate
  4. Monta el disco:
    mount /dev/sda1 /mnt
  5. Edita lo que necesites:
    nano /mnt/etc/ssh/sshd_config    # Reactivar PermitRootLogin temporalmente
    cp tu_key.pub /mnt/home/edu/.ssh/authorized_keys  # Nueva SSH key
  6. Desmonta y reinicia:
    umount /mnt && reboot

Que se puede recuperar sin backup

DatoRecuperable?Como
Acceso SSHSiHetzner Rescue
Password de eduSiReset desde Rescue
Codigo de la appSigit clone desde GitHub
Base de datosNOSolo con backup previo
Media uploadsNOSolo con backup previo
Variables de entornoNOSolo en Dokploy
Certificado SSLSiLet’s Encrypt regenera automaticamente

Credenciales criticas — guardar en gestor de passwords

CredencialSi la pierdes…
Password de eduRecuperable via Hetzner Rescue
SSH key privadaRecuperable via Hetzner Rescue
Credenciales DokployReinstalar desde SSH
Cuenta HetznerRecuperacion via email
Cuenta CloudflareRecuperacion via email
DJANGO_SECRET_KEYGenerar nueva (invalida sesiones activas)
POSTGRES_PASSWORDResetear desde container
GEMINI_API_KEYRegenerar en Google AI Studio

Regla de oro: La cuenta de Hetzner es la mas importante. Con ella recuperas todo lo demas.


Última actualización: 01-05-2026 Maintained by: CreaRack Team

Véase también

  • [[crearack-tech—admin—hetzner-ssh-setup]] — setup de SSH contra Hetzner
  • [[crearack-tech—admin—dokploy-guide]] — guía operativa de Dokploy
  • [[crearack-tech—admin—monitoring-tools]] — herramientas admin de monitorización
  • [[crearack-tech—admin—cache-and-database]] — operativa de cache Valkey y DB Postgres
  • [[crearack-tech—guides—disaster-recovery]] — disaster recovery del sistema