Dockerのデータをバックアップしたいのです(実践編その2)

どうも、やまもとやまです。
前回の記事では、Dockerのイメージを利用したバックアップとリストアを試してみました。
イメージのみで完結する場合は良いのですが、データ領域がホスト側にマウントされている場合は利用しづらかったため、今回は別方法で試してみます。

環境

Dockerのホストとして、AlmaLinux9を最小インストールした環境を想定しています。
また構築した環境とは別に、AlmaLinux9を最小インストールしたリストア用環境も用意します。

ファイルベースでのバックアップ

ファイルベースでのバックアップを行います。
具体的には、Webサーバー(wordpress)側は外部ボリューム領域のコンテンツデータを保管します。
また、DBサーバー(mariadb)側はデータベースのダンプを取得します。
早速前々回構築したWordPressで、コンテンツをtarで保存しましょう。
今回はパーミッションも考慮して、root権限で作業することにします。

# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED       STATUS         PORTS                                     NAMES
68593745090e   wordpress:latest   "docker-entrypoint.s…"   5 weeks ago   Up 5 seconds   0.0.0.0:8000->80/tcp, [::]:8000->80/tcp   wordpress-wordpress-1
ebe5ff2ff8cc   mariadb:latest     "docker-entrypoint.s…"   5 weeks ago   Up 2 seconds   3306/tcp                                  wordpress-db-1

# cd /home/yamamoto/wordpress
# ls -l
drwxr-xr-x 6 systemd-coredump input         4096 Jun 26 13:26 db
-rw-r--r-- 1 yamamoto         yamamoto       560 May 22 13:21 docker-compose.yml
-rw-r--r-- 1 yamamoto         yamamoto        38 May 26 17:01 Dockerfile
drwxr-xr-x 5               33 tape          4096 Jun 26 13:26 web

# tar czf web-backup.tgz web
# ls -l
drwxr-xr-x 6 systemd-coredump input         4096 Jun 26 13:26 db
-rw-r--r-- 1 yamamoto         yamamoto       560 May 22 13:21 docker-compose.yml
-rw-r--r-- 1 yamamoto         yamamoto        38 May 26 17:01 Dockerfile
drwxr-xr-x 5               33 tape          4096 Jun 26 13:26 web
-rw-r--r-- 1 root             root      28133250 Jun 26 13:31 web-backup.tgz

保存できました。
続いてDBのダンプを取得します。
MariaDBのrootパスワード直書きですがとりあえずは気にしない気にしない、、

# docker-compose -f /home/yamamoto/wordpress/docker-compose.yml exec db mariadb-dump --all-databases -uroot -poRom6tsa}4R^ > db-backup.sql

# ls -l
drwxr-xr-x 6 systemd-coredump input         4096 Jun 26 13:26 db
-rw-r--r-- 1 root             root       3332283 Jun 26 13:48 db-backup.sql
-rw-r--r-- 1 yamamoto         yamamoto       560 May 22 13:21 docker-compose.yml
-rw-r--r-- 1 yamamoto         yamamoto        38 May 26 17:01 Dockerfile
drwxr-xr-x 5               33 tape          4096 Jun 26 13:26 web
-rw-r--r-- 1 root             root      28133250 Jun 26 13:31 web-backup.tgz

# head -20 db-backup.sql
/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19-11.7.2-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost    Database:
-- ------------------------------------------------------
-- Server version       11.7.2-MariaDB-ubu2404

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;

--
-- Current Database: `mysql`

正常にダンプできていそうです。
保存した2つのファイルはリストア用サーバーへ転送します。

ファイルおよびダンプデータからのリストア

ここからはリストア用サーバーでの作業になります。
こちらもroot権限で作業をします。
初期状態ではコンテナが存在しない状態とします。

# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

何もないですね。
では移行元サーバーと同じymlファイルを作成しましょう。
※本来はこれもバックアップしておくべきですね

# cd /home/yamamoto/wordpress
# vi docker-compose.yml
----------------------------------------------------------------------services:
   db:
     image: mariadb:latest
     volumes:
       - ./db:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: oRom6tsa}4R^
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wpadmin
       MYSQL_PASSWORD: 1{UFgh@bfmw4

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     volumes:
       - ./web:/var/www/html
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wpadmin
       WORDPRESS_DB_PASSWORD: 1{UFgh@bfmw4
----------------------------------------------------------------------

それでは起動します。

# docker-compose up -d
# docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                     NAMES
1671eaaf7d4c   wordpress:latest   "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   0.0.0.0:8000->80/tcp, [::]:8000->80/tcp   wordpress-wordpress-1
d2ea8b25fa09   mariadb:latest     "docker-entrypoint.s…"   8 seconds ago   Up 8 seconds   3306/tcp                                  wordpress-db-1

正常に起動しました。

# ls -l
drwxr-xr-x 6 systemd-coredump systemd-coredump     4096 Jun 26 15:31 db
-rw-r--r-- 1 root             root              3332283 Jun 26 15:27 db-backup.sql
-rw-r--r-- 1 yamamoto         yamamoto              560 Jun 26 15:30 docker-compose.yml
drwxr-xr-x 5               33 tape                 4096 Jun 26 15:31 web
-rw-r--r-- 1 root             root             28133250 Jun 26 15:26 web-backup.tgz

永続化用のディレクトリもできていますね。
ではリストアしましょう。
まずはコンテンツから。

# ls -la web
drwxr-xr-x  5       33 tape      4096 Jun 26 15:31 .
drwxr-xr-x  5 yamamoto yamamoto   107 Jun 26 15:32 ..
-rw-r--r--  1       33 tape       261 Jun 26 04:57 .htaccess
-rw-r--r--  1       33 tape       405 Feb  6  2020 index.php
-rw-r--r--  1       33 tape     19903 Mar  6 23:24 license.txt
-rw-r--r--  1       33 tape      7425 Mar  7 17:45 readme.html
-rw-r--r--  1       33 tape      7387 Feb 13  2024 wp-activate.php
drwxr-xr-x  9       33 tape      4096 May  1 01:41 wp-admin
-rw-r--r--  1       33 tape       351 Feb  6  2020 wp-blog-header.php
-rw-r--r--  1       33 tape      2323 Jun 14  2023 wp-comments-post.php
-rw-r--r--  1       33 tape      5815 Jun 26 04:56 wp-config-docker.php
-rw-r--r--  1       33 tape      5919 Jun 26 15:31 wp-config.php
-rw-r--r--  1       33 tape      3336 Oct 16  2024 wp-config-sample.php
drwxr-xr-x  4       33 tape        52 Apr 15 08:37 wp-content
-rw-r--r--  1       33 tape      5617 Aug  3  2024 wp-cron.php
drwxr-xr-x 30       33 tape     12288 May  1 01:41 wp-includes
-rw-r--r--  1       33 tape      2502 Nov 27  2022 wp-links-opml.php
-rw-r--r--  1       33 tape      3937 Mar 11  2024 wp-load.php
-rw-r--r--  1       33 tape     51414 Feb  4 01:55 wp-login.php
-rw-r--r--  1       33 tape      8727 Feb  9 01:00 wp-mail.php
-rw-r--r--  1       33 tape     30081 Mar  4 22:06 wp-settings.php
-rw-r--r--  1       33 tape     34516 Mar 11 03:16 wp-signup.php
-rw-r--r--  1       33 tape      5102 Oct 19  2024 wp-trackback.php
-rw-r--r--  1       33 tape      3205 Nov  9  2024 xmlrpc.php

# tar xzf web-backup.tgz

# ls -l web
drwxr-xr-x  5       33 tape      4096 Jun 26 13:26 .
drwxr-xr-x  5 yamamoto yamamoto   107 Jun 26 15:32 ..
-rw-r--r--  1       33 tape       598 May 22 13:31 .htaccess
-rw-r--r--  1       33 tape       405 Feb  6  2020 index.php
-rw-r--r--  1       33 tape     19903 Mar  6 23:24 license.txt
-rw-r--r--  1       33 tape      7425 Mar  7 17:45 readme.html
-rw-r--r--  1       33 tape      7387 Feb 13  2024 wp-activate.php
drwxr-xr-x  9       33 tape      4096 May  1 01:41 wp-admin
-rw-r--r--  1       33 tape       351 Feb  6  2020 wp-blog-header.php
-rw-r--r--  1       33 tape      2323 Jun 14  2023 wp-comments-post.php
-rw-r--r--  1       33 tape      5815 May 22 08:36 wp-config-docker.php
-rw-r--r--  1       33 tape      5919 May 22 13:24 wp-config.php
-rw-r--r--  1       33 tape      3336 Oct 16  2024 wp-config-sample.php
drwxr-xr-x  7       33 tape        99 Jun 26 13:26 wp-content
-rw-r--r--  1       33 tape      5617 Aug  3  2024 wp-cron.php
drwxr-xr-x 30       33 tape     12288 May  1 01:41 wp-includes
-rw-r--r--  1       33 tape      2502 Nov 27  2022 wp-links-opml.php
-rw-r--r--  1       33 tape      3937 Mar 11  2024 wp-load.php
-rw-r--r--  1       33 tape     51414 Feb  4 01:55 wp-login.php
-rw-r--r--  1       33 tape      8727 Feb  9 01:00 wp-mail.php
-rw-r--r--  1       33 tape     30081 Mar  4 22:06 wp-settings.php
-rw-r--r--  1       33 tape     34516 Mar 11 03:16 wp-signup.php
-rw-r--r--  1       33 tape      5102 Oct 19  2024 wp-trackback.php
-rw-r--r--  1       33 tape      3205 Nov  9  2024 xmlrpc.php

バックアップしておいたファイルが展開されました。
実際にリストアする場合は、中身を削除してから展開しなければ不要な差分が発生する可能性があるのでご注意を。

続いてデータベースをリストアします。

# cp db-backup.sql db/
# docker-compose -f /home/yamamoto/wordpress/docker-compose.yml exec db bash -c 'mariadb -uroot -poRom6tsa}4R^ < /var/lib/mysql/db-backup.sql'
# docker-compose -f /home/yamamoto/wordpress/docker-compose.yml exec db bash -c "mariadb -uroot -poRom6tsa}4R^ -e 'flush privileges;'"
# rm db/db-backup.sql

一時的にDBの永続化領域にダンプファイルをコピーしてからリストアしています。
権限のflushもお忘れなく。
さてさて、リストアも無事完了しました。ブラウザからアクセスしてみます。

yamamoto30-dockerbackup003

表示されました!
前回同様、画像が表示されないのはパスのせい(旧サーバーIPアドレスがホストになっている)なので、WordPress設定でURLを修正すればOKです。

リストアできた!ばんざい!

というわけで、今度こそ想定通りにバックアップおよびリストアができました。
手順はもう少しブラッシュアップした方が良いと思いますが、停止等も不要で、障害時に備えた定期バックアップが可能です。
もちろん、複雑な環境になれば対象データ等の精査も必要になるでしょうが、全データ消失のようなリスクも減り安心ですね。

それではまた!