{"id":19349076,"url":"https://github.com/digineo/zackup","last_synced_at":"2025-04-23T06:30:47.920Z","repository":{"id":38316482,"uuid":"163992174","full_name":"digineo/zackup","owner":"digineo","description":"Backup to ZFS. Inspired by BackupPC","archived":false,"fork":false,"pushed_at":"2023-04-14T07:00:31.000Z","size":303,"stargazers_count":13,"open_issues_count":10,"forks_count":3,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-02T09:22:30.818Z","etag":null,"topics":["backup","backup-tool","backuppc","go","golang","rsync","zfs","zfs-snapshots"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digineo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-03T15:45:24.000Z","updated_at":"2023-11-14T02:49:20.000Z","dependencies_parsed_at":"2024-06-19T04:00:45.007Z","dependency_job_id":"165c5257-9565-49fd-b03d-83d9c34cc913","html_url":"https://github.com/digineo/zackup","commit_stats":{"total_commits":79,"total_committers":4,"mean_commits":19.75,"dds":"0.15189873417721522","last_synced_commit":"085d0300ef48504e5e503af54ce8b5bfaacf32f7"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digineo%2Fzackup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digineo%2Fzackup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digineo%2Fzackup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digineo%2Fzackup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digineo","download_url":"https://codeload.github.com/digineo/zackup/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250384707,"owners_count":21421779,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup","backup-tool","backuppc","go","golang","rsync","zfs","zfs-snapshots"],"created_at":"2024-11-10T04:24:35.010Z","updated_at":"2025-04-23T06:30:47.539Z","avatar_url":"https://github.com/digineo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"zackup.png\" alt=\"zackup\" style=\"max-width:100%;\"\u003e\u003c/p\u003e\n\n# zackup - Backup to ZFS\n\n\nSmall utility to replace BackupPC.\n\n- for each `host` in `list_of_hosts` do:\n  - if `zfs_dataset_for_host` does not exist:\n    - create `zfs_dataset_for_host`\n  - for each `command` in `list_of_pre_commands_for_host`:\n    - execute `command` on host\n  - rsync `list_of_configured_files` from `host` to `zfs_dataset_for_host`\n  - for each `command` in `list_of_post_commands_for_host`:\n    - execute `command` on `host`\n  - create snapshot of `zfs_dataset_for_host`\n\n\n## Usage\n\n    zackup [COMMAND] [--root ROOT_DIR] [--gelf host:port]\n\nInstead of `--root`, you may set a `ZACKUP_ROOT` environment variable.\nThe command line flag takes precedence if both are given.\n\n    export ZACKUP_ROOT=ROOT_DIR\n    zackup [COMMAND]\n\nUse something like `--gelf graylog.example.com:12201` to direct log\nmessages to a remote logging server.\n\n### `COMMAND`\n\nDefaults to `help`.\n\n- `run`\n\n  Creates a backup for each host config. Backups are stored locally in\n  a per-host dataset.\n\n  Run `zackup help run` for a list of possible options.\n\n- `status`\n\n  Prints a list of hosts and their backup status (last success, size)\n\n- `help`\n\n  Prints a help listing with all available commands.\n\nYou can run `zackup help COMMAND` to get a list of possible options.\n\n### `ROOT_DIR`\n\nDefaults to `/usr/local/etc/zackup`. Its content is used as config tree.\nWe assume these files exist in `ROOT_DIR`:\n\n    ROOT_DIR/\n    +-- config.yml                    service configuration\n    +-- globals.yml                   global defaults for host configs\n    +-- hosts/\n        +-- $host/config.yml          host config (variant A)\n        +-- $host.yml                 host config (variant B)\n        +-- $host/{pre,post}.*.sh     host-specific scripts (optional)\n\nThe *list of hosts* is comprised of each `ROOT_DIR/hosts/$host` entry.\nA `$host` is a string matching the rules for DNS host name labels.\n\nA host may have scripts executed (via SSH) *before* and/or *after*\nrsyncing. These scripts are defined by the `ROOT_DIR/hosts/$host/pre.*.sh`\nand `ROOT_DIR/hosts/$host/post.*.sh` files. See sec. \"Hooks\" below.\n\nYou may also create a `ROOT_DIR/hosts/example.com.yml` instead of a\n`ROOT_DIR/hosts/example.com/config.yml` if you don't have any pre- or\npost-commands to execute (i.e. you have no script *files*, you can still\ndefine *inline* script one-liners).\n\nIt is an error to have both `ROOT_DIR/hosts/$host/config.yml` and\n`ROOT_DIR/$host.yml`.\n\n\n## Setup\n\nIt is recommended to create a compressed ZFS dataset for all backups:\n\n```console\n# zfs create -o compression=lz4 zpool/zackup\n```\n\nand add `zpool/zackup` as `root_dataset` to the service configuration file.\n\n\n## Service config\n\nzackup requires a previously mentioned service configuration file in\n`ROOT_DIR/config.yml`, which defines these properties:\n\n```yaml\nparallel:     uint8     # number backups to run in parallel\nroot_dataset: string    # base dataset to create host-datasets under\nmount_base:   path      # working directory to mount host dataset into\nlog_level:    enum      # one of DEBUG, INFO, WARN, ERROR, FATAL, PANIC (case insensitive)\ngraylog:      addr      # if set, write logs to this GELF UDP endpoint\n\n# We require rsync and ssh commands to be in $PATH. Adjust these, if either\n# $PATH does not contain these, or your binaries are named differently.\nrsync_bin:    string\nssh_bin:      string\n\n# daemon hold settings specific to the \"zackup serve\" command.\ndaemon:\n  # strftime format for scheduled backups\n  schedule:   \"%H:%M:%S\"\n\n  # Random amount of jitter around the schedule time. The actual backup\n  # will start in the time range schedule ± jitter/2. jitter must be\n  # parsable with Go's time.ParseDuration() function.\n  #\n  # Jitter is applied to each host seperately.\n  jitter:     duration\n```\n\nThe defaults are:\n\n```yaml\nparallel:     5\nroot_dataset: zpool/zackup\nmount_base:   /zpool/zackup\nlog_level:    info\nrsync_bin:    rsync\nssh_bin:      ssh\ndaemon:\n  schedule:   \"04:00:00\"\n  jitter:     \"40m\" # → between 03:40:00 and 04:20:00\n```\n\n\n## Hooks (pre- and post-scripts)\n\nWithin the host config directory, you can define `pre.*.sh` and `post.*.sh`\nfiles, which are executed in alphabetically order *before* the rsync\nprocess starts, and *after* it has finished.\n\nFor conveniance, you can add *inline* hook scripts into the host config\nfile (more on that in the next section). These inline scripts are executed\nbefore any `pre.*.sh` or `post.*.sh` scripts.\n\nPlease note that hook scripts (both inline and files) are piped directly\ninto `/bin/sh -esx`, so you don't need a shebang. Think of a simple\n`cat $host/pre.*.sh | ssh $host /bin/sh -esx`.\n\nIf any of those scripts exits with a non-zero exit status, the backup is\nmarked as failed.\n\n\n## Host config\n\nA host's config file is written in YAML and has this structure:\n\n```yaml\nssh:\n  user:     string    # username on the remote host\n  port:     uint16    # SSH port number\n  timeout:  int       # timeout for establishing connection\n\nrsync:\n  include:  []string  # rsync pattern for included files/directories\n  exclude:  []string  # rsync pattern for excluded files/directories\n  args:     []string  # other rsync arguments\n\n  # included, excluded and args will be merged with the global config\n  # by default. if you want a fresh start, without globally defined\n  # values, uncomment the corresponding entry:\n  #override_global_included: true\n  #override_global_excluded: true\n  #override_global_args:     true\n\n# Inline scripts executed on the remote host before and after rsyncing,\n# and before any `pre.*.sh` and/or `post.*.sh` scripts for this host.\npre_script:  string\npost_script: string\n```\n\n\n## Global config\n\nzackup looks for a global config file in `ROOT_DIR/globals.yml`.\n\nUse this file to specify defaults (a single host's config is basically\nmerged into the global config). zackup brings no defaults (not even for\nrsync!), but you can use this as a start:\n\n```yaml\nssh:\n  user: root\n  port: 22\n  timeout: 10\nrsync:\n  include:\n  - /etc\n  - /home\n  - /opt\n  - /root\n  - /srv\n  - /usr/local/etc\n  - /var/spool/cron\n  - /var/www\n  exclude:\n  - \"tmp\"\n  - \"*.log\"\n  - \"*.log.*\"\n  - \".cache\"\n  - \".config\"\n  args:\n  - \"--numeric-ids\"\n  - \"--perms\"\n  - \"--owner\"\n  - \"--group\"\n  - \"--devices\"\n  - \"--specials\"\n  - \"--links\"\n  - \"--hard-links\"\n  - \"--block-size=2048\"\n  - \"--recursive\"\n```\n\n# Copyright\n\nCopyright (C) 2018-2019 Dominik Menke, Digineo GmbH. All rights reserved.\n\nContains ported code of BackupPC, Copyright (C) 2001-2018 Craig Barret.\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License.\n\nSee the LICENSE file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigineo%2Fzackup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigineo%2Fzackup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigineo%2Fzackup/lists"}