Backup e Restauro do servidor Gitea

Backup e restauração do Gitea da maneira correta

Conteúdo da página

Os backups do Gitea envolvem três partes móveis - o banco de dados, os repositórios git e os arquivos da aplicação - e, desde 2024, o comando integrado gitea dump trata todos eles de uma vez.

foto muito boa de um hdd aberto

No post Testando o Gitea, instalamos o servidor Gitea. Este é o artigo de continuação: como fazer o backup de fato e, mais importante, como restaurá-lo quando algo der errado.

Para a coleção completa de ferramentas de desenvolvedor, incluindo fluxos de trabalho do Git e gerenciamento do Docker, consulte Ferramentas de Desenvolvimento: O Guia Completo para Fluxos de Trabalho Modernos.

Se você está configurando o Gitea pela primeira vez, confira Escolhendo um servidor git gratuito local - Gitea é o vencedor! para detalhes da instalação e Gitea SSL com Apache como proxy reverso para implantação segura.

Quando ensaiar isso

Agora, apenas como precaução contra coisas terríveis, é um bom momento para ensaiar o procedimento de backup e restauração - antes de realmente precisar, não depois que um disco falhar.

Melhor prevenir do que remediar.

Onde os dados estão

Uma instância do Gitea é realmente composta por três componentes que precisam manter sincronia:

  • código (repositórios git)
  • armazenamento de arquivos (anexos, avatares, objetos LFS, indexadores)
  • banco de dados (usuários, problemas, PRs, configurações)

No nosso ambiente de teste, tudo junto ocupa um pouco mais de 700MB:

uso de disco do gitea

Como essas três peças se referenciam mutuamente, a documentação própria do Gitea é explícita sobre a consistência do backup: a instância deve ser parada durante a duração do backup, caso contrário, um repositório copiado no meio de uma migração pode ficar dessincronizado com o que o banco de dados acredita ter acontecido. A restauração, pela mesma razão, também precisa ser feita como uma única transação.

O jeito fácil - gitea dump

Esta é a parte que mudou desde a versão anterior deste artigo: em vez de lidar com pg_dump, tar e pastas separadas manualmente, o Gitea oferece um único comando dump que agrupa o banco de dados, repositórios, dados LFS, anexos e configuração em um único arquivo.

gitea dump -c /path/to/app.ini

Isso produz um arquivo com carimbo de data/hora, como gitea-dump-1610949662.zip, contendo:

  • app.ini - cópia do arquivo de configuração
  • custom/ - personalizações sob custom/
  • data/ - anexos, avatares, objetos LFS, indexadores (e o arquivo SQLite, se esse for seu banco de dados)
  • repos/ - cópia completa do diretório de repositórios
  • gitea-db.sql - despejo SQL do banco de dados
  • log/ - logs (não necessários para a restauração)

Parâmetros úteis que valem a pena conhecer:

  • --file name / -f name - nome do arquivo de saída (- para stdout, útil para encaminhar diretamente para scp ou armazenamento de objetos)
  • --type - formato de saída: zip (padrão), tar, tar.gz, tar.xz, tar.zst, etc.
  • --database / -d - força o dialeto SQL em gitea-db.sql (sqlite3, mysql, mssql, postgres) - útil ao migrar entre mecanismos de banco de dados
  • --skip-repository / -R, --skip-lfs-data, --skip-attachment-data, --skip-package-data, --skip-log, --skip-db - reduz o despejo apenas ao que você precisa
  • --tempdir / -t - onde os arquivos intermediários são armazenados (padrão /tmp ou $TMPDIR) - verifique se há espaço livre suficiente para toda a instância

Executando gitea dump no Docker

Como a maioria das configurações auto-hospedadas executa o Gitea via docker-compose, o comando precisa ser executado dentro do container, como o usuário git, a partir do diretório temporário do container:

cd ~/gitea-srv-local

# cria um dump dentro do container em execução
sudo docker exec -u git -it -w /tmp gitea bash -c \
  '/usr/local/bin/gitea dump -c /data/gitea/conf/app.ini'

# copia o zip resultante para fora do container
sudo docker cp gitea:/tmp/gitea-dump-*.zip ./gitea-backups/

-w /tmp é importante: o dump precisa gravar e criar o zip do seu diretório de trabalho temporário, e executá-lo em qualquer local sem permissões de escrita resultará em um erro de permissão.

Depois, como antes, retire o arquivo da máquina:

scp uname@gitea-srv-ip-addr:~/gitea-srv-local/gitea-backups/gitea-dump-*.zip ~/gitea-backups/

Se você preferir despejar o banco de dados com ferramentas nativas (a documentação própria do Gitea recomenda isso para MySQL/PostgreSQL, pois o despejo SQL baseado em XORM dentro do gitea dump tem casos conhecidos de borda na restauração), você ainda pode fazê-lo em paralelo:

sudo docker exec -t gitea-srv-local_db_1 bash -c \
  'pg_dump gitea -U gitea --file=/var/lib/postgresql/backups/gitea-db-$(date +%Y-%m-%d).sql'

Consulte a Folha de Dicas PostgreSQL para mais opções de pg_dump/pg_restore, e a Folha de Dicas Docker Compose se qualquer uma da sintaxe de docker exec/docker cp acima parecer familiar.

Como - Restaurar

Ainda não existe uma restauração em um único comando - a documentação do Gitea é franca de que isso permanece como um processo manual de mover arquivos de volta para o lugar certo e restaurar o despejo do banco de dados. Mas! Sempre verifique primeiro a documentação original, pois os caminhos e layouts dos containers mudam entre releases.

# instale/inicie um gitea novo (mesma versão que o backup) e depois derrube-o
sudo docker-compose down

# descompacte o dump
unzip gitea-dump-1610949662.zip -d gitea-restore
cd gitea-restore

# restaure repositórios e dados para os volumes usados pelo gitea
sudo cp -r repos/* ../gitea/git/
sudo cp -r data/* ../gitea/gitea/
sudo chown -R 1000:1000 ../gitea/git ../gitea/gitea

# traga o gitea de volta
sudo docker-compose up -d

# restaure o banco de dados
sudo docker exec -i gitea-srv-local_db_1 psql -U gitea gitea < gitea-db.sql

Se você despejou o banco de dados separadamente com pg_dump/pg_restore em vez disso, restaure esse despejo da mesma forma que faria para qualquer outra instância do Postgres - consulte a Folha de Dicas PostgreSQL para os comandos exatos.

Regenerar hooks após a restauração

Se você restaurou para um método de instalação diferente (binário vs Docker) ou um caminho diferente, os git hooks incorporados em cada repositório ainda apontarão para os caminhos antigos. Corrija isso com:

sudo docker exec -u git -it gitea bash -c '/usr/local/bin/gitea admin regenerate hooks'

Pular esta etapa é a causa clássica de push falhar logo após uma restauração sem nenhum erro óbvio na interface.

Verificar a restauração

Antes de considerar concluído:

  1. Faça login na interface e confirme se usuários, problemas e configurações estão corretos.
  2. Clone um repositório e faça push de um commit trivial para confirmar que os hooks funcionam.
  3. Execute gitea doctor check (adicione --fix se detectar algo) para pegar descompassos de caminho ou permissão cedo.

Restaurando um único repositório - restore-repo

A outra peça genuinamente nova desde a última versão deste artigo é um par de comandos para backup e restauração no nível de repositório, separado do fluxo de trabalho de dump/restauração da instância completa acima. São úteis quando você só precisa recuperar um projeto - por exemplo, se alguém deletou à força um repositório - em vez de reverter todo o servidor.

dump-repo extrai um único repositório (mais, opcionalmente, seus problemas, PRs, wiki e outros metadados) para um diretório local:

gitea dump-repo \
  --git_service gitea \
  --clone_addr https://gitea.example.com/owner/repo.git \
  --auth_token <token> \
  --repo_dir /backup/repos/owner/repo \
  --units wiki,issues,labels,releases,milestones,pull_requests,comments

restore-repo então reproduz esse diretório de volta para uma instância, para um dono/repositório escolhido:

gitea restore-repo \
  --repo_dir /backup/repos/owner/repo \
  --owner_name owner \
  --repo_name repo \
  --units issues,labels,milestones,pull_requests,comments

Ambas as listas --units são opcionais - omita-as e tudo que for suportado será migrado. Este par é, na verdade, uma ferramenta de migração no coração (também funciona contra GitHub/GitLab como fonte via --git_service), mas serve bem como uma alternativa leve, por repositório, para um gitea dump completo quando uma restauração completa seria exagero.

Automatizando

Um despejo diário mais cópia fora da caixa é um trabalho cron de duas linhas uma vez que os passos manuais acima funcionem:

# /etc/cron.d/gitea-backup
0 2 * * * root docker exec -u git -w /tmp gitea gitea dump -c /data/gitea/conf/app.ini -f - > /home/uname/gitea-backups/gitea-dump-$(date +\%F).zip 2>> /var/log/gitea-backup.log

Combine isso com uma limpeza de retenção (find ~/gitea-backups -mtime +14 -delete) e uma cópia externa via scp/rsync para que uma falha em um único host não leve os backups junto.

Solução de Problemas

  • permission denied durante o dump - você não está executando como o usuário git, ou --tempdir/-w aponta para um diretório onde o usuário do container não pode gravar.
  • A restauração tem sucesso, mas git push falha - os hooks não foram regenerados; execute gitea admin regenerate hooks.
  • Erros de restauração do banco de dados em uma instância grande - prefira pg_dump/mysqldump nativos em vez do SQL embutido no zip do gitea dump; é conhecido por ter arestas ásperas na restauração para esquemas grandes ou incomuns.
  • Restaurado para um novo versão principal - execute gitea doctor check --all --fix e verifique as notas de lançamento para as etapas de migração daquela versão antes de assumir que a restauração está completa.

Para referência rápida de comandos Git, consulte Folha de Dicas GIT: Os comandos GIT mais úteis.

Subscrever

Receba novos artigos sobre sistemas, infraestrutura e engenharia de IA.