MySQLのDockerコンテナ上のデータベースをバックアップする

目的

MySQLコンテナのデータベースファイルをホスト側にバックアップしたい

背景

Dockerだけで管理しているとうっかりコンテナやボリュームの削除なんてのもありうるのでDockerからも隔離された場所に完全なバックアップを作りたい

解決策

MySQL Dockerの公式ドキュメントを参考にbashを書く
取り出す方法は色々あるが、安全、確実を優先しmysqldumpコマンドを採用することにした

#!/bin/bash
MYSQL_ROOT_PASSWORD='HOGEHOGEPASSWORD'

if [ -z "$CONTAINER_ID" ]; then
  echo '$CONTAINE_ID is empty. ex. CONTAINER_ID=abc123...'
  exit 1
fi

if [ -z "$OUTPUT_FILE" ]; then
  echo '$OUTPUT_FILE is empty. ex. OUTPUT_FILE=/home/path/bk.sql'
  exit 1
fi

docker exec ${CONTAINER_ID} sh -c 'exec mysqldump --all-databases --lock-all-tables -uroot -p"$MYSQL_ROOT_PASSWORD"' > ${OUTPUT_FILE}

定期実行

このスクリプトだけでは定期的にバックアップはしてくれないので、ホスト側のcron等で定期実行するようにする必要がある

下記は未検証だが、上記のスクリプトを仮に~/local/script/docker.mysql.backup.shとしているのなら、AM5:00にバックアップする場合は恐らくこんな感じになるはず

crontab -e
0 5 * * * CONTAINER_ID=ABCDEF123 OUTPUT_FILE=~/local/backup/mysql.sql ~/local/script/docker.mysql.backup.sh

課題

  • このままだと生パスワードを埋め込んでるので恐らく警告が表示される
  • コンテナIDが見つからない場合の処理が必要
  • コンテナごとまたは差分をdumpして別の場所に退避するのもありかもしれない
  • ロックするのでdump中はサービスは停止してしまう(--single-transactionオプションで回避可能ではあるが適用できるかは別の話)