Backup, restauração e atualização

Este tutorial faz backup da configuração do posto, credenciais de acesso, concessões de dispositivos, pontos de verificação de monitoramento e notificações em fila. As mensagens de e-mail originais permanecem com seu provedor de e-mail; este backup restaura a instância do Mailwake.

1. O que preservar

Um backup recuperável contém:

  • O diretório /data completo: mailwake.db , secret.key e arquivos SQLite relacionados. Mantenha o banco de dados e a chave juntos.
  • Configuração do Compose: portas, volumes e configurações de ambiente.
  • A imagem em execução: restaure a mesma versão do programa que o banco de dados.

O script abaixo tem como alvo a instalação padrão do Compose. Ele salva a configuração e a imagem, interrompe brevemente o posto, copia todos os dados e reinicia o posto. O monitoramento faz uma pausa durante esse intervalo. Após a reinicialização, o posto retoma dos pontos de verificação salvos e recupera as mensagens ainda na pasta que foram recebidas nas últimas 24 horas.

Se sua instalação usar configuração de proxy reverso ou outros arquivos montados no host, copie esses arquivos também no backup. Ajuste seus caminhos ao restaurar em outra máquina.

2. Crie seu primeiro backup

Baixe o script de backup , salve-o como backup.sh e coloque-o no diretório de instalação do servidor, por exemplo ~/mailwake/backup.sh .

Visualize o script de backup

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"

Execute no terminal do seu servidor:

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

Verifique o resultado: o terminal imprime Backup saved: com o novo caminho do diretório e docker compose ps mostra o posto em execução novamente. Se a cópia falhar, o script tentará reiniciar o posto e retornará uma falha. Os diretórios que terminam em .incomplete são backups inacabados; guarde-os para solução de problemas.

O diretório de bloqueio evita a sobreposição de backups agendados e manuais. Se o host travar ou o processo for encerrado à força, primeiro confirme se nenhum backup está em execução e, em seguida, remova .mailwake-backup.lock do diretório de instalação e execute novamente o script.

Cada backup possui este layout:

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

Salvar a imagem requer espaço em disco adicional e acontece antes da parada do posto. O diretório usa permissões privadas e contém as credenciais criptografadas e sua chave. Confirme que data/mailwake.db , data/secret.key e image.tar existem e execute o exercício de restauração abaixo pelo menos uma vez.

3. Restaurar em um novo volume

Pare a instância original e mantenha seu volume original. Ambas as instâncias compartilham identidades de caixa de correio e de dispositivo, portanto, execute apenas uma de cada vez.

cd ~/mailwake
docker compose stop core

Configure backup para seu caminho de backup real. Prepare um novo diretório de instalação, sua imagem e configuração:

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

O Compose carrega automaticamente compose.override.yaml . Ele seleciona um novo volume de dados e a imagem exata de backup. Crie o contêiner, copie os dados, defina a propriedade do usuário do contêiner e inicie:

(
  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
)

Continue somente após cada comando ser bem-sucedido. Se a verificação do volume vazio falhar, escolha um restore_volume novo, reescreva a substituição e recrie o contêiner. Um destino preenchido pode misturar arquivos antigos com dados restaurados; este procedimento usa um volume vazio.

Verifique o resultado: faça login com sua senha de administrador original. As caixas de correio e as seleções de pasta permanecem presentes, o monitoramento é retomado e as concessões de dispositivos vêm do backup. Se você vir uma nova tela de configuração, interrompa a instância restaurada e verifique o caminho da cópia e a montagem do volume. Para erros de descriptografia, confirme se o banco de dados e secret.key vieram do mesmo backup.

4. Verifique a instância restaurada

  1. Verifique contagens de caixas de correio, pastas selecionadas e métodos de verificação em relação à instalação original.
  2. Envie uma notificação de teste de canal e confirme se ela chega ao seu telefone.
  3. Envie um novo e-mail de outra caixa de correio para uma pasta monitorada e verifique seu registro de entrega.
  4. Reinicie a instância restaurada, conecte-se novamente e confirme se sua configuração e monitoramento persistem.

Depois de verificado, aponte o proxy reverso para a instância restaurada e gerencie-o a partir de ~/mailwake-restored . Atualize a tarefa de backup para usar esse diretório. Deixe a instância original parada e retenha seu volume e o backup até que a recuperação seja confirmada.

Notificações pendentes ou com falha retornam ao estado de backup e podem ser entregues novamente. Use o mesmo procedimento para reverter uma atualização, restaurando os dados e a imagem antigos juntos.

5. Agende backups e mantenha uma cópia externa

Em um servidor Linux, primeiro conclua um backup manual e, em seguida, use crontab -e para adicionar o seguinte. Substitua /home/you pelos seus caminhos absolutos:

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

É executado diariamente às 03:00 no fuso horário local do servidor. O usuário agendado precisa de acesso ao Docker. Em um NAS, use o mesmo comando Shell em seu agendador de tarefas. No dia seguinte, verifique se há um novo diretório e Backup saved: no log. Abordar falhas; um agendador não pode estabelecer que um backup é recuperável.

Um backup no mesmo disco não cobre falha do disco ou da máquina. Copie os diretórios concluídos para outra máquina ou armazenamento de backup protegido, por exemplo, por SSH:

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

Substitua a origem, o usuário remoto, o host e o destino. Restrinja o acesso no destino aos mantenedores de backup. Use armazenamento criptografado ou criptografe o arquivo antes de fazer upload quando a criptografia em repouso for necessária. Uma possível política de retenção é de sete exemplares diários e quatro semanais. Antes de excluir backups mais antigos, verifique a cópia externa e um exercício de restauração recente.

Fazer backup de uma instalação do Docker Run

A instalação do Docker Run usa um contêiner chamado mailwake e o volume mailwake-data . Esses comandos são executados em um subshell e tentam reiniciar o contêiner original se a cópia falhar:

(
  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"
)

Salve seu comando Docker Run junto com os dados. Para restaurar, pare o contêiner original, carregue image.tar , crie um novo volume e contêiner e copie os dados antes de iniciar:

(
  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
)

Continue somente após cada comando ser bem-sucedido e siga a lista de verificação de verificação acima. Mantenha o contêiner e o volume originais, deixando o contêiner original parado enquanto a instância restaurada é executada.

Markdown · AGPL-3.0-only · Colaboradores do Mailwake