Dockerのデータをバックアップしたいのです(準備編)

どうも、やまもとやまです。
Dockerを利用している場合、データのバックアップってどうしたら良いでしょう?
定番的な方法では、コンテナを停止してイメージを取得、、みたいになると思いますが、日次のバックアップでそれはできないしな。。
ということで簡単に試してみます。

環境

Dockerのホストとして、AlmaLinux9を最小インストールした環境を想定しています。

とりあえずDockerを入れてみる

何はともあれDockerを導入しましょう。

# dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# dnf install docker-ce

Docker Composeも入れておきます。

# curl -SL https://github.com/docker/compose/releases/download/v2.35.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

ここまではおまじないのようなものですね。
ついでに特定の一般ユーザから実行できるようにしておきましょう。

# useradd yamamoto
# usermod -aG docker yamamoto

これでyamamotoユーザでもDocker操作が可能です。
ではDockerを起動します。

# systemctl start docker

WordPress環境を作ってみる

さてここからは一般ユーザ(yamamoto)で作業していきます。
バックアップする対象のサンプルとして、WordPressの動作する環境を作ってみましょう。
コンテナには公式レポジトリのmariadbおよびwordpressのイメージを利用します。
とりあえずlatest指定をしていますが、必要に応じたバージョン指定をしても良いですね。
MariaDBとApacheのデータ領域( /var/lib/mysql および /var/www/html )は、永続化できるようにvolumesでホスト側のディレクトリを指定します。

$ mkdir ~/wordpress
$ cd ~/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用のymlファイルを作成しました。
それぞれvolumesで外部領域を指定し、Webサーバー(wordperss)はホストのTCP8000ポートをコンテナのTCP80へマッピングしています。
環境変数で指定するパスワードはランダムなものを。
ではコンテナを起動してみましょう。

$ docker-compose up -d
[+] Running 32/32
 ? wordpress Pulled                                                  9.0s
   ? 61320b01ae5e Pull complete                                      1.9s
   ? b4ce612dc732 Pull complete                                      1.9s
   ? 093338982d92 Pull complete                                      3.9s
   ? 0c2a0ba9eb0c Pull complete                                      4.0s
   ? 442abaed7751 Pull complete                                      4.3s
   ? aa4e51934eef Pull complete                                      4.3s
   ? 924949db942b Pull complete                                      4.3s
   ? 153d2fb08c64 Pull complete                                      4.3s
   ? 26f17ce45149 Pull complete                                      4.3s
   ? 64a857ca8a6a Pull complete                                      4.6s
   ? 7443480a6bdb Pull complete                                      4.6s
   ? d4dfcfe68eba Pull complete                                      4.6s
   ? 91e76e37da73 Pull complete                                      4.6s
   ? 4f4fb700ef54 Pull complete                                      4.6s
   ? 79eaebcf6f91 Pull complete                                      5.1s
   ? 70a6388697d7 Pull complete                                      5.4s
   ? d33dc2ec72e5 Pull complete                                      5.4s
   ? 116f8f9c524a Pull complete                                      5.4s
   ? 8220bc2ecbd0 Pull complete                                      5.4s
   ? 2cc26c3ac19c Pull complete                                      6.1s
   ? f06097973e73 Pull complete                                      6.1s
   ? 369bf408b523 Pull complete                                      6.1s
 ? db Pulled                                                        11.9s
   ? 0622fac788ed Pull complete                                      7.1s
   ? 90dbf4535882 Pull complete                                      7.1s
   ? 95ed3e3fde04 Pull complete                                      7.3s
   ? 0b381eed6c88 Pull complete                                      7.3s
   ? d7547f36e497 Pull complete                                      7.3s
   ? a5e33262a388 Pull complete                                      9.1s
   ? 3984aae8ebb4 Pull complete                                      9.1s
   ? 9883ef72c7c9 Pull complete                                      9.1s
[+] Running 3/3
 ? Network wordpress_default        Created                          0.1s
 ? Container wordpress-db-1         Started                          0.2s
 ? Container wordpress-wordpress-1  Started                          0.3s

初回なのでイメージをレポジトリからpullしてきて、その後コンテナ2台が起動したようです。

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

wordpressとmariadbのコンテナが起動してますね。

$ ls -la
total 16
drwxr-xr-x 4 yamamoto         yamamoto   82 May 22 13:24 .
drwx------ 3 yamamoto         yamamoto  116 May 22 13:21 ..
drwxr-xr-x 6 systemd-coredump input    4096 May 22 13:25 db
-rw-r--r-- 1 yamamoto         yamamoto  560 May 22 13:21 docker-compose.yml
drwxr-xr-x 5               33 tape     4096 May 22 13:24 web

volumesで指定したディレクトリも作成され、データが永続化されています。
ホストとコンテナ内のIDの違いのためか変なユーザ名とグループ名になっていますが、とりあえずは気にしないでおきましょう、、
では、ブラウザからアクセスしてみます。

yamamoto30-dockerbackup001

http://ホストのIPアドレス:8000/ へアクセスすると、無事WordPressインストール画面が表示されました。
通常通りインストールしましょう。
ついでに記事も1つ作成しておきます。

yamamoto30-dockerbackup002
作成した記事のブラウザ表示も問題なさそうです。

$ ls -l web/wp-content/uploads/2025/05/
total 40
-rw-r--r-- 1 33 tape  3985 May 22 13:34 usagi-150x150.jpg
-rw-r--r-- 1 33 tape 10244 May 22 13:34 usagi-300x300.jpg
-rw-r--r-- 1 33 tape 24533 May 22 13:34 usagi.jpg

アップロードした画像もvolumes領域に保存されていますね。

ということで

今回は準備まで完了しました。
Docker環境を作成し、WordPressで記事の投稿ができるところまで確認しています。
次回はいよいよバックアップとリストアを試してみます。

それではまた!