Backup e ripristino del server Gitea

Backup e ripristino di Gitea, nel modo giusto

Indice

I backup di Gitea interessano tre elementi dinamici - il database, i repository git e i file dell’applicazione - e dal 2024 il comando integrato gitea dump gestisce tutti e tre in un’unica operazione.

bellissima foto di un hdd aperto

Nel post Test di Gitea abbiamo installato il server Gitea. Questo è il seguito: come effettuare effettivamente il backup e, soprattutto, come ripristinarlo quando qualcosa va storto.

Per la completa collezione di strumenti per sviluppatori, inclusi i flussi di lavoro Git e la gestione Docker, consulta Strumenti per Sviluppatori: La Guida Completa ai Flussi di Lavoro Moderni di Sviluppo.

Se stai configurando Gitea per la prima volta, consulta Scegliere un server git on-prem gratuito - Gitea è il vincitore! per i dettagli sull’installazione, e Gitea SSL con Apache come reverse proxy per una deployment sicura.

Quando provare questa procedura

Adesso, come precauzione contro eventi spiacevoli, è un buon momento per provare la procedura di backup e ripristino - prima di averne davvero bisogno, non dopo la morte di un disco.

Meglio essere prudenti che pentirsene.

Dove risiedono i dati

Un’istanza Gitea è in realtà composta da tre componenti che devono rimanere in sincronia:

  • codice (repository git)
  • filestore (allegati, avatar, oggetti LFS, indicizzatori)
  • db (utenti, issue, PR, impostazioni)

Nel nostro ambiente di test, tutti insieme occupano un po’ più di 700MB:

utilizzo disco gitea

Poiché questi tre elementi si fanno riferimento a vicenda, la documentazione di Gitea stessa è esplicita sulla coerenza del backup: l’istanza deve essere fermata per la durata dell’operazione, altrimenti un repository copiato durante una migrazione potrebbe risultare fuori sincronia rispetto a ciò che il database registra. Il ripristino, per lo stesso motivo, deve avvenire come un’unica transazione.

Il metodo semplice - gitea dump

Questa è la parte che è cambiata rispetto alla versione precedente di questo articolo: invece di gestire manualmente pg_dump, tar e cartelle separate, Gitea offre un singolo comando dump che raggruppa database, repository, dati LFS, allegati e configurazione in un unico archivio.

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

Questo produce un file con timestamp come gitea-dump-1610949662.zip contenente:

  • app.ini - copia del file di configurazione
  • custom/ - personalizzazioni sotto custom/
  • data/ - allegati, avatar, oggetti LFS, indicizzatori (e il file SQLite, se è il tuo db)
  • repos/ - copia completa della directory dei repository
  • gitea-db.sql - dump SQL del database
  • log/ - log (non necessari per il ripristino)

Flag utili da conoscere:

  • --file name / -f name - nome del file di output (- per stdout, comodo per pipe dirette su scp o archivi oggetto)
  • --type - formato di output: zip (default), tar, tar.gz, tar.xz, tar.zst, ecc.
  • --database / -d - forza il dialetto SQL in gitea-db.sql (sqlite3, mysql, mssql, postgres) - utile quando si migra tra motori database
  • --skip-repository / -R, --skip-lfs-data, --skip-attachment-data, --skip-package-data, --skip-log, --skip-db - riduce il dump solo a ciò che serve
  • --tempdir / -t - dove vengono posizionati i file intermedi (default /tmp o $TMPDIR) - assicurati che ci sia spazio libero sufficiente per l’intera istanza

Eseguire gitea dump in Docker

Poiché la maggior parte delle configurazioni self-hosted esegue Gitea tramite docker-compose, il comando deve essere eseguito all’interno del container, come utente git, dalla directory temporanea del container:

cd ~/gitea-srv-local

# crea un dump all'interno del container in esecuzione
sudo docker exec -u git -it -w /tmp gitea bash -c \
  '/usr/local/bin/gitea dump -c /data/gitea/conf/app.ini'

# copia il zip risultante fuori dal container
sudo docker cp gitea:/tmp/gitea-dump-*.zip ./gitea-backups/

-w /tmp è importante: dump deve scrivere e comprimere la sua directory di lavoro temporanea, ed eseguirlo in un luogo senza permessi di scrittura causerà un errore di permesso.

Poi, come prima, porta l’archivio fuori dalla macchina:

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

Se preferisci fare il dump del database con strumenti nativi (la documentazione di Gitea stessa lo consiglia per MySQL/PostgreSQL, poiché il dump SQL basato su XORM all’interno di gitea dump presenta casi limite noti al ripristino), puoi farlo comunque in parallelo:

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'

Consulta la Scheda Rapida PostgreSQL per altre opzioni di pg_dump/pg_restore, e la Scheda Rapida Docker Compose se la sintassi docker exec/docker cp sopra sembra non familiare.

Come - Ripristino

Non esiste ancora un ripristino con un solo comando - la documentazione di Gitea è trasparente nel dire che questo rimane un processo manuale di rimettere i file a posto e ripristinare il dump del database. Ma! Verifica sempre prima la documentazione originale, poiché i percorsi e i layout dei container cambiano tra le versioni.

# installa/avvia un gitea fresco (stessa versione del backup) poi fermalo
sudo docker-compose down

# dezippa il dump
unzip gitea-dump-1610949662.zip -d gitea-restore
cd gitea-restore

# ripristina repo e dati nei volumi che gitea usa
sudo cp -r repos/* ../gitea/git/
sudo cp -r data/* ../gitea/gitea/
sudo chown -R 1000:1000 ../gitea/git ../gitea/gitea

# riavvia gitea
sudo docker-compose up -d

# ripristina il database
sudo docker exec -i gitea-srv-local_db_1 psql -U gitea gitea < gitea-db.sql

Se hai fatto il dump del db separatamente con pg_dump/pg_restore invece, ripristina quel dump allo stesso modo in cui faresti per qualsiasi altra istanza Postgres - consulta la Scheda Rapida PostgreSQL per i comandi esatti.

Rigenerare gli hook dopo il ripristino

Se hai ripristinato in un metodo di installazione diverso (binario vs Docker) o in un percorso diverso, gli hook git incorporati in ciascun repository punteranno ancora ai vecchi percorsi. Correggi questo con:

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

Saltare questo passaggio è la causa classica di push che fallisce subito dopo un ripristino senza errori evidenti nell’interfaccia.

Verificare il ripristino

Prima di considerarlo completato:

  1. Accedi all’interfaccia e conferma che utenti, issue e impostazioni siano corrette.
  2. Clona un repository e fai push di un commit banale per confermare che gli hook funzionino.
  3. Esegui gitea doctor check (aggiungi --fix se segnala qualcosa) per catturare presto discrepanze di percorso o permessi.

Ripristino di un singolo repository - restore-repo

L’altra nuova caratteristica genuina da l’ultima versione di questo articolo è una coppia di comandi per backup e ripristino a livello di repository, separati dal flusso di lavoro dump/ripristino dell’intera istanza sopra. Sono utili quando hai bisogno di recuperare solo un progetto - ad esempio, qualcuno ha eliminato di forza un repo - invece di fare rollback dell’intero server.

dump-repo estrae un singolo repository (più, opzionalmente, le sue issue, PR, wiki e altri metadati) in una directory locale:

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 poi ricalcola quella directory all’interno di un’istanza, in un owner/repo scelto:

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

Entrambi gli elenchi --units sono opzionali - omettili e tutto ciò che è supportato verrà migrato. Questa coppia è in realtà uno strumento di migrazione nel cuore (funziona anche contro GitHub/GitLab come sorgente tramite --git_service), ma funziona anche bene come alternativa leggera, per-repo, a un gitea dump completo quando un ripristino completo sarebbe eccessivo.

Automatizzarlo

Un dump giornaliero più una copia off-box è un lavoro cron di due righe una volta che i passaggi manuali sopra funzionano:

# /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

Abbinalo a una pulizia della retention (find ~/gitea-backups -mtime +14 -delete) e a una copia off-site tramite scp/rsync in modo che un guasto a un singolo host non trascini con sé i backup.

Risoluzione dei problemi

  • permission denied durante dump - non stai eseguendo come utente git, o --tempdir/-w punta a una directory a cui l’utente del container non può scrivere.
  • Il ripristino riesce ma git push fallisce - gli hook non sono stati rigenerati; esegui gitea admin regenerate hooks.
  • Errori di ripristino del database su un’istanza grande - preferisci i nativi pg_dump/mysqldump rispetto al SQL incorporato nel zip di gitea dump; è noto per avere spigoli ruvidi al ripristino per schemi grandi o insoliti.
  • Ripristinato a una nuova major version - esegui gitea doctor check --all --fix e controlla le release notes per i passaggi di migrazione di quella versione prima di dare per scontato che il ripristino sia completo.

Per riferimento rapido sui comandi Git, consulta Scheda Rapida GIT: I comandi GIT più utili.

Iscriviti

Ricevi nuovi articoli su sistemi, infrastruttura e ingegneria AI.