MCPcopy
hub / github.com/nicotsx/zerobyte

github.com/nicotsx/zerobyte @v0.40.0 sqlite

repository ↗ · DeepWiki ↗ · release v0.40.0 ↗
1,928 symbols 6,330 edges 642 files 20 documented · 1%
README

Zerobyte

Powerful backup automation for your remote storage Encrypt, compress, and protect your data with ease

Demo
Backup management with scheduling and monitoring

Join the community

Discord

[!WARNING] Zerobyte is still in version 0.x.x and is subject to major changes from version to version. I am developing the core features and collecting feedback. Please open issues for bugs or feature requests.

Buy Me A Coffee

Introduction

Zerobyte is a backup automation tool that helps you save your data across multiple storage backends. Built on top of Restic, it provides an modern web interface to schedule, manage, and monitor encrypted backups of your remote storage.

Documentation

The official documentation website is available at zerobyte.app.

It contains up-to-date setup guides, configuration reference, and usage documentation for running Zerobyte in production.

Features

  • Automated backups with encryption, compression, and retention policies, powered by Restic
  • Flexible scheduling for automated backup jobs with fine-grained retention policies
  • End-to-end encryption will ensure your data is always protected
  • Multi-protocol support for backup from NFS, SMB, WebDAV, SFTP, or local directories

Installation

In order to run Zerobyte, you need to have Docker and Docker Compose installed on your server. Then, you can use the provided compose.yaml file to start the application.

services:
  zerobyte:
    image: ghcr.io/nicotsx/zerobyte:v0.39
    container_name: zerobyte
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    ports:
      - "4096:4096"
    devices:
      - /dev/fuse:/dev/fuse
    environment:
      - TZ=Europe/Zurich # Set your timezone here
      - BASE_URL=http://localhost:4096 # URL you will use to access Zerobyte
      - APP_SECRET=94bad46...c66e25d5c2b # Generate your own secret with `openssl rand -hex 32`
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/lib/zerobyte:/var/lib/zerobyte

[!WARNING] It is highly discouraged to run Zerobyte on a server that is accessible from the internet (VPS or home server with port forwarding). If you do, make sure to change the port mapping to "127.0.0.1:4096:4096" and use a secure tunnel (SSH tunnel, Cloudflare Tunnel, etc.) with authentication.

[!WARNING] Do not try to point /var/lib/zerobyte to a network share. You will face permission issues and strong performance degradation.

[!NOTE] TrueNAS Users: The host path /var/lib is ephemeral on TrueNAS and will be reset during system upgrades. Instead of using /var/lib/zerobyte:/var/lib/zerobyte, create a dedicated ZFS dataset (e.g., tank/docker/zerobyte) and mount it instead:

yaml volumes: - /etc/localtime:/etc/localtime:ro - /mnt/tank/docker/zerobyte:/var/lib/zerobyte

This ensures your configuration, encryption keys, and database persist across TrueNAS upgrades.

Then, run the following command to start Zerobyte:

docker compose up -d

Once the container is running, you can access the web interface at http://<your-server-ip>:4096.

Configuration

Zerobyte can be customized using environment variables. Below are the available options:

Environment variables

Variable Description Default
BASE_URL Required. The base URL of your Zerobyte instance (e.g., https://zerobyte.example.com). See Authentication below. (none)
APP_SECRET Required. A random secret key (32+ chars) used to encrypt sensitive data in the database. Generate with openssl rand -hex 32. (none)
APP_SECRET_FILE Path to a file containing APP_SECRET, useful with Docker or Kubernetes secrets. Mutually exclusive with APP_SECRET. (none)
PORT The port the web interface and API will listen on. 4096
RESTIC_HOSTNAME The hostname used by Restic when creating snapshots. Automatically detected if a custom hostname is set in Docker. zerobyte
GOMAXPROCS Optional positive integer passed to Restic processes to limit CPU scheduler threads. Useful for reducing CPU pressure during backups. Restic default
TZ Timezone for the container (e.g., Europe/Zurich). Crucial for accurate backup scheduling. UTC
TRUST_PROXY When true, trust an existing X-Forwarded-For header from your reverse proxy. Leave false for direct deployments. false
TRUSTED_ORIGINS Comma-separated list of extra trusted origins for CORS (e.g., http://localhost:3000,http://example.com). (none)
WEBHOOK_ALLOWED_ORIGINS Comma-separated list of HTTP origins allowed for backup webhooks and outbound HTTP notification destinations. (none)
WEBHOOK_TIMEOUT Timeout for backup webhook requests in seconds. 60
LOG_LEVEL Logging verbosity. Options: debug, info, warn, error. info
SERVER_IDLE_TIMEOUT Idle timeout for the server in seconds. 60
RCLONE_CONFIG_DIR Path to the directory containing rclone.conf inside the container. Change this if running as a non-root user. /root/.config/rclone
PROVISIONING_PATH Path to a JSON file with operator-managed repositories and volumes to sync at startup. (none)

Performance tuning

If backups use too much CPU, set GOMAXPROCS on the Zerobyte container and restart it:

environment:
  - GOMAXPROCS=2

This limits the Go scheduler used by Restic child processes. Existing operations are not changed; the new value applies to Restic processes started after the container restart.

Other useful Restic tuning options:

  • Set repository compression to off to reduce CPU usage, or auto for the usual balance. max can save more space but uses more CPU.
  • Use repository upload/download limits to avoid saturating network links.
  • Use backup schedule Custom restic parameters for advanced per-job flags such as --read-concurrency 1, --exclude-larger-than 10G, or --no-scan.

See the full guide: Performance tuning.

Webhook and notification network policy

Backup webhooks and outbound notification destinations that can target arbitrary network hosts are restricted by WEBHOOK_ALLOWED_ORIGINS.

The allowlist matches exact origins only: scheme, host, and port must match. Paths are ignored, so https://hooks.example.com/backups allows any path on https://hooks.example.com, but it does not allow http://hooks.example.com, https://hooks.example.com:8443, or https://other.example.com.

This policy applies to:

  • backup pre/post webhook URLs
  • Generic HTTP notification URLs
  • Gotify server URLs
  • self-hosted ntfy server URLs
  • custom Shoutrrr URLs that point at generic HTTP or SMTP network targets

The public ntfy.sh service and fixed-provider notification services such as Slack, Discord, Pushover, and Telegram do not need WEBHOOK_ALLOWED_ORIGINS.

Backup webhooks do not follow redirects. Add the final destination origin to WEBHOOK_ALLOWED_ORIGINS and configure that final URL directly.

Webhook headers are stored as plain text and must use one Key: Value header per line. WEBHOOK_TIMEOUT controls backup pre/post webhook request timeouts; notification delivery uses the underlying provider sender behavior.

Provisioned resources

Zerobyte can sync operator-managed repositories and volumes from a JSON file at startup. This is useful when you want credentials or connection details to live in deployment-time configuration instead of being entered through the UI.

Provisioned resources:

  • appear in the normal repositories and volumes screens
  • can resolve credential fields from environment variables or /run/secrets/* during startup sync

The complete provisioning documentation is available at zerobyte.app/docs/guides/provisioning.

See examples/provisioned-resources/README.md for a full example.

Simplified setup (no remote mounts)

If you only need to back up locally-mounted folders and don't require remote share mounting capabilities, you can remove the SYS_ADMIN capability and FUSE device from your compose.yaml:

services:
  zerobyte:
    image: ghcr.io/nicotsx/zerobyte:v0.39
    container_name: zerobyte
    restart: unless-stopped
    ports:
      - "4096:4096"
    environment:
      - TZ=Europe/Zurich # Set your timezone here
      - BASE_URL=http://localhost:4096 # Change this to your actual URL (use https:// for secure cookies)
      - APP_SECRET=94bad46...c66e25d5c2b # Generate your own secret with `openssl rand -hex 32`
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/lib/zerobyte:/var/lib/zerobyte
      - /path/to/your/directory:/mydata

Trade-offs:

  • ✅ Improved security by reducing container capabilities
  • ✅ Support for local directories as backup sources
  • ✅ Support all repository types, local and remote (S3, GCS, Azure, rclone)
  • ❌ Cannot mount NFS, SMB, WebDAV, or SFTP shares directly from Zerobyte

If you need remote mount capabilities, keep the original configuration with cap_add: SYS_ADMIN and devices: /dev/fuse:/dev/fuse.

Examples

See examples/README.md for runnable, copy/paste-friendly examples.

Adding your first volume

Zerobyte supports multiple volume backends including NFS, SMB, WebDAV, SFTP, and local directories. A volume represents the source data you want to back up and monitor.

To add your first volume, navigate to the "Volumes" section in the web interface and click on "Create volume". Fill in the required details such as volume name, type, and connection settings.

If you want to backup a local directory on the same host where Zerobyte is running, you'll first need to mount that directory into the Zerobyte container. You can do this by adding a volume mapping in your compose.yaml file. For example, to mount /path/to/your/directory from the host to /mydata in the container, you would add the following line under the volumes section:

services:
  zerobyte:
    image: ghcr.io/nicotsx/zerobyte:v0.39
    container_name: zerobyte
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    ports:
      - "4096:4096"
    devices:
      - /dev/fuse:/dev/fuse
    environment:
      - TZ=Europe/Zurich
      - BASE_URL=http://localhost:4096 # URL you will use to access Zerobyte
      - APP_SECRET=94bad46...c66e25d5c2b # Generate your own secret with `openssl rand -hex 32`
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/lib/zerobyte:/var/lib/zerobyte
+     - /path/to/your/directory:/mydata

After updating the compose.yaml file, restart the Zerobyte container to apply the changes:

docker compose down
docker compose up -d

Now, when adding a new volume in the Zerobyte web interface, you can select "Directory" as the volume type and search for your mounted path (e.g., /mydata) as the source path.

Add a new volume UI

Creating a repository

A repository is where your backups will be securely stored encrypted. Zerobyte supports multiple storage backends for your backup repositories:

  • Local directories: Store backups on local disk subfolders in /var/lib/zerobyte/repositories/ or any other (mounted) path
  • S3-compatible storage: Amazon S3, MinIO, Wasabi, DigitalOcean Spaces, etc.
  • Google Cloud Storage: Google's cloud storage service
  • Azure Blob Storage: Microsoft Azure storage
  • rclone remotes: 40+ cloud storage providers via rclone (see below)

Repositories are optimized for storage efficiency and data integrity, leveraging Restic's deduplication and encryption features.

To create a repository, navigate to the "Repositories" section in the web interface and click on "C

Extension points exported contracts — how you extend this code

ResticDeps (Interface)
(no doc)
packages/core/src/restic/types.ts
Register (Interface)
(no doc)
apps/docs/src/router.tsx
Register (Interface)
(no doc)
app/router.tsx
FileRoutesByFullPath (Interface)
(no doc)
app/routeTree.gen.ts
Window (Interface)
(no doc)
app/client/types/desktop.d.ts
ContextVariableMap (Interface)
(no doc)
app/server/modules/auth/auth.middleware.ts
TestFile (Interface)
(no doc)
scripts/create-test-files.ts
RetentionPolicy (Interface)
(no doc)
packages/core/src/restic/types.ts

Core symbols most depended-on inside this repo

cn
called by 262
app/client/lib/utils.ts
update
called by 132
app/client/api-client/client/utils.gen.ts
toMessage
called by 130
app/server/utils/errors.ts
createTestRepository
called by 93
app/test/helpers/repository.ts
createTestBackupSchedule
called by 83
app/test/helpers/backup.ts
createTestVolume
called by 79
app/test/helpers/volume.ts
createTestSession
called by 61
app/test/helpers/auth.ts
asShortId
called by 56
app/server/utils/branded.ts

Shape

Function 1,649
Method 103
Class 95
Interface 81

Languages

TypeScript100%

Modules by API surface

app/client/api-client/@tanstack/react-query.gen.ts122 symbols
app/client/api-client/sdk.gen.ts82 symbols
app/server/modules/repositories/repositories.service.ts41 symbols
app/server/core/repository-mutex.ts38 symbols
app/client/components/ui/sidebar.tsx25 symbols
app/server/modules/agents/agents-manager.ts21 symbols
app/server/modules/sso/sso.service.ts20 symbols
app/client/api-client/client/utils.gen.ts20 symbols
e2e/0003-oidc.spec.ts19 symbols
e2e/0002-backup-restore.spec.ts19 symbols
app/server/modules/volumes/volume.service.ts19 symbols
app/server/modules/notifications/notifications.service.ts18 symbols

Dependencies from manifests, versioned

@base-ui/react1.5.0 · 1×
@better-auth/api-key1.6.18 · 1×
@better-auth/passkey1.6.18 · 1×
@better-auth/sso1.6.18 · 1×
@better-auth/utils0.4.1 · 1×
@cloudflare/vite-plugin1.40.2 · 1×
@dnd-kit/core6.3.1 · 1×
@dnd-kit/sortable10.0.0 · 1×
@dnd-kit/utilities3.2.2 · 1×
@effect/language-service0.86.2 · 1×
@faker-js/faker10.4.0 · 1×
@fontsource-variable/jetbrains-mono5.2.8 · 1×

For agents

$ claude mcp add zerobyte \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact