El escenario#
Se me quemó la placa madre del servidor doméstico. Tenía todo en Docker: aplicaciones, PostgreSQL, datos críticos. El backup estaba en Restic, pero nunca había probado la recuperación completa en un servidor nuevo. Aquí documento cómo lo hice sin perder servicios ni datos.
Preparación inicial en el servidor nuevo#
Primero, instalé Docker y las herramientas necesarias:
sudo apt-get update
sudo apt-get install -y docker.io docker-compose git curl restic
sudo usermod -aG docker $USERCreé la estructura de directorios donde vivirán los datos:
mkdir -p /srv/docker-data/{postgres,volumes,configs}
mkdir -p /var/backups/restic-cacheRestaurar la configuración de Restic#
Lo crítico aquí es configurar Restic con los mismos parámetros que usé para hacer backup. Necesitaba:
- La contraseña del repositorio
- Las credenciales del almacenamiento (S3, B2, o dónde esté alojado)
- La ruta del repositorio
En mi caso usaba B2:
export RESTIC_REPOSITORY="b2:mi-bucket:/ruta/del/repo"
export RESTIC_PASSWORD="mi-contraseña-segura"
export B2_ACCOUNT_ID="id"
export B2_ACCOUNT_KEY="key"
# Verificar que Restic puede acceder al repositorio
restic snapshotsSi ves el listado de snapshots, estás conectado correctamente.
Estrategia de restore sin downtime#
La clave es no restaurar todo de una vez. Mi plan fue:
- Restaurar datos de PostgreSQL en un volumen temporal
- Restaurar configs y docker-compose
- Levantar servicios no-críticos primero
- Restaurar PostgreSQL y validar
- Levantar aplicaciones críticas
Restauración del snapshot#
Primero, listaba los snapshots disponibles:
restic snapshots --json | jq '.[] | {time, id, hostname}'Elegía el más reciente y lo restauraba a un directorio temporal:
restic restore [SNAPSHOT_ID] --target /tmp/restic-restoreEste proceso tardó unos minutos dependiendo del tamaño. En mi caso, unos 150GB.
Recuperando PostgreSQL#
Una vez restaurado, localizaba el directorio de datos de PostgreSQL:
ls -la /tmp/restic-restore/srv/docker-data/postgres/data/Aquí está el problema: no puedo simplemente copiar datos vivos de PostgreSQL. Necesitaba hacer esto correctamente:
# 1. Copiar el directorio de datos restaurado
sudo cp -r /tmp/restic-restore/srv/docker-data/postgres /srv/docker-data/postgres-restored
# 2. Ajustar permisos (PostgreSQL en Docker usa UID 999)
sudo chown -R 999:999 /srv/docker-data/postgres-restored
# 3. Crear volumen temporal para verificar integridad
docker volume create postgres-restore-check
docker run --rm -v postgres-restore-check:/var/lib/postgresql/data -v /srv/docker-data/postgres-restored:/backup postgres:15 \
/bin/bash -c "pg_controldata /backup/data" 2>&1 | head -20Si pg_controldata no lanza errores críticos, el backup es válido.
Levantar servicios de forma gradual#
En lugar de hacer docker-compose up, levantaba servicios individuales:
# Restaurar docker-compose.yml y configs
cp -r /tmp/restic-restore/srv/docker-data/configs /srv/docker-data/
# Levantar servicios sin dependencia de DB primero
docker-compose -f /srv/docker-data/docker-compose.yml up -d redis nginx
# Esperar 30 segundos
sleep 30
# Levantar PostgreSQL
docker-compose up -d postgres
# Verificar logs
docker logs -f [postgres-container-id]Validación y corte final#
Antes de considerar la recuperación completa:
# Verificar que PostgreSQL está sano
docker exec -it [postgres-container-id] pg_isready
# Testear una aplicación crítica
curl -s http://localhost:8080/health | jq .
# Revisar espacio en disco
df -h /srv/docker-dataUna vez validado, levantaba el resto de servicios:
docker-compose up -dLecciones aprendidas#
- Prueba tus backups regularmente. Descubrí un problema de permisos recién al restaurar.
- Documenta las variables de entorno. Me tomó 15 minutos encontrar las credenciales de B2.
- Restaura a directorios temporales primero. Así no sobrescribos nada en caso de error.
- Valida integridad de datos antes de declarar éxito. Los logs de PostgreSQL son tus amigos.
El downtime real fue 0, porque servicios no críticos estuvieron activos mientras restauraba la BD.