Difyのデータ移行方法

  1. はじめに
  2. バックアップの方法 [1]
  3. 移行手順の具体例 [2]
    1. scpを使用してサーバ間でファイルのコピーを行う
      1. SSHの認証公開キーを作成する
      2. 移行元サーバーの公開鍵を移行先サーバーにコピーする
      3. 移行元サーバーの圧縮ファイルを移行先サーバーにコピーする
  4. 復元手順 [1]
  5. データの同期と保存場所 [2]
    1. データベースの移行
      1. 1. pg_dumpとpsqlを使った方法(推奨)
        1. ステップ1: サーバーAでデータをバックアップする (ダンプ)
        2. ステップ2: サーバーBへSQLファイルを転送する
        3. ステップ3: サーバーBでデータを復元する (リストア)
      2. 2. ボリュームを直接コピーする方法
        1. ステップ1: サーバーAでボリュームの場所を特定する
        2. ステップ2: データをサーバーBにコピーする
        3. ステップ3: サーバーBでデータを復元する
        4. ステップ4: ボリュームの認識とdocker-compose.ymlの変更
          1. 変更前の設定
          2. 変更後の設定
        5. ステップ5: コンテナを起動する
    2. ディレクトリをそっくり移行する手順
      1. 3.pg_dumpとpsqlを使った方法とボリュームを直接コピーする方法の比較
    3. 2つのバックアップ方法の違い
      1. 4.pg_dumpとpsqlを使った方法とボリュームを直接コピーする方法の比較
  6. コンテナの設定変更 [2]
    1. .envファイルの書き換えポイント
    2. 解決方法
      1. 競合Portが発生した場合
      2. 1. ポートを使用しているプロセスを特定して停止する
      3. 2. Difyコンテナのポートマッピングを変更する
    3. 推奨される手順
  7. 新しい環境へのアクセス [2]
    1. 手順の整理と補足
      1. 1. Difyディレクトリのコピー
      2. 2. volumesディレクトリのリネーム
      3. 3. .envファイルの修正
      4. 4. ボリュームデータのコピー
    2. まとめ
  8. サーバのレスポンス確認と対処方法
    1. サーバーの負荷状況の確認
      1. 1. docker stats
      2. 2. htop (または top)
      3. 3. df -h
    2. 考えられる原因と対策
      1. 1. メモリ不足
      2. 2. CPUの過負荷
      3. 3. 複数のコンテナ
    3. レスポンス対策
    4. 原因の可能性
    5. 解決策

はじめに

  • データの同期: Difyのコンテナは、データをフォルダに同期します。このため、フォルダごとコピーすればデータを移行できます。
  • データのコピー手順: 保存されたデータは新しい環境のフォルダにコピーします。具体的には、旧DifyのVolumesフォルダ内容を新しいDifyフォルダに上書きします。
  • コンテナの設定: 環境変数の書き換えが必要です。.envファイルを作成し、設定を調整します。このことで、移行後も設定が保持されます。
  • バックアップ: データ移行前にバックアップを取ることが推奨されます。DockerのボリュームをGzip形式で圧縮して保存します。
  • 復元手順: SSHで新環境にログインし、バックアップファイルを展開してDockerを起動します。

 

バックアップの方法 [1]

      • バックアップ作成手順: Docker Composeを停止し、Difyディレクトリ全体をtarコマンドで圧縮します。
        Dockerディレクトリに移動
        sudo docker compose down
      • 保存場所: バックアップファイルは安全な場所に確保することが重要です。
        Difyを格納しているフォルダーのルートに移動し、「cd ..」にて一つ上の階層に移動
        tar -czvf dify_backup.tar.gz dify
        ※difyディレクトリをdify_backup.tar.gzに圧縮して格納
  • 復元準備: バックアップファイルを適切に管理し、復元時のアクセスを容易にする必要があります。

 

移行手順の具体例 [2]

  • 旧環境の停止: 前回起動したディレクトリに移動後停止させます。
  • 新フォルダ作成: 新しいDifyのコンテナを作るため、フォルダを作成しリポジトリをクローンします。
  • 環境変数の設定: .envファイルを作成し、必要な設定を調整。

 

scpを使用してサーバ間でファイルのコピーを行う

SSHの認証公開キーを作成する

移行元サーバでSSH鍵を生成する: まだ鍵がない場合、以下のコマンドで鍵を生成します。パスフレーズは空でも構いませんが、設定しておくとより安全です。

「ssh-keygen」コマンドを使用してコピー元のサーバへSSHの公開鍵と秘密鍵のペアを生成します。

$ sudo ssh-keygen

<実行結果>

$ sudo ssh-keygen
Generating public/private rsa key pair.・
Enter file in which to save the key (/root/.ssh/id_rsa):←格納先のフォルダーを指定(Enterでデフォルトの/root/.ssh/id_rsaへ格納されます。)
Enter passphrase (empty for no passphrase): ←公開キー利用の為のパスフレーズ
Enter same passphrase again: ←パスフレーズの再入力
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:o57j6tqpJ+cLrvkn1hZxTDpheHVSq6sh6D2Nx+aJYiw root@dify.com
The key's randomart image is:
+---[RSA 3072]----+
| . .o.o |
| . + .o . |
| o = . |
| + o. |
| +. S |
| . . o . |
|o o.=.o |
|E*=*BXo. |
|==*#&*+. |
+----[SHA256]-----+

移行元サーバーの公開鍵を移行先サーバーにコピーする

以下のコマンドを実行すると、パスワード認証を一度だけ使って公開鍵を移行先サーバーに登録できます。

$ sudo ssh-copy-id dify@192.168.1.1    ←移行先のユーザ名(dify)とIPアドレス(192.168.1.1)

<実行結果>

$ sudo ssh-copy-id dify@192.168.1.1 /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed Enter passphrase for key '/root/.ssh/id_rsa': ←先に設定したパスコード

※尚、sshが上手く接続できない場合には、先に移行元サーバで作成した「id_rsa.pub」の内容をターゲット先の~/etc/.ssh/authorized_keysの内容にvi等で追加することで、移行先サーバーに登録できます。

 

移行元サーバーの圧縮ファイルを移行先サーバーにコピーする

$ sudo scp /home/dify/dify_backup.tar.gz

dify@192.168.1.1:/home/mirrormaster/ パスワード入力が求められずに、コピーが完了するはずです。

<実行結果>

$ sudo scp /home/kagami-dify/dify_backup.tar.gz
dify@192.168.1.1:/home/mirrormaster/ Enter passphrase for key '/root/.ssh/id_rsa':←先に設定したパスコード dify_backup.tar.gz

 

復元手順 [1]

    • SSHログイン: 新しいサーバーにSSHでログインします。
    • バックアップファイルの確認: バックアップファイルが目的の場所にあることを確認します。
      • バックアップ展開: tarコマンドを使ってバックアップファイルを解凍します。
        $ tar -xzvf dify_backup.tar.gz -C dify
        -x:ファイルを解凍するオプションです。
        -z:gzipで圧縮されたファイルを扱います(.gzに対応)。 -v:解凍中にファイルリストを詳細に表示します(verbose)。 -f:アーカイブファイルの名前を指定します(file)。 -C:解凍先のディレクトリを指定します(change directory) ※dify_backup.tar.gzは解凍元のファイル   difyは解凍先のディレクトリ名(このディレクトリの下に解凍元のディレクトリが作成される)
      • Docker Compose起動: コンテナをバックグラウンドで立ち上げます。

       

データの同期と保存場所 [2]

  • フォルダの役割: Difyのコンテナはデータをフォルダに同期します。
  • 保存場所の確認: データはdify/docker/volumesフォルダに格納されています。
  • データのコピー方法: 新しい環境のvolumesフォルダにデータをコピーします。

データベースの移行

 

1. pg_dumpとpsqlを使った方法(推奨)

この方法は、データベースの内容をSQLファイルとしてエクスポートし、それを新しいサーバーにインポートします。データ量が多い場合や、データベースのバージョンが異なる場合に適しています。

ステップ1: サーバーAでデータをバックアップする (ダンプ)
  1. Difyコンテナを停止する: データベースの整合性を保つため、まずDifyのコンテナをすべて停止します。
    cd /path/to/dify_directory
    docker-compose down
    
  2. pg_dumpコマンドを実行する: Docker Composeを使用して、dbコンテナ内でpg_dumpを実行し、データをSQLファイルとして出力します。
    docker-compose exec -T db pg_dump -U postgres -d dify > dify_backup.sql
    • exec -T: コンテナ内でコマンドを実行します。
    • -U postgres: PostgreSQLのユーザー名を指定します。
    • -d dify: difyデータベースを指定します。

 

ステップ2: サーバーBへSQLファイルを転送する

SCPコマンドを使って、作成したdify_backup.sqlファイルをサーバーBに転送します。

scp dify_backup.sql mirrormaster@163.44.113.144:/path/to/difyai_directory/

 

ステップ3: サーバーBでデータを復元する (リストア)
  1. 新しいDify環境を起動する: 新しいサーバー(difyai)で、空のデータベースを持つDifyコンテナを起動します。
    cd /path/to/difyai_directory
    docker-compose up -d
    
  2. psqlコマンドを実行する: Docker Composeを使用して、dbコンテナ内でpsqlを実行し、SQLファイルをインポートします。
    cat dify_backup.sql | docker-compose exec -T db psql -U postgres -d dify
    
  3. コンテナを再起動する: データのインポート後、コンテナを再起動して設定を反映させます。
    docker-compose restart
    

 

2. ボリュームを直接コピーする方法

この方法は、データベースのデータそのものを物理的にコピーします。データベースのバージョンが同じ場合に適しています。

 

ステップ1: サーバーAでボリュームの場所を特定する
  1. コンテナを停止する: docker-compose downを実行してコンテナを停止します。
  2. ボリュームのパスを調べる: docker inspectコマンドで、dbコンテナがマウントしているボリュームのホスト上の場所を特定します。
    docker inspect [コンテナIDまたはコンテナ名]
    

    出力されるJSONのMountsセクションにあるSourceが物理パスです。通常は/var/lib/docker/volumes/[ボリューム名]/_dataのようなパスになります。

 

ステップ2: データをサーバーBにコピーする
  1. ボリュームを圧縮する:
    tar -czvf db_volume_backup.tar.gz /var/lib/docker/volumes
  2. 圧縮ファイルを転送する: scp db_volume_backup.tar.gz mirrormaster@163.44.113.144:/path/to/destination/

 

ステップ3: サーバーBでデータを復元する
  1. 新しいDify環境のボリュームを準備する: サーバーBのdifyaiディレクトリで、まずdocker-compose up -dを実行して、空のデータベースボリュームを作成します。
  2. 新しいコンテナを停止する: docker-compose downを実行します。
  3. ボリュームのパスを特定する: docker inspectで、サーバーB上の新しいデータベースボリュームの物理パスを調べます。
  4. バックアップデータを展開する: サーバーBのrootユーザーで、新しいボリュームの物理パスに直接バックアップファイルを展開します。 tar -xzvf db_volume_backup.tar.gz -C /path/to/new/db/volume/on/server_B
  1. バックアップファイルを展開する: 新しいサーバーの/var/lib/ディレクトリに移動し、バックアップファイルを展開します。 sudo tar -xzvf docker_volumes_backup.tar.gz -C /
    ※但し、既存環境が存在する場合には、/var/lib/volumesではなく、/var/lib/volumes2等異なるディレクトリへ展開する必要必要があります。
    異なるディレクトリへの解凍は一旦/var/lib/tmpなどの名前のディレクトリ上に解凍して、mv dify/* .やmv dify/{.,}* .、mv dify/.??* .などのコマンドを使用してファイルの保管ディレクトリを変更します。
    最後に不要なディレクトリをrmdir difyにて削除します。

 

ステップ4: ボリュームの認識とdocker-compose.ymlの変更

volumes2というディレクトリにデータを解凍した場合、Difyコンテナにそれを認識させるには、docker-compose.ymlボリュームマッピングを変更する必要があります。

変更前の設定

これは、名前付きボリュームを使用している場合です。

services:
  db:
    volumes:
      - 'dify_db_data:/var/lib/postgresql/data'

volumes:
  dify_db_data:

※Dockerはデータを独自のボリュームに格納しており、コンテナは、ホスト上の特定のディレクトリ(この場合は/var/lib/postgresql/)にデータを直接書き込むのではなく、Dockerが管理する抽象化されたボリュームを使用します。このボリュームの実体は、ホスト上の/var/lib/docker/volumes/以下に存在します。

PostgreSQLのデータが実際にどこに保存されているかを確認するには、docker inspectコマンドを使用します。

docker inspect [コンテナ名またはコンテナID]

このコマンドの出力にあるMountsセクションのSourceが、データが実際に保存されているホスト上の物理パスです。

 

変更後の設定

解凍したホスト上の物理パスを直接指定するように変更します。

services:
  db:
    volumes:
      - '/var/lib/docker/volumes2/dify_db_data/_data:/var/lib/postgresql/data'

この変更により、Dockerはdify_db_dataという名前付きボリュームを探す代わりに、指定された物理ディレクトリのデータを使用します。

 

ステップ5: コンテナを起動する

docker-compose up -dでDifyを再起動すると、元のデータが読み込まれます。

 

ディレクトリをそっくり移行する手順

 

  1. 元のサーバー(A)でDockerコンテナを停止する: データの不整合を防ぐため、移行するDifyコンテナをすべて停止します。 docker-compose down
  2. ボリュームディレクトリを圧縮する: Dockerのボリュームデータが格納されている /var/lib/docker/volumes/ディレクトリを、tarコマンドなどで圧縮します。これにより、すべてのボリュームを一つのファイルとして扱えます。 sudo tar -czvf docker_volumes_backup.tar.gz /var/lib/docker/volumes
  3. 新しいサーバー(B)にファイルを転送する: scprsyncなどのツールを使って、圧縮したファイルを新しいサーバーに転送します。
  4. 新しいサーバーでDockerを停止する: もしDockerが動いていれば停止します。 sudo systemctl stop docker
  5. バックアップファイルを展開する: 新しいサーバーの/var/lib/ディレクトリに移動し、バックアップファイルを展開します。 sudo tar -xzvf docker_volumes_backup.tar.gz -C /

3.pg_dumpとpsqlを使った方法とボリュームを直接コピーする方法の比較

2つのバックアップ方法の違い

データベースをバックアップする最初の方法(pg_dump/psql)と、2番目の方法(ボリュームを直接コピー)の主な違いは、システムの負荷ではなく、安全性と互換性です。

「pg_dumppsql」を使った方法は、同一のデータベースでの管理となり、「ボリュームを直接コピーする方法」はDifyコンテナ毎にデータベースを分離するため、より独立性の高い環境を構築できます。このため、今回は「ボリュームを直接コピーする方法」を使用します。

項目 pg_dumppsqlを使った方法 ボリュームを直接コピーする方法
データ形式 SQLコマンド形式。 ディレクトリ内の物理ファイル。
互換性 PostgreSQLのバージョンが異なっていても比較的安全。 Docker、OS、PostgreSQLのバージョンが完全に一致する必要がある。
データの整合性 データベースの論理的な整合性を保つため、より安全。 ファイルが破損しているとデータが使えないリスクがある。
システム負荷 ダンプとリストア時にCPUとメモリを使用する。 圧縮と転送にI/OとCPUを使用する。

結論: pg_dump/psqlを使った方法は、少し複雑ですが、データの安全性が非常に高く、最も推奨される方法です。ボリュームを直接コピーする方法は、簡単ですが、両サーバーの環境が完全に一致していないと動作しないリスクがあります。

どちらの方法も、元の環境と新しい環境のDifyのバージョンが一致していることを確認してください。 バージョンが異なると、データベースのスキーマが合わず、正常に動作しない可能性があります。

 

4.pg_dumpとpsqlを使った方法とボリュームを直接コピーする方法の比較

 

 

コンテナの設定変更 [2]

  • 環境変数の書き換え: .envファイル作成で環境設定が簡易化されます。
  • ポート番号の変更: ポート番号を.envファイルで設定できます。
  • 設定の重要性: デフォルト設定ではセキュリティが懸念されるため、カスタマイズが推奨されます。

.envファイルの書き換えポイント

 

 

 

解決方法

以下のいずれかの方法で、このポート競合の問題を解決できます。

 

競合Portが発生した場合

1. ポートを使用しているプロセスを特定して停止する

最も直接的な解決策です。5003番ポートを使用しているプロセスを特定し、そのプロセスを停止します。

  • プロセスを特定するコマンド:

    Bash

    sudo lsof -i :5003
    

    または

    Bash

    sudo netstat -tulpn | grep 5003
    
  • プロセスの停止:
    • 上記のコマンドで表示されたプロセスID(PID)を確認し、sudo kill <PID>コマンドでプロセスを停止します。

 

2. Difyコンテナのポートマッピングを変更する

もし、ポートを使用しているプロセスを停止できない場合や、恒久的な解決策が必要な場合は、difyai-plugin_daemon-1コンテナのポートマッピングを変更します。

  • docker-compose.ymlファイルで、plugin_daemonサービスのポート設定を編集します。

    YAML

    plugin_daemon:
      ...
      ports:
        # 例: 5003ポートを別のポートにマッピングする
        - "5004:5003"
    

    この例では、ホストマシンの5004番ポートがコンテナの5003番ポートにバインドされるようになります。


 

推奨される手順

新しい環境へのアクセス [2]

  • ローカルアクセス試行: 新しいDify環境にローカルIPアドレスでアクセスして接続を確認します。
  • ポート番号の確認: 設定したポート番号を使用して新しい環境にアクセス。
  • 設定保持の確認: 全てのチャットボットなどの設定がアップデート後も保持されていることを確認します。

 

コメント