How to back up MySQL in Docker with mysqldump and restic
Back up a live Docker MySQL database without copying its active volume, then verify the encrypted dump in an isolated database.
Why a live MySQL volume copy is unsafe
A Docker volume contains MySQL's live data files. Copying that volume while MySQL is writing can capture files from different moments and leave you with a backup that will not start cleanly. A logical dump asks MySQL to export schema and rows in a form the mysql client can load later.
For an InnoDB application database, mysqldump with --single-transaction is a sensible baseline. It opens a consistent read without holding table locks for the entire export. That guarantee does not extend to MyISAM or MEMORY tables, and schema changes such as ALTER TABLE or TRUNCATE TABLE can still invalidate a dump in progress.
Run mysqldump inside the MySQL container
Run mysqldump through a dedicated database account and write the result outside the container's writable layer. The job must protect the credential, reject overlapping runs, detect a non-zero exporter status, and keep a partial file from replacing the last known-good dump.
The exact flags depend on the schema. Transactional consistency, routines, events, triggers, and non-transactional tables all change what a complete export means. Treat the dump definition as production configuration rather than a command copied from a generic tutorial.
Credential handling is also part of the design. MySQL explicitly warns against casual use of environment passwords, while command-line passwords can be visible to process inspection. Use the secret mechanism already trusted on the host and include privileged host access in the threat model.
Check the limits before scheduling it
Keep schema migrations out of the dump window. --single-transaction protects a consistent view of transactional rows, but it cannot make non-transactional tables consistent and it does not isolate the export from DDL. On a large database, the long-running read can also retain old row versions and add I/O load.
A SQL dump gives you the state at the time of that run. It does not provide point-in-time recovery between dumps. If the recovery point objective is shorter than the schedule interval, retain and protect MySQL binary logs or use a physical backup system that supports roll-forward recovery.
- Fail the job if mysqldump exits non-zero or the output file is empty.
- Watch dump size and duration; a sudden drop often exposes a wrong database name or missing privileges.
- Use a client version compatible with the server and test again after a MySQL or MariaDB upgrade.
- Do not assume MySQL and MariaDB dump options behave identically across releases.
Encrypt the SQL dump and move it off the host
The SQL file is readable database content, so leaving it beside the Docker volume only changes the failure mode. Restic encrypts repository contents before upload and creates a snapshot that can be copied to S3-compatible or other supported storage.
Use a repository password file with restrictive permissions for automation. Keep a recoverable copy of that password away from both the database host and the storage account. The repository is unusable without it.
Restore into a scratch database and verify the result
Do not use the production database as the first restore target. Create a separate database, load the SQL there, and check application-specific facts such as a known migration, a representative row count, and whether routines or events were recreated.
Select an exact recovery point rather than assuming the newest repository snapshot belongs to this database. Restore into a newly named scratch database, validate application-specific facts, and make production replacement a separate reviewed decision.
Where Rested removes the operational work
Rested turns the moving parts into a managed backup recipe: scheduling, protected credentials, dump capture, encryption, off-site storage, retention, run history, failure visibility, and guided recovery. You choose the database scope and storage; the agent performs the repeatable work on the server.
Logical backups are still not point-in-time recovery. Workloads that require binary-log replay, special object coverage, or a tightly bounded recovery time need those requirements documented alongside the Rested setup.
Technical basis
First-party references
Technical claims and limitations in this guide were checked against these primary sources. Confirm version-specific behavior when designing a production recovery process.
Related from Rested
Common questions
Frequently asked questions
Can mysqldump back up MySQL while it is running?
Yes. For InnoDB tables, --single-transaction creates a consistent read without locking tables for the whole dump. Avoid schema changes during the run, and remember that non-transactional tables do not receive the same consistency guarantee.
Should I back up the Docker volume as well?
A logical dump is the portable recovery artifact for this workflow. A volume copy can be useful only when it is made with a database-aware physical backup or a properly coordinated snapshot. Do not copy live MySQL files and assume they are consistent.
Does mysqldump include users and grants?
A single application-database dump does not reproduce every server-level account and grant. An --all-databases dump includes the mysql system database, but restoring it is much broader and version-sensitive. Document users and privileges and test the exact recovery path you intend to use.
Is a mysqldump plus restic enough for point-in-time recovery?
No. It restores to the time of the selected dump. Point-in-time recovery also requires a suitable full backup plus retained binary logs and a tested roll-forward procedure.