Copias de seguridad, restauración y actualización

Este tutorial realiza una copia de seguridad de la configuración del puesto, las credenciales de acceso, las concesiones de dispositivos, los puntos de control de monitoreo y las notificaciones en cola. Los mensajes de correo electrónico originales permanecen con su proveedor de correo electrónico; esta copia de seguridad restaura la instancia Mailwake.

1. Qué conservar

Una copia de seguridad recuperable contiene:

  • El directorio /data completo: mailwake.db, secret.key y archivos SQLite relacionados. Mantenga la base de datos y la clave juntas.
  • Redactar configuración: puertos, volúmenes y configuración del entorno.
  • La imagen en ejecución: restaure la misma versión del programa que la base de datos.

El siguiente script se dirige a la instalación estándar de Compose. Guarda la configuración y la imagen, detiene brevemente el puesto, copia todos los datos y luego reinicia el puesto. El monitoreo se detiene durante ese intervalo. Después del reinicio, el puesto se reanuda desde los puntos de control guardados y recupera los mensajes que aún están en la carpeta y que se recibieron en las últimas 24 horas.

Si su instalación utiliza una configuración de proxy inverso u otros archivos montados en el host, copie esos archivos también en la copia de seguridad. Ajuste sus rutas al restaurar en otra máquina.

2. Crea tu primera copia de seguridad

Descargue script de respaldo, guárdelo como backup.sh y colóquelo en el directorio de instalación de su servidor, por ejemplo ~/mailwake/backup.sh.

Ver el script de respaldo

sh
#!/bin/sh
# Copyright (C) 2026 Mailwake contributors
# SPDX-License-Identifier: AGPL-3.0-only
# License: https://www.gnu.org/licenses/agpl-3.0.html
# Back up a running Compose installation; execute as a user with Docker access.
set -eu

if [ "$#" -ne 2 ]; then
  echo "Usage: backup.sh /absolute/compose-directory /absolute/backup-directory" >&2
  exit 2
fi
case "$1:$2" in
  /*:/*) ;;
  *) echo "Use absolute directory paths." >&2; exit 2 ;;
esac
cd "$1"
umask 077
lock=".mailwake-backup.lock"
if ! mkdir "$lock" 2>/dev/null; then
  echo "Could not create $PWD/$lock. Check directory permissions and active backups." >&2
  exit 1
fi
restart=0
cleanup() {
  result=$?
  trap - EXIT
  if [ "$restart" -eq 1 ]; then
    docker compose start core >&2 || result=1
  fi
  rmdir "$lock" || result=1
  exit "$result"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
container=$(docker compose ps -q core)
if [ -z "$container" ]; then
  echo "Start the Core service before running this backup." >&2
  exit 1
fi
mkdir -p "$2"
backup="$2/mailwake-$(date +%Y%m%d-%H%M%S)"
test ! -e "$backup"
staging="$backup.incomplete"
mkdir "$staging"
mkdir "$staging/data"
docker compose config > "$staging/compose.yaml"
docker inspect --format '{{.Image}}' "$container" > "$staging/image-id.txt"
docker image save --output "$staging/image.tar" "$(cat "$staging/image-id.txt")"
restart=1
docker compose stop core >&2
docker compose cp core:/data/. "$staging/data/" >&2
docker compose start core >&2
restart=0
mv "$staging" "$backup"
printf 'Backup saved: %s\n' "$backup"

Ejecute en la terminal de su servidor:

sh "$HOME/mailwake/backup.sh" "$HOME/mailwake" "$HOME/mailwake-backups"

Verifique el resultado: la terminal imprime Backup saved: con la nueva ruta del directorio y docker compose ps muestra el puesto ejecutándose nuevamente. Si la copia falla, el script intenta reiniciar el puesto y devuelve un error. Los directorios que terminan en .incomplete son copias de seguridad sin terminar; guárdelos para solucionar problemas.

El directorio de bloqueo evita la superposición de copias de seguridad manuales y programadas. Si el host falla o el proceso se cierra a la fuerza, primero confirme que no se esté ejecutando ninguna copia de seguridad, luego elimine .mailwake-backup.lock del directorio de instalación y vuelva a ejecutar el script.

Cada copia de seguridad tiene este diseño:

mailwake-20261008-030000/
  compose.yaml
  image-id.txt
  image.tar
  data/
    mailwake.db
    secret.key
    ...

Guardar la imagen requiere espacio adicional en el disco y ocurre antes de que se detenga el puesto. El directorio utiliza permisos privados y contiene tanto las credenciales cifradas como su clave. Confirme que existen data/mailwake.db, data/secret.key y image.tar, luego realice el ejercicio de restauración a continuación al menos una vez.

3. Restaurar en un nuevo volumen

Detenga la instancia original y mantenga su volumen original. Ambas instancias comparten identidades de buzón y dispositivo, por lo que se debe ejecutar solo una a la vez.

cd ~/mailwake
docker compose stop core

Configure backup en su ruta de respaldo real. Prepare un nuevo directorio de instalación, su imagen y configuración:

backup="$HOME/mailwake-backups/mailwake-20261008-030000"
mkdir -p ~/mailwake-restored
cd ~/mailwake-restored
cp "$backup/compose.yaml" ./compose.yaml
docker load --input "$backup/image.tar"
restore_volume="mailwake-restored-$(date +%Y%m%d-%H%M%S)"
cat > compose.override.yaml <<EOF
name: mailwake-restored
services:
  core:
    image: $(cat "$backup/image-id.txt")
volumes:
  core-data:
    name: $restore_volume
networks:
  default:
    name: $restore_volume-network
EOF

Redactar carga automáticamente compose.override.yaml. Selecciona un volumen de datos nuevo y la imagen respaldada exacta. Cree el contenedor, copie los datos, establezca la propiedad para el usuario del contenedor y comience:

(
  set -eu
  docker compose create --pull never core
  docker compose run --rm --no-deps -T --user 0:0 --entrypoint sh core \
    -c 'entries=$(ls -A /data) && test -z "$entries"'
  docker compose cp "$backup/data/." core:/data/
  docker compose run --rm --no-deps -T --user 0:0 --cap-add CHOWN --entrypoint chown core \
    -R 10001:10001 /data
  docker compose up -d --pull never
  docker compose logs --tail=50 core
)

Continúe solo después de que cada comando tenga éxito. Si la verificación del volumen vacío falla, elija un restore_volume nuevo, reescriba la anulación y vuelva a crear el contenedor. Un destino poblado podría mezclar archivos antiguos con datos restaurados; este procedimiento utiliza un volumen vacío.

Comprueba el resultado: inicia sesión con tu contraseña de administrador original. Los buzones de correo y las selecciones de carpetas permanecen presentes, la supervisión se reanuda y las concesiones de dispositivos provienen de la copia de seguridad. Si ve una nueva pantalla de configuración, detenga la instancia restaurada y verifique la ruta de copia y el montaje del volumen. Para errores de descifrado, confirme que la base de datos y secret.key provienen de la misma copia de seguridad.

4. Verificar la instancia restaurada

  1. Verifique el recuento de buzones de correo, las carpetas seleccionadas y verifique los métodos con la instalación original.
  2. Envía una notificación de prueba de canal y confirma que llega a tu teléfono.
  3. Envíe un nuevo correo electrónico desde otro buzón a una carpeta supervisada y verifique su registro de entrega.
  4. Reinicie la instancia restaurada, inicie sesión nuevamente y confirme que su configuración y monitoreo persisten.

Una vez verificado, apunte el proxy inverso a la instancia restaurada y adminístrela desde ~/mailwake-restored. Actualice el trabajo de copia de seguridad para usar ese directorio. Deje la instancia original detenida y conserve su volumen y la copia de seguridad hasta que se confirme la recuperación.

Las notificaciones pendientes o fallidas vuelven a su estado de copia de seguridad y pueden entregarse nuevamente. Utilice el mismo procedimiento para revertir una actualización, restaurando los datos y la imagen antiguos juntos.

5. Programe copias de seguridad y guarde una copia externa

En un servidor Linux, primero complete una copia de seguridad manual y luego use crontab -e para agregar lo siguiente. Reemplace /home/you con sus rutas absolutas:

PATH=/usr/local/bin:/usr/bin:/bin
0 3 * * * /bin/sh /home/you/mailwake/backup.sh /home/you/mailwake /home/you/mailwake-backups >> /home/you/mailwake-backup.log 2>&1

Esto se ejecuta diariamente a las 03:00 en la zona horaria local del servidor. El usuario programado necesita acceso a Docker. En un NAS, utilice el mismo comando de Shell en su programador de tareas. Al día siguiente, busque un nuevo directorio y Backup saved: en el registro. Abordar las fallas; un programador no puede establecer que una copia de seguridad sea recuperable.

Una copia de seguridad en el mismo disco no cubre fallas del disco o de la máquina. Copie los directorios completos a otra máquina o a un almacenamiento de copia de seguridad protegido, por ejemplo a través de SSH:

scp -r "$HOME/mailwake-backups/mailwake-20261008-030000" \
  backup-user@backup-host:/srv/mailwake-backups/

Reemplace el origen, el usuario remoto, el host y el destino. Restrinja el acceso en el destino a los mantenedores de respaldo. Utilice almacenamiento cifrado o cifre el archivo antes de cargarlo cuando sea necesario el cifrado en reposo. Una posible política de retención es siete copias diarias y cuatro semanales. Antes de eliminar copias de seguridad anteriores, verifique la copia externa y un ejercicio de restauración reciente.

Hacer una copia de seguridad de una instalación de Docker Run

La instalación de Docker Run utiliza un contenedor denominado mailwake y el volumen mailwake-data. Estos comandos se ejecutan en un subshell e intentan reiniciar el contenedor original si falla la copia:

(
  set -eu
  umask 077
  backup="$HOME/mailwake-backups/mailwake-$(date +%Y%m%d-%H%M%S)"
  mkdir -p "$backup/data"
  docker inspect --format '{{.Image}}' mailwake > "$backup/image-id.txt"
  docker image save --output "$backup/image.tar" "$(cat "$backup/image-id.txt")"
  trap 'docker start mailwake >/dev/null' EXIT
  docker stop mailwake
  docker cp mailwake:/data/. "$backup/data/"
  docker start mailwake
  trap - EXIT
  printf 'Backup saved: %s\n' "$backup"
)

Guarde su comando Docker Run junto con los datos. Para restaurar, detenga el contenedor original, cargue image.tar, cree un nuevo volumen y contenedor y copie los datos antes de comenzar:

(
  set -eu
  backup="$HOME/mailwake-backups/mailwake-20261008-030000"
  image=$(cat "$backup/image-id.txt")
  restore_volume="mailwake-restored-$(date +%Y%m%d-%H%M%S)"
  docker stop mailwake
  docker load --input "$backup/image.tar"
  docker volume create "$restore_volume"
  docker create --name mailwake-restored --restart unless-stopped \
    --stop-timeout 30 --read-only --security-opt no-new-privileges:true --cap-drop ALL \
    -p 127.0.0.1:8080:8080 -v "$restore_volume:/data" "$image"
  docker run --rm --user 0:0 --entrypoint sh -v "$restore_volume:/data" "$image" \
    -c 'entries=$(ls -A /data) && test -z "$entries"'
  docker cp "$backup/data/." mailwake-restored:/data/
  docker run --rm --user 0:0 --entrypoint chown -v "$restore_volume:/data" "$image" \
    -R 10001:10001 /data
  docker start mailwake-restored
)

Continúe solo después de que cada comando tenga éxito y siga la lista de verificación anterior. Mantenga el contenedor y el volumen originales y deje el contenedor original detenido mientras se ejecuta la instancia restaurada.

Markdown · AGPL-3.0-only · Colaboradores de Mailwake