Backups
What to back up and how. Currently no automation — these are commands I run by hand.
What to back up
| Path | What's in it |
|---|---|
/var/discourse/shared/standalone/ |
Discourse db + uploads — use Discourse's built-in backup, not raw tar |
/opt/forgejo/data/ |
Forgejo repos + sqlite + LFS — stop the container first |
/var/sftp/shared/uploads/ |
Filedrop + SFTP shared bucket |
/home/drew/docker/filebrowser/{srv,database,config} |
Filebrowser files + user db |
/etc/cloudflared/ |
Tunnel UUID + credentials |
/etc/ssh/sshd_config + /etc/ssh/ssh_host_* |
sshd config + host keys |
/var/landing/ |
The two landing sites + their compose |
/opt/filedrop/ |
Filedrop compose, nginx.conf, hooks |
Skipped: Docker images (re-pullable), /opt/filedrop/tusdata/ (in-flight uploads).
Procedures
Discourse — use the built-in backup
# Web UI: Admin → Settings → Backups → Create Backup
# Or CLI:
sudo /var/discourse/launcher enter app
discourse backup
exit
# Backup lands in /var/discourse/shared/standalone/backups/default/<timestamp>.tar.gz
# Copy off-host:
rsync -av /var/discourse/shared/standalone/backups/default/ <remote>:/backups/discourse/
The Discourse backup CLI produces one tarball with everything — db dump + uploads. Don't just rsync the data dir — you'll grab postgres mid-write and end up with a broken backup.
Forgejo — stop, tar, start
cd /opt/forgejo
docker compose stop forgejo
sudo tar czf /backups/forgejo-$(date +%F).tar.gz -C /opt/forgejo data/
docker compose start forgejo
Stop is required because the sqlite db is a single file with WAL — copying it live can produce a corrupted backup. Stop is fast (seconds).
For zero-downtime: use sqlite3 /opt/forgejo/data/gitea/gitea.db ".backup /tmp/gitea.db.bak" then tar both that and the rest of data/. The repos themselves are bare git and are safe to copy live (a half-pushed pack is harmless — git resyncs).
Filedrop / SFTP shared bucket
rsync -av --delete /var/sftp/shared/uploads/ <remote>:/backups/uploads/
Append-only bucket — --delete is safe if the policy is "remote mirror". Drop --delete if you want to retain files that have been removed locally.
Filebrowser
cd /home/drew/docker/filebrowser
docker compose stop filebrowser # quick — protects sqlite
sudo tar czf /backups/filebrowser-$(date +%F).tar.gz srv/ database/ config/
docker compose start filebrowser
Configs (small, daily)
sudo tar czf /backups/configs-$(date +%F).tar.gz \
/etc/cloudflared \
/etc/ssh/sshd_config /etc/ssh/ssh_host_* \
/var/landing \
/opt/filedrop/docker-compose.yml /opt/filedrop/nginx /opt/filedrop/hooks \
/opt/forgejo/docker-compose.yml \
/home/drew/docker/filebrowser/docker-compose.yml
Tiny tarball (~MB). Run daily. This is what you'd need to rebuild the box alongside the data tarballs above.
Where to put the tarballs
Easiest: rsync them to another machine on the tailnet.
rsync -av /backups/ drew@um890pro:/backups/discourse/
Tailscale handles the encryption, no other setup needed. Right now there is no off-host backup — that's the gap.
Restore
See Recovery.
Navigation
Quick Links
Projects
Server (discourse)
- Host
- Cloudflare Tunnel
- Tailscale
- SFTP
- Discourse
- Forgejo
- Filedrop
- Filebrowser
- Landing Sites
- Onboarding
- Backups
- Recovery
Window Managers
Homelab
Docker
Software
Thoughts
Archived
Connect
Butterbian — my Debian 13 distro · butterrepo — community APT repo · butterknife — TUI installer
justaguylinux.com · Butterforge · Butter Lab · The Churn · YouTube · Mastodon · Links · Contact · Support on Buy Me a Coffee
"Not an expert. Just A Guy." — Licensed CC BY-SA 4.0 · © 2026 JustAGuy Linux