Skip to content

Add git backup to remote repository (closes #996)#1018

Open
EduardSchwarzkopf wants to merge 57 commits into
perber:mainfrom
EduardSchwarzkopf:main
Open

Add git backup to remote repository (closes #996)#1018
EduardSchwarzkopf wants to merge 57 commits into
perber:mainfrom
EduardSchwarzkopf:main

Conversation

@EduardSchwarzkopf
Copy link
Copy Markdown

What: Automated git backup to a remote repository via SSH with configurable schedule.

Why: Addresses the feature request in #996 — users wanted an optional way to auto-commit page saves and push them to a remote git repository for backup purposes, similar to Otterwiki's experimental repository management feature.

Changes:

  • New internal/backup/ package — Git repository operations, scheduled backup runner, configuration, status tracking, and gitignore handling
  • Admin API routesGET /api/admin/backup/status and POST /api/admin/backup/push endpoints
  • Frontend UI — Backup settings page accessible from user dropdown
  • Documentation — README updated, docs/docker-backup.md added
  • Configuration — CLI flags and env variables for remote URL, branch, SSH key, interval, author

Configuration

CLI Flags

Flag Description Default
--git-backup Enable automated git backup false
--git-backup-remote SSH remote URL for the backup repository ""
--git-backup-branch Git branch to push to main
--git-backup-author-name Git commit author name LeafWiki Backup
--git-backup-author-email Git commit author email backup@leafwiki.local
--git-backup-interval Backup interval in minutes 60
--git-backup-ssh-key-path Path to SSH private key file ""
--git-backup-ssh-key Raw SSH private key (PEM) ""
(new) --git-backup-ssh-known-hosts Known hosts for MITM protection ""

Environment Variables

Variable Description
LEAFWIKI_GIT_BACKUP Enable automated git backup
LEAFWIKI_GIT_BACKUP_REMOTE SSH remote URL for the backup repository
LEAFWIKI_GIT_BACKUP_BRANCH Git branch to push to
LEAFWIKI_GIT_BACKUP_AUTHOR_NAME Git commit author name
LEAFWIKI_GIT_BACKUP_AUTHOR_EMAIL Git commit author email
LEAFWIKI_GIT_BACKUP_INTERVAL Backup interval in minutes
LEAFWIKI_GIT_BACKUP_SSH_KEY_PATH Path to SSH private key file
LEAFWIKI_GIT_BACKUP_SSH_KEY Raw SSH private key (PEM)
LEAFWIKI_GIT_BACKUP_SSH_KNOWN_HOSTS Known hosts for MITM protection

Example usage

./leafwiki \
  --git-backup=true \
  --git-backup-remote=git@github.com:user/leafwiki-backup.git \
  --git-backup-branch=main \
  --git-backup-author-name="LeafWiki Backup" \
  --git-backup-author-email=backup@leafwiki.local \
  --git-backup-interval=60 \
  --git-backup-ssh-key-path=/path/to/id_rsa

Or via environment variables:

LEAFWIKI_GIT_BACKUP=true
LEAFWIKI_GIT_BACKUP_REMOTE=git@github.com:user/leafwiki-backup.git
LEAFWIKI_GIT_BACKUP_SSH_KEY_PATH=/path/to/id_rsa

Admin API

When git backup is enabled, two admin-only REST endpoints are available:

Method Endpoint Description
GET /api/admin/backup/status Returns backup status: lastBackupAt, lastError
POST /api/admin/backup/push Triggers an immediate backup push (returns 202 Accepted)

Restoring from backup

To restore your wiki from a git backup:

  1. Stop the LeafWiki server
  2. Navigate to your data directory
  3. Use git log to view backup history and git checkout <commit> to restore
  4. Restart the LeafWiki server

Note: Only root/ and assets/ are backed up. The SQLite database is not included.

@perber
Copy link
Copy Markdown
Owner

perber commented May 22, 2026

I let Co-Pilot running a review as well. Lets see what the AI is finding :) - Actually for me it looks already good for first version.
I'm just thinking about to move the startup code into tools (https://github.com/perber/leafwiki/tree/main/internal/core/tools). Let me know what you are thinking. I've added the admin-reset there.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an automated Git-based backup system that periodically commits wiki content and (optionally) pushes it to a configured SSH remote, plus admin endpoints and UI to view status and trigger manual pushes.

Changes:

  • Introduces internal/backup (git repo init/commit/push, scheduler, status, gitignore management) and wires it into the server.
  • Adds admin-only API routes for backup status and manual push triggers.
  • Adds a frontend “Backup Settings” page + Zustand store + API client for status/push.

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
ui/leafwiki-ui/src/stores/backup.ts Zustand store for backup status + push trigger state
ui/leafwiki-ui/src/lib/api/backup.ts Frontend API client for backup status + push
ui/leafwiki-ui/src/features/router/router.tsx Adds /settings/backup route
ui/leafwiki-ui/src/features/backup/useToolbarActions.ts Clears toolbar buttons on Backup Settings mount
ui/leafwiki-ui/src/features/backup/BackupSettings.tsx Backup Settings UI incl. status polling + manual push
ui/leafwiki-ui/src/components/UserToolbar.tsx Adds “Backup Settings” link for admins
readme.md Documents git backup feature + config + usage
internal/wiki/wiki.go Allows optionally registering backup routes
internal/wiki/backup/routes.go Admin API endpoints for backup status + manual trigger
internal/backup/status.go Status tracking for last backup + error
internal/backup/scheduler.go Background scheduler + manual trigger channel
internal/backup/scheduler_test.go Tests for scheduler behavior
internal/backup/repo.go Git repository init/commit/push implementation
internal/backup/repo_test.go Tests for repo init + commit behavior
internal/backup/gitignore.go Writes .gitignore into the repo root
internal/backup/gitignore_test.go Tests .gitignore creation/non-overwrite
internal/backup/config.go Backup config (paths, author, remote, SSH, interval)
cmd/leafwiki/main.go CLI/env wiring, scheduler startup, routes registration
.env.example Documents git backup environment variables
go.mod Adds go-git and other deps
go.sum Updates checksums for new deps

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ui/leafwiki-ui/src/features/backup/BackupSettings.tsx
Comment thread ui/leafwiki-ui/src/lib/api/backup.ts Outdated
Comment thread internal/backup/repo.go
Comment thread internal/backup/repo.go
Comment thread internal/backup/gitignore.go
Comment thread cmd/leafwiki/main.go
Comment thread .env.example
Comment thread go.mod Outdated
Comment thread readme.md Outdated
Comment thread readme.md Outdated
@perber
Copy link
Copy Markdown
Owner

perber commented May 22, 2026

Could you go through the Co-Pilot mentions.

@EduardSchwarzkopf
Copy link
Copy Markdown
Author

oh wow, I'm impressed by the findings. I will check them out.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@perber
Copy link
Copy Markdown
Owner

perber commented May 23, 2026

oh wow, I'm impressed by the findings. I will check them out.

Yes, I’m often shocked too :)
But you really need to go through it, because sometimes not all of it is true.

@perber
Copy link
Copy Markdown
Owner

perber commented May 23, 2026

Let me know when you are done.
I think we should release this in v0.11.0. Hopefully this is fine for you.

@EduardSchwarzkopf
Copy link
Copy Markdown
Author

absolutely fine. Should I update the versions in the README from v0.10.0 to v,0.11.0 for the backup and reverse proxy features?

Flag Description Default Available since
--jwt-secret Secret used for signing JWTs (required)
--host Host/IP address the server binds to 127.0.0.1
--port Port the server listens on 8080
--data-dir Directory where data is stored ./data
--admin-password Initial admin password (used only if no admin exists) (required)
--public-access Allow public read-only access false
--hide-link-metadata-section Hide link metadata section false
--inject-code-in-header Raw HTML/JS code injected into tag (e.g., analytics, custom CSS) "" v0.6.0
--custom-stylesheet Path to a .css file inside the data dir, served publicly as /custom.css or ${base-path}/custom.css "" v0.8.5
--allow-insecure ⚠️ Allows insecure HTTP usage for auth cookies (required for plain HTTP) false v0.7.0
--access-token-timeout Access token timeout duration (e.g. 24h, 15m) 15m v0.7.0
--refresh-token-timeout Refresh token timeout duration (e.g. 168h, 7d) 7d v0.7.0
--disable-auth ⚠️ Disable authentication & authorization (internal networks only!) false v0.7.0
--base-path URL prefix when served behind a reverse proxy (e.g. /wiki) "" v0.8.2
--max-asset-upload-size Maximum size for asset uploads (e.g. 50MiB, 50MB, 52428800) 50MiB v0.8.5
--enable-revision Enable revision history / page history false v0.9.0
--enable-link-refactor Enable link refactoring dialog and rewrite flow false v0.9.0
--max-revision-history Maximum revisions kept per page; 0 means unlimited 100 v0.9.0
--enable-http-remote-user Enable reverse-proxy authentication via HTTP header false v0.10.0
--http-remote-user-header-name HTTP header carrying the username from a trusted proxy Remote-User v0.10.0
--trusted-proxy-ips Comma-separated list of trusted proxy IPs/CIDRs (e.g. 127.0.0.1,172.18.0.0/16) "" v0.10.0
--http-remote-user-logout-url URL the frontend redirects to after logout in proxy-auth mode "" v0.10.0
--git-backup Enable automated git backup to a remote repository false v0.10.0
--git-backup-remote SSH remote URL for the backup repository (optional; omit to use local-only git history) "" v0.10.0
--git-backup-branch Git branch to push to main v0.10.0
--git-backup-author-name Git commit author name LeafWiki Backup v0.10.0
--git-backup-author-email Git commit author email backup@leafwiki.local v0.10.0
--git-backup-interval Backup interval in minutes 60 v0.10.0
--git-backup-ssh-key-path Path to SSH private key file "" v0.10.0
--git-backup-ssh-key Raw SSH private key (PEM) "" v0.10.0

@EduardSchwarzkopf
Copy link
Copy Markdown
Author

alright, i have updated the code. I hope i got everything. Let me know if there is still some things missing.

@perber
Copy link
Copy Markdown
Owner

perber commented May 24, 2026

Hi @EduardSchwarzkopf,

thanks!
The proxy configuration will be in v0.10.0. I added a proxy setup with dex enabled into the hacks folder to verify if it is working as expected.

It would be could if you could create a separate PR with the flag documentation of the proxy settings. I would keep the Git configuration still in this PR, to be ready for the v0.11.0 release.

I will checkout the branch and let it run on my system and test it a bit manually before merging it. Hopefully soon ;)

If you are interested to support more let me know!

One issue I'm facing at the moment, as the flags are growing not sure if it makes sense to keep them like that. If you are interested to do a proposal and implementing it.

Let me know!

But we still need to consider how it could be started in a few seconds without providing a huge configuration file.
So, I'm not sure at the moment how to do it best and if this is a good direction either. Or just grouping the flags.

Maybe like Paperless-ngx? https://docs.paperless-ngx.com/configuration/

They allow a configuration file & flags. Maybe this is the way to go.

@EduardSchwarzkopf
Copy link
Copy Markdown
Author

It would be could if you could create a separate PR with the flag documentation of the proxy settings. I would keep the Git configuration still in this PR, to be ready for the v0.11.0 release.

Alright, will remove this from my PR then and provide a new PR.

If you are interested to support more let me know!

Sadly i do not have that much time to be an active maintainer, but I might provide more support in the future, when i see the need for a new feature/fix :D

One issue I'm facing at the moment, as the flags are growing not sure if it makes sense to keep them like that. If you are interested to do a proposal and implementing it.

Yes, I see the point, having this managed via a config or .env file is fine for the moment. Long term, I'd suggest moving this into a settings page, so the user can manage this via UI?

@perber
Copy link
Copy Markdown
Owner

perber commented May 24, 2026

Alright, will remove this from my PR then and provide a new PR.

Perfect, thanks!

Sadly i do not have that much time to be an active maintainer, but I might provide more support in the future, when i see the need for a new feature/fix :D

Happy to hear ;)

Yes, I see the point, having this managed via a config or .env file is fine for the moment. Long term, I'd suggest moving this into a settings page, so the user can manage this via UI?

Here I need to think a bit deeper, because as a K8s admin, I hate having my configuration not managed via GitOps. So it depends, but I need to think about it.

@EduardSchwarzkopf
Copy link
Copy Markdown
Author

Here I need to think a bit deeper, because as a K8s admin, I hate having my configuration not managed via GitOps. So it depends, but I need to think about it.

100%, considering the point that the setup itself requires some sort of technical knowledge, I'd 100% second your idea with a configuration file. Maybe to have the pluses of both worlds, the app can provide a small overview of enabled features and their values, similar to Firefox's about:config`. Another benefit of this is that it also provides a bit of a sanity check.

@perber perber added this to the v0.11.0 milestone May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants