Loading...

2024-05-22(水) 15:00

🐳 動いているDocker Composeによるコンテナのデータをバックアップしてバインド先を変更する

docker
Docker Composeを使って動いているコンテナ内のデータをホストマシンのローカルにバックアップし、コンテナのボリュームのバインド先を変更する手順を解説します。

目次

前提と注意点

この記事では以下を前提としています。

  • Docker Compose 環境が構築済みであること
  • この記事では、Paperless ngx というオープンソースのドキュメント管理システムを例にしていますので、それぞれが動かしているコンテナに合わせて置き換えてください。

状況としては、以下の内容のdocker-compose.ymlを使ってコンテナを動かしていました。

docker-compose.yml
version: '3.4'
services:
  broker:
    image: docker.io/library/redis:7
    restart: unless-stopped
    volumes:
      - /redisdata:/data
 
  db:
    image: docker.io/library/postgres:15
    restart: unless-stopped
    volumes:
      - /pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless
 
  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - '8001:8000'
    volumes:
      - /data:/usr/src/paperless/data
      - /media:/usr/src/paperless/media
      - /export:/usr/src/paperless/export
      - /consume:/usr/src/paperless/consume
    env_file: docker-compose.env
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
 
volumes:
  data:
  media:
  pgdata:
  redisdata:

ただ上記だと、ボリュームのバインド先がホストマシンのルート直下である/redisdata/pgdata/data/media/export/consumeになっており、Docker Compose を起動したユーザーの権限によってはこれらディレクトリを作成できず、ホストマシン側にバインド先が作られない場合があります。そしてこの場合はコンテナを停止するとコンテナ内のデータも消えてしまいます。

この記事のゴール

この記事では、以下をゴールとします。

  • Docker Compose で動かしているコンテナのデータをホストマシンにバックアップする
  • Docker Compose で動かしているコンテナのボリュームのバインド先を変更する

コンテナ名を調べる

まず、Docker Compose で動かしているコンテナの名前を調べます。コンテナ名を指定して後ほどコンテナ内のデータをバックアップします。 以下を実行し、コンテナ名を取得します。

docker psコマンドを使ってコンテナ情報を取得する
$ sudo docker ps
CONTAINER ID   IMAGE                                                COMMAND                    CREATED         STATUS                  PORTS                                                                                                      NAMES
9ccfcb25f38d   ghcr.io/paperless-ngx/paperless-ngx:latest           "/sbin/docker-entryp…"    2 days ago      Up 2 days (healthy)     0.0.0.0:8001->8000/tcp, :::8001->8000/tcp                                                                  paperless-compose-webserver-1
868f5df6f38e   redis:7                                              "docker-entrypoint.s…"    2 days ago      Up 2 days               6379/tcp                                                                                                   paperless-compose-broker-1
907e6df733a9   postgres:15                                          "docker-entrypoint.s…"    2 days ago      Up 2 days               5432/tcp                                                                                                   paperless-compose-db-1

上記から、一番最後の列のNAMESに該当するpaperless-compose-webserver-1paperless-compose-broker-1paperless-compose-db-1 がコンテナ名として取得できました。 これらコンテナ名を使ってバックアップを取得します。

コンテナ内のデータをバックアップする

以下のようにdocker cpコマンドを使用してコンテナのデータをホストマシンにコピーすることでバックアップします。

docker cpコマンドを使ってデータをコピーする
$ sudo docker cp paperless-compose-webserver-1:/usr/src/paperless/data ./data
$ sudo docker cp paperless-compose-db-1:/var/lib/postgresql/data ./pgdata
$ sudo docker cp paperless-compose-broker-1:/data ./redisdata

上記のコマンドは、上から順番に以下のような処理を行います。

  1. paperless-compose-webserver-1 コンテナの /usr/src/paperless/data ディレクトリをホストマシンの ./data ディレクトリにコピー
  2. paperless-compose-db-1 コンテナの /var/lib/postgresql/data ディレクトリをホストマシンの ./pgdata ディレクトリにコピー
  3. paperless-compose-broker-1 コンテナの /data ディレクトリをホストマシンの./redisdata ディレクトリにコピー

これでコンテナ内のデータをホストマシンにバックアップできました。 ただし、必ずホストマシン側にコピーした内容を確認しておくことをお勧めします。 また、上記では、paperless-ngxというオープンソースのドキュメント管理システムを例にしており、各コンテナのデータのパス(/usr/src/paperless/dataなど)は Docker Compose で動かしている内容によりますので、それぞれが動かしているコンテナに合わせて置き換えてください。

ボリュームのバインド先を変更する

あとは、docker-compose.ymlの中でのvolumesのバインド先を修正します。例えば、以下のように修正します。

docker-compose.yml
version: '3.4'
services:
  broker:
    image: docker.io/library/redis:7
    restart: unless-stopped
    volumes:
      - ./redisdata:/data
 
  db:
    image: docker.io/library/postgres:15
    restart: unless-stopped
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: paperless
      POSTGRES_USER: paperless
      POSTGRES_PASSWORD: paperless
 
  webserver:
    image: ghcr.io/paperless-ngx/paperless-ngx:latest
    restart: unless-stopped
    depends_on:
      - db
      - broker
    ports:
      - '8001:8000'
    volumes:
      - ./data:/usr/src/paperless/data
      - ./media:/usr/src/paperless/media
      - ./export:/usr/src/paperless/export
      - ./consume:/usr/src/paperless/consume
    env_file: docker-compose.env
    environment:
      PAPERLESS_REDIS: redis://broker:6379
      PAPERLESS_DBHOST: db
 
volumes:
  data:
  media:
  pgdata:
  redisdata:

上記のように、volumesのバインド先を./data./media./export./consumeに変更しました。これによって誤ってホストマシンのルート直下にバインドしていたディレクトリを、docker-compose.ymlがあるディレクトリと同じディレクトリの中のdatamediaexportconsumeにバインドするように変更しました。

あとは以下によって コンテナ を再起動します。ただし、もしコンテナのデータをホストマシンにバックアップできていない場合は、以下のコマンドによってコンテナが停止することでコンテナ内のデータが消えてしまうので、必ずバックアップを取得し、ホストマシン側でデータを開けることを確認してから実行してください。

Docker Composeのコンテナを再起動する
$ sudo docker compose down
$ sudo docker compose up -d

まとめ

この記事では、Docker Compose を使って動いているコンテナ内のデータをホストマシンにバックアップし、コンテナのボリュームのバインド先を変更する手順を解説しました。