GoBackup:一个 Go 二进制,把数据库和目录按 cron 备份到 20+ 种存储
- 项目地址:
- 文档站:
- 示例配置:
- License:MIT(Go 编写,单二进制、无运行时依赖)
设计目标
GoBackup 面向应用服务器:把数据库和文件按计划备份到云存储(FTP、SCP、S3、GCS、阿里云 OSS 等)。它的几个明确取向:
- 一次配置,跑几年不需要维护;
- 低成本,靠每个存储目标上的
keep份数回收旧备份; - 安全,落盘前做压缩和加密;
- 单二进制,不依赖 Ruby 或其他运行时。
项目灵感来自 backup/backup,用 Go 重写以去掉 Ruby 依赖。README 里给的案例是 Ruby China 的应用服务器,从 2017 年起每天备份到外部云存储,阿里云 OSS 的月成本约 0.2 元(回收周期一个月)。
安装
三种方式:
# 安装脚本,落到 /usr/local/bin/gobackup
curl -sSL https://gobackup.github.io/install | sh
# Homebrew
brew install gobackup
# Docker
docker pull huacnlee/gobackup
命令与 Web UI
gobackup -h 的输出(VERSION 1.3.0 示例):
$ gobackup -h
NAME: gobackup - Backup your databases, files to FTP / SCP / S3 / GCS and other cloud storages.
VERSION: 1.3.0
COMMANDS:
perform
start (Start as daemon)
run (Run GoBackup)
help
三个常用入口:
gobackup perform:跑一次备份然后退出;gobackup start:以守护进程方式启动,同时开启调度和 Web UI,启动时输出Starting API server on port http://127.0.0.1:2703;gobackup run:执行备份但不进入守护模式,适合放在 systemd、supervisor 或容器前台。
Web UI 默认监听 http://127.0.0.1:2703。配置里的 web 段可以设 username / password,示例配置给的是 gobackup / 123456——这是示例默认值,实际部署必须改掉。
配置结构:model → databases / storages / archive
配置文件按以下顺序查找:
~/.gobackup/gobackup.yml/etc/gobackup/gobackup.yml
顶层是 models,每个 model 下分三块:databases(数据源)、storages(备份目标)、archive(要打进 tar 的路径)。storages 下可以用 default_storage 指定默认目标,多个目标可同时写,每个目标单独带自己的 keep。
最小结构,来自文档示例:
models:
gitlab_app:
databases:
gitlab_db:
type: postgresql
database: gitlab_production
username: gitlab
password:
gitlab_redis:
type: redis
mode: sync
rdb_path: /var/db/redis/dump.rdb
invoke_save: true
storages:
s3:
type: s3
bucket: my_app_backup
region: us-east-1
path: backups
access_key_id: $S3_ACCESS_KEY_ID
secret_access_key: $S3_SECRET_ACCESS_KEY
compress_with:
type: tgz
Redis 这种数据源的重点是 mode: sync:直接取 rdb_path 指向的 dump.rdb,invoke_save: true 表示备份前先触发一次 save,避免拿到旧快照。
压缩、加密、回收
compress_with 负责打包压缩,type: tgz 之外还能用 filename_format 控制文件名,走的是 Go 的时间格式:
compress_with:
filename_format: "2006.01.01.15.00.00"
type: tgz
encrypt_with 在压缩之后加密,示例用 openssl:
encrypt_with:
type: openssl
password: 123456
salt: false
openssl: true
回收靠每个 storage 自己的 keep。示例配置里 local 是 keep: 10,S3 是 keep: 20,FTP 是 keep: 15,SCP 也有独立的 keep: 10——同一个 model 推到多个目标时,各目标按自己的份数轮转。
调度与前后脚本
调度有两种写法:cron 表达式,或者 every + at 的自然语言式间隔。
models:
my_backup:
before_script: |
echo "Before script"
after_script: |
echo "After script"
schedule:
cron: "5 4 * * sun"
storages:
local:
type: local
path: /path/to/backups
databases:
mysql:
type: mysql
host: localhost
port: 3306
database: my_database
username: root
password: password
other_backup:
schedule:
every: "1day"
at: "04:05"
before_script / after_script 是多行 shell,直接写脚本内容,适合在备份前停写、刷盘,或备份后清理临时目录。every 也支持更短的间隔,示例里有一个 every: "30s" 的 model。
归档目录与文件
archive 段把目录和文件打成 tar,和数据库备份一起走同一套 storage:
archive:
includes:
- /home/ubuntu/.ssh/
- /etc/nginx/nginx.conf
- /etc/redis/redis.conf
- /etc/logrotate.d/
excludes:
- /home/ubuntu/.ssh/known_hosts
- /etc/logrotate.d/syslog
只备份单文件也可以,includes: [/etc/hosts] 即可。
环境变量
配置里的值支持取环境变量,两种写法等价:
expand_env:
storages:
s3:
type: s3
access_key_id: $S3_ACCESS_KEY_ID
secret_access_key: ${S3_SECRET_ACCESS_KEY}
凭证走环境变量而不是写死在 yaml 里,配合下面的文件权限处理。
热重载与退出
SIGHUP 热重载配置,SIGQUIT 优雅退出:
$ ps aux | grep gobackup
jason 20443 0.0 0.1 409232800 8912 ?? Ss 7:47PM 0:00.02 gobackup run
$ kill -HUP 20443 # 重新加载配置
$ kill -QUIT 20443 # 优雅退出
改完 yaml 不用重启进程,发 HUP 即可;正在跑的备份任务在 QUIT 时会走完再退出。
支持的数据源、存储与通知
数据库:MySQL、MariaDB、PostgreSQL、Redis、MongoDB、SQLite、Microsoft SQL Server、InfluxDB、etcd、Firebird。
存储(20 余种):Local、FTP、SFTP、SCP、Amazon S3、Aliyun OSS、Google Cloud Storage、Azure Blob Storage、Backblaze B2、Cloudflare R2、DigitalOcean Spaces、QCloud COS、UCloud US3、Qiniu Kodo、Baidu BOS、MinIO、Huawei OBS、Volcengine TOS、UpYun、WebDAV。
通知(1.5.0 起):Mail(SMTP)、Webhook、Discord、Slack、Feishu、DingTalk、GitHub(在 issue 上评论)、Telegram、AWS SES、Postmark、SendGrid。示例里 notifiers: 留空,说明按需配置。
一个大 model 的完整字段可以对照示例配置:web 下的账号密码、default_storage、多个 storage 各自 keep、compress_with + encrypt_with、多个 database、archive.includes/excludes,都可以放在同一个 model 里。
落地时的几个判断
1. keep 是按每个 storage 各算的。 同一个 model 同时推 S3 和本地时,S3 保留 20 份、本地保留 10 份,两边的份数和时间窗口并不一致。多目标备份要先把每边的保留策略对齐,否则清理时会出现「远端有、本地没有」的偏差。
2. 加密密码和 Web UI 密码都写在 yaml 里。 示例里的 password: 123456 只是占位。实际部署把配置文件权限收到 0600,并且不要把 yaml 提交进 git;能走环境变量的凭证(如 $S3_ACCESS_KEY_ID)就不要再写回文件。
3. Web UI 默认监听 127.0.0.1:2703。 远程访问要么别开,要么在 web 段加 username / password 并确认前面有反代或防火墙。把 2703 直接暴露到公网、又留着示例账号,等于把备份配置和触发入口一起交出去。
4. 备份能不能成功,取决于外部命令和通知链路。 mysqldump、pg_dump 这类工具必须装在 PATH 里,容器镜像里也要确认存在。cron 有没有触发不代表备份成功,要靠 notifier 或日志确认每次执行的结果,尤其是数据库导出失败但归档步骤仍然产出了文件的情况。
5. 它没有恢复流程和校验环节。 备份产物就是 dump、rdb 和 tar,恢复仍然要自己用对应工具还原。这决定了它适合「定时导出到对象存储」这类需求,不适合「可验证的灾难恢复」——后者需要恢复演练、校验和与恢复编排,这些不在 GoBackup 的范围内。