SqlBak Blog

Backup MySQL Docker container

If your MySQL database is running in Docker, backing it up is no more complicated than backing up a database installed directly on the server. However, there are tips, tricks, and best practices that can simplify the process.

Backup the database, not the container

Although MySQL in Docker is ultimately just a program interacting with the disk, this does not mean you can create a reliable backup by simply copying the contents of the volume where the database stores its files. Directly copying database files while the database is running can lead to errors. If data, including system tables, is partially written, the database may fail to start after restore.

For this reason, you should use a specialized tool provided by the database vendor to create backups of your database.

Everything you need for a backup is already in the container

mysqldump is a utility for creating logical backups of MySQL databases. It generates a .sql dump file of the database. This utility is specifically designed for backup MySQL and is included as part of the MySQL server, which means it is already in the container.

This tool allows you to create hot backups, meaning there is no need to stop MySQL to perform the backup.

To restore a backup created this way, you simply execute the instructions in the dump file using the mysql utility, which is also included in the container.

Backup MySQL database in Docker container

The command for creating a backup:

docker exec <container-name> mysqldump -u<user> -p<password> --all-databases > mysql-backup.sql

This command creates a backup of all databases in the container and saves it as a file named mysql-backup.sql, which will appear in the host system directory where the command was executed:

  • <container-name>: the name of the container running the MySQL database
  • <user>: the username
  • <password>: the password for the user

Example of a MySQL backup command in Docker:

docker exec root_db_1 mysqldump -uroot -ppassword --all-databases > backup.sql

Restore MySQL database in Docker container

The general command to restore a backup is as follows:

 docker exec <container-name> mysql -u<user> -p<password> < mysql-backup.sql

The same parameters should be used as in the backup command.

Example of a MySQL restore command in Docker:

docker exec root_db_1 mysql -uroot -ppassword < backup.sql

How to improve this backup

A single backup is good, but there might be situations where you accidentally back up a broken database. For example, you might delete an important table by mistake and not notice it immediately, and during that time, a backup of the damaged database is created. In such cases, you won’t be able to restore the correct data.

To avoid this, it’s recommended to create backups regularly and retain them for a certain period. For instance, you could schedule daily backups and keep them for a week.

MySQL backup in a container with compression and a filename including the current date

To save space, it’s a good idea to compress backups. This can be done during the creation of the backup. Adding the current date to the backup filename ensures that a new file is created each time instead of overwriting the existing one.

Linux

Here’s an example of the command:

docker exec mysql_container mysqldump -uroot -ppassword --all-databases | gzip > backup_$(date +%Y-%m-%d).sql.gz

You can restore this backup using the following command:

 gunzip < backup_2024-12-08.sql.gz | docker exec -i mysql_container mysql -uroot -ppassword

Widows (powershell)

On Windows, it’s more convenient to use the 7-Zip archiver from the command line. Install it using the following command:

winget install --id=7zip.7zip -e

Now you can back up all databases in the container using the following command:

docker exec mysql_container mysqldump -u root -pmy-secret-pw --all-databases | & 'C:\Program Files\7-Zip\7z.exe' a -si "backup_$(Get-Date -Format 'yyyy-MM-dd').sql.7z"

You can restore the backup using the following command:

& 'C:\Program Files\7-Zip\7z.exe' e -so "backup_2024-12-08.sql.7z" | docker exec -i mysql_container mysql -u root -pmy-secret-p

Simple daily backups with Docker-Compose

Using Docker-Compose for automating backups is a truly convenient solution. It not only centralizes the configuration but also makes it easy to transfer settings to another server. Here’s how you can set up regular MySQL backups using Docker-Compose.

In this example, an additional MySQL container is created, which performs backups of the primary database via a health check and deletes backups older than 7 days:

version: '3.8'

services:
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - ./data:/var/lib/mysql

  mysql-backup:
    image: mysql
    depends_on:
      - db
    volumes:
      - ./backups:/backup
    entrypoint: ["sh", "-c", "sleep infinity"]
    healthcheck:
      test:
        - "CMD-SHELL"
        - >
          export MYSQL_PWD=password &&
          DUMP_FILE=/backup/backup_$$(date +%F_%H-%M-%S).sql &&
          ERROR_LOG=/backup/error.log &&
          mysqldump -h db -u root --all-databases > $$DUMP_FILE 2>> $$ERROR_LOG &&
          find /backup -type f -name "backup_*.sql" -mmin +7 -exec rm -f {} \;
      interval: 24h
      timeout: 5h
      retries: 1

Unfortunately, it is not possible to set the start time for the healthcheck service. The first backup will be performed 24 hours after the mysql-backup container starts.

Start the mysql-backup container after adding it to docker-compose.ym (there is no need to restart all services):

 docker-compose start mysql-backup

SqlBak

SqlBak is a agent-based service for database backups that allows you to back up a database and upload it to the cloud. It supports sending backups to Local Disk, network directories, FTP, SFTP, FTPS, NAS, local or network folders, Google Drive, Dropbox, OneDrive, Box, Amazon S3 (and any S3-Compatible storage), Azure Storage, Backblaze B2, Yandex.Disk, and also enables restoring them with just a few clicks.

To connect SqlBak to a MySQL database, you can simply add it to your docker-compose.yml file. Don’t forget to specify the secret key, which you can find on the Download page after registration.

version: '3.3'
services:
 db_mysql:
  image: mysql
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: example
  networks:
   - overlay
 sqlbak:
  image: pranasnet/sqlbak
  volumes:
   - sqlbak_local_data:/opt/sqlbak
   - backup_folder:/tmp/sqlbak
  environment:
   sqlbak_key: [secret-key]
   sqlbak_name: sqlbak_agent
   db_type: mysql
   user: root
   password: example
   host: db_mysql
  networks:
   - overlay
volumes:
 sqlbak_local_data:
 backup_folder:
networks:
 overlay:

After adding SqlBak to the docker-compose.yml file, start it:

 docker-compose start sqlbak

After that, you can configure the backup on the website sqlbak.com.

1. Open the Dashboard page and click on the Add new job button to create a new backup job:Create new backup job SqlBak

2. At the opened window, please choose the databases you are going to backup:
Choose the databases in backup job SqlBak

3. The next step is to set the destinations where the backups will be stored, for example, a local folder and Google Drive:
Select backup destinations SqlBak

4. Now you can set a schedule when a backup job should be run:
Schedule backup SqlBak

5. And the last setting from the minimum set is the notification setting:
Email notifications SqlBak

That’s all, to run the backups according to the schedule you need to save the settings by clicking the Save & Exit button at the top of the page:

Save backup job SqlBak

Restore

The backups can be easily restored by clicking the “restore” icon on your backup job’s settings page. Just choose a backup you need to restore, click the “restore” icon and follow the instructions. If it is a full or incremental backup, all the needed backups will be restored automatically:

Backup job history SqlBak

Also, the very last backup can be restored from your “Dashboard” page, just click the “restore” icon at the “LAST RUN” column:

Restore backup SqlBak

About cold backups

The methods described above allow for a hot backup of MySQL, meaning you don’t need to shut down the database to create the backup.

A cold backup, on the other hand, involves backup the database while it is stopped. With the database turned off, you can safely copy the volume containing the data. This method has its advantages and disadvantages:

Advantages

  • Cold backup faster

Disadvantages

  • Requires shutting down the database
  • Access to the server’s file system is necessary
  • The backup can only be restored on the same version of MySQL

To perform a cold backup, start by stopping the container:

docker stop <container-name>

and copy the volume:

docker cp <container-name>:/var/lib/mysql /path/to/backup

Cold backups are typically considered a bad practice and are included in this article for informational purposes. However, there are scenarios where cold backups might be preferable. For instance, if you are using the ZFS file system, you can instantly create snapshots of files, making cold backups a viable option.

Conclusion

Backup isn’t just an extra task; it’s about peace of mind. Automate your backups, avoid storing them on the same server where the container resides, periodically test the restore process, and may luck always be on your side.🙂

Leave a Comment