Self-hosted service
databacker/mysql-backup avatar
databacker/mysql-backup

mysql-backup: scheduled MySQL dumps and restores from a container or a single binary

image to enable automated backups of mysql databases in containers

761 stars208 forksGoLicense varies

At a glance

What is it?
mysql-backup runs as a container image or a standalone binary, dumps MySQL databases on a cron-style schedule to local files, SMB shares or S3, and restores them the same way. It is a Go rewrite published by Databacker whose configuration is environment-variable driven, which makes it easy to compose in Docker and easy to misconfigure.
Who is it for?
mysql-backup is a reasonable choice for teams that already run MySQL in containers and want a scheduled dump with retention pruning, a restore path that reuses the same target abstraction, and a single binary they can run from cron without orchestrating a sidecar.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 23 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A backup tool that runs where the database already runs

mysql-backup is described as an image to enable automated backups of MySQL databases in containers, and the README presents it as a simple way to do MySQL database backups and restores as well as manage backups. The audience is anyone running MySQL in containers who wants a scheduled dump without assembling a bespoke sidecar, and the README lists the feature set concretely: dump and restore, dump to supported targets, selecting the database user and password, connecting to any container running on the same system, choosing how often to run a dump, choosing when to start the first dump either by time of day or relative to container start time, and pruning backups older than a specific time period or quantity. That last item matters more than it first appears, because a backup job with no retention rule is a disk incident waiting to happen. The project also states that this is the latest version, based on a complete rebuild of the codebase in Go completed in late 2023 for the 1.0.0 release, which explains why the current command syntax differs from older documentation you may find elsewhere.

The same run, three ways: container, binary, or config file

The design choice that defines this tool is that one configuration surface is expressed in three interchangeable forms: environment variables for the container, command-line flags for the binary, and a YAML file for either. The README's backup example shows the container and binary side by side:

bash
docker run -d --restart=always -e DB_DUMP_FREQUENCY=60 -e DB_DUMP_BEGIN=2330Z -e DB_DUMP_TARGET=/local/file/path -e DB_SERVER=my-db-address -v /local/file/path:/db databack/mysql-backup dump

# or

mysql-backup dump --frequency=60 --begin=2330Z --target=/local/file/path --server=my-db-address

# or to connect to a local mysqld via the unix domain socket as the current user

mysql-backup dump --frequency=60 --begin=2330Z --target=/local/file/path --server=/run/mysqld/mysqld.sock

A configuration file is a third option, invoked with the --config-file flag pointing at a YAML document:

yaml
server: my-db-address
dump:
  frequency: 60
  begin: 2330
  target: /local/file/path

One subtlety is worth flagging before you copy that YAML. The README states that the command and environment-variable examples run a dump every 60 minutes beginning at the next 23:30 local time, while the config-file example uses the legacy zoneless form, which is interpreted as UTC. A silent shift from local time to UTC is the kind of detail that makes a first backup land at the wrong hour and look like a missing run.

Credentials and ports belong in a file, not in the shell history

Adding a user and a password works the same way in both forms, with the flags and variables mirroring each other:

bash
docker run -d --restart=always -e DB_USER=user123 -e DB_PASS=pass123 -e DB_DUMP_FREQUENCY=60 -e DB_DUMP_BEGIN=2330Z -e DB_DUMP_TARGET=/db -e DB_SERVER=my-db-address -v /local/file/path:/db databack/mysql-backup dump

# or

mysql-backup dump --user=user123 --pass=pass123 --frequency=60 --begin=2330Z --target=/local/file/path --server=my-db-address --port=3306

The port appears only in the binary form here because the container example omits it, and the documentation lists DB_PORT as optional with a default of 3306. The README also points at the --env-file option of docker run, with an explicit note that you should consider it to keep secrets out of your shell history. That advice extends beyond convenience. A backup process that runs as a long-lived container holds the database password in its environment, which means any process that can read the container configuration can read the credential. The image itself was built with that in mind: the Dockerfile creates a non-root user with a fixed uid and gid of 1005, switches to it with a USER instruction, and copies in only the compiled binary and the entrypoint script.

Restores reuse the target abstraction, with a subset option

Restore is the same command with the verb changed, and the README is explicit that you connect to a database in the same way, pass the restore command instead of dump, and pass a restore target instead of a dump target. The environment variables for a restore include DB_SERVER as a hostname or a unix domain socket path starting with a slash, DB_PORT, DB_USER, DB_PASS, DB_RESTORE_TARGET pointing at a compressed dump file, and DB_DEBUG for copious output in the container logs. Two flags handle multi-schema databases. DB_DUMP_INCLUDE takes space-separated database names and is required if SINGLE_DATABASE is true, in which case it must contain exactly one database name and the MySQL command runs with the --database flag, which avoids needing a USE statement and is useful when restoring a file saved with SINGLE_DATABASE set to true. When restoring with DB_DUMP_INCLUDE, schemas keep their original names; to restore under other names you need SINGLE_DATABASE on both the dump and the restore, one schema at a time. The README gives concrete restore invocations, including one from a local file with SSL client certificates, one from an SMB share and one from S3.

Where the backup actually goes

The target is an abstraction rather than a fixed directory, and the restore examples make the supported shapes explicit. A local file is addressed with DB_RESTORE_TARGET as an absolute path inside the container, with the host directory bind-mounted to match. An SMB share is given as a smb:// scheme pointing at a server and share. An S3 object is given as an s3:// bucket and path, and for the S3 driver the README says AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION will need to be defined. The module file corroborates the scope of that list: the Go dependencies include the AWS SDK v2 with its S3 service and manager packages, github.com/cloudsoda/go-smb2 for SMB, and the usual suspects for the rest of the plumbing such as robfig/cron for scheduling, spf13/cobra and viper for the command line and configuration, and sirupsen/logrus for logging. The go.mod file also pulls in otel packages for tracing, plus age, scp, sftp and ssh libraries, and the Docker build target covers linux/amd64 and linux/arm64 while the local build targets include darwin, windows and 386 variants.

A container image built for hooks and non-root execution

The Dockerfile in the repository root says more about the intended operational shape than the feature list does. The build stage uses a pinned Go version on an Alpine base and produces a single binary, and the runtime stage is a separate Alpine image that adds bash and tzdata, with a comment in the file explaining that a from-scratch base was not used because basic utilities are needed to support pre and post scripts. Four environment variables are baked in as defaults for those hook directories: DB_DUMP_PRE_BACKUP_SCRIPTS, DB_DUMP_POST_BACKUP_SCRIPTS, DB_DUMP_PRE_RESTORE_SCRIPTS and DB_DUMP_POST_RESTORE_SCRIPTS, each pointing at a path under /scripts.d/. The repository layout backs this up, with a scripts.d directory at the top level and an entrypoint file. The scripts.d hooks are the mechanism for adding steps around a dump or a restore, such as compression or a copy to a second location, and the presence of an examples directory with configs and a docker-compose.yaml gives you a starting composition to adapt.

Testing, releases and the state of the project

The Makefile shows how the project is built and verified. Unit tests run with go test -v ./..., and an integration target runs the same test tree with TEST_INTEGRATION=true and a twenty minute timeout, which is consistent with the test suite starting MySQL containers tagged with a mysqltest label, since there are clean-test-stop and clean-test-remove targets that find and kill or remove containers by that label. A vet target runs go vet with the integration build tag, and the image build uses docker buildx with explicit platform flags. On releases, the project publishes v1.5.0 on 2026-06-29, v1.4.0 on 2026-05-11 and v1.3.0 on 2025-08-13, and the last push to the repository was on 2026-09-30. Support is offered through a Slack channel and the maintainers state that commercial support is available by contact. No licence identifier is recorded for the repository, which is a point to resolve directly with the maintainers if you intend to run this inside a commercial data pipeline.

Editorial conclusion

mysql-backup is a reasonable choice for teams that already run MySQL in containers and want a scheduled dump with retention pruning, a restore path that reuses the same target abstraction, and a single binary they can run from cron without orchestrating a sidecar. It is the wrong tool for a database that needs physical backup, point-in-time recovery or verified restores, since the documented workflow is logical dumping to a compressed file, and it is the wrong tool if you cannot accept environment-variable configuration, because the container form passes credentials and schedule through DB_SERVER, DB_USER, DB_PASS and the DB_DUMP_ variables, which is exactly where mistakes tend to hide. Verify first that the target path you intend is writable from the container, that your chosen frequency value is one the scheduler accepts, and that your retention settings match the backup window you actually need before you point it at a production server.

Frequently asked questions

How do I run a mysql-backup dump every 60 minutes?

Run the container with DB_DUMP_FREQUENCY=60, DB_DUMP_BEGIN=2330Z, DB_DUMP_TARGET and DB_SERVER set, or run the binary with the equivalent flags --frequency=60 --begin=2330Z --target and --server. The README states these examples begin at the next 23:30 local time.

How do I restore only some databases from a multi-schema backup?

Use DB_DUMP_INCLUDE with space-separated database names on the restore. The schemas are restored with their original names, and renaming requires SINGLE_DATABASE=true on both the dump and the restore, one schema at a time.

Which backup targets does mysql-backup support?

The README shows restores from a local file, an SMB share addressed as smb://server/share, and an S3 object addressed as s3://bucket/path. For the S3 driver, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION need to be defined.

Can mysql-backup connect to a local MySQL through a unix socket?

Yes. The DB_SERVER value accepts a unix domain socket path starting with a slash, and the README shows an example using --server=/run/mysqld/mysqld.sock to reach a local mysqld as the current user.

How do I run scripts before or after a dump or restore?

The container image defines four script directories through environment variables: DB_DUMP_PRE_BACKUP_SCRIPTS, DB_DUMP_POST_BACKUP_SCRIPTS, DB_DUMP_PRE_RESTORE_SCRIPTS and DB_DUMP_POST_RESTORE_SCRIPTS, pointing under /scripts.d/. The runtime image includes bash and tzdata to support these scripts.

Official sources

  1. databacker/mysql-backup on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/databacker-mysql-backup.svg)](https://hysenlabs.com/projects/databacker-mysql-backup)

Was this useful?