WordPress(Docker)をコンテナとボリュームごと別マシンに移行するスクリプト

以下の記事の自動化スクリプト。

目次

やることとやらないこと

  • やること
    • 移行元からボリュームをバックアップして、移行先で復元する
  • やらないこと
    • 移行後のルーティング

スクリプトでやっていることについて図示する。バックアップ中はダウンタイムとなるので注意

flowchart TD subgraph Local["ローカルマシン (移行元)"] direction TB A[YAMLからボリューム一覧を取得] --> B[移行対象のボリュームを選択] B --> C[元マシンのコンテナ停止] C --> D[選択ボリュームのバックアップ<br>vackup export] D --> E[元マシンのコンテナ再開<br>ダウンタイム短縮] E --> F[設定ファイル一式とバックアップを転送<br>rsync] end subgraph Remote["リモートマシン (移行先) SSH経由で自動実行"] direction TB G[作業ディレクトリに移動] H[ボリュームのリストア<br>vackup import] I[ネスト構造の解消<br>vackup-volumeを直下へ移動] J[移行先コンテナ起動<br>docker compose up -d] K[リモートの一時バックアップ削除] end F -->|ネットワーク転送| G G --> H H -.各ボリュームごとにループ.-> I I --> J J --> K subgraph Local_Cleanup["ローカルマシン (完了後)"] L[ローカルの一時バックアップ削除] end K -->|処理完了| L

準備

  • 移行元から移行先に、sshで転送できるようにしておく。
    • 移行元はLAN内のマシンで、移行先はVPSとする。
  • 移行元と移行先にdockerdocker composevackupを入れる。

vackupについては以下。

また、移行元のディレクトリ構成を以下のようにする。

.
├── site1
│   ├── custom-php.ini
│   └── docker-compose.yml
├── site2
│   ├── ads.txt
│   ├── custom-php.ini
│   └── docker-compose.yml
└── migrate-wp.sh

上記のディレクトリ構成で、migrate-wp.shを実行すると、転送先のマシンにコンテナの設定とボリュームごともってく。ディレクトリごともっていくので、見えていないが.envも含む。

スクリプトと実行

スクリプトは以下。AIが書いた。

#!/bin/bash

# エラー発生時にスクリプトを終了
set -e

# 引数のチェック
if [ "$#" -ne 3 ]; then
    echo "Usage: $0 <dir_name> <user@ip> <remote_base_path>"
    echo "Example: $0 site1 [email protected] /home/user/wordpress"
    exit 1
fi

DIR_NAME=$1
REMOTE_TARGET=$2
REMOTE_BASE_PATH=$3

LOCAL_DIR="./$DIR_NAME"
REMOTE_DIR="$REMOTE_BASE_PATH/$DIR_NAME"

# ローカルディレクトリの存在確認
if [ ! -d "$LOCAL_DIR" ]; then
    echo "Error: Local directory '$LOCAL_DIR' does not exist."
    exit 1
fi

echo "=== 1. ボリューム名の取得 ==="
cd "$LOCAL_DIR"

# docker compose config を使ってボリューム名一覧を取得
VOLUMES=$(docker compose config --volumes)

if [ -z "$VOLUMES" ]; then
    echo "Error: No volumes found in docker compose config for $DIR_NAME."
    exit 1
fi

echo "対象ボリューム:"
echo "$VOLUMES"

echo "=== 2. 元マシンのコンテナ停止 ==="
docker compose stop

echo "=== 3. ボリュームのバックアップ (vackup) ==="
mkdir -p volume-backups
for vol in $VOLUMES; do
    echo "Exporting volume: $vol"
    vackup export "$vol" "volume-backups/$vol.tar.gz"
done

echo "=== 4. 元マシンのコンテナ再開 (ダウンタイム短縮) ==="
docker compose up -d

echo "=== 5. 移行先へのファイル転送 (設定ファイル一式 + バックアップ) ==="
cd ..

# 移行先にターゲットディレクトリを作成
ssh -o ServerAliveInterval=60 "${REMOTE_TARGET}" "mkdir -p ${REMOTE_DIR}"

# フォルダごとリモートへ同期
rsync -avz --progress -e "ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=10" \
    "$DIR_NAME/" "${REMOTE_TARGET}:${REMOTE_DIR}/"

echo "=== 6. 移行先でのボリュームリストアと起動 ==="

# 変数内の改行をスペースに変換する
VOLUMES_ONELINE=$(echo "${VOLUMES}" | tr '\n' ' ')

REMOTE_SCRIPT=$(cat << EOF
cd "${REMOTE_DIR}"

for vol in ${VOLUMES_ONELINE}; do
    echo "----------------------------------------"
    echo "Processing volume on remote: \$vol"
    
    # リストアを実行
    vackup import "volume-backups/\$vol.tar.gz" "\$vol"
    
    # vackup-volume のネスト構造を修正
    echo "Fixing nested directory structure for \$vol..."
    docker run --rm -v "\$vol":/volume alpine sh -c "
        if [ -d /volume/vackup-volume ]; then
            mv /volume/vackup-volume/* /volume/ 2>/dev/null || true
            mv /volume/vackup-volume/.[!.]* /volume/ 2>/dev/null || true
            rmdir /volume/vackup-volume 2>/dev/null || true
        fi
    "
done

echo "----------------------------------------"
echo "Starting containers on remote host..."
docker compose up -d
EOF
)

# 移行先マシンでリストア処理を実行
ssh -o ServerAliveInterval=60 "${REMOTE_TARGET}" "${REMOTE_SCRIPT}"

echo "=== 7. ローカルの一時バックアップを削除 ==="
rm -rf "$DIR_NAME/volume-backups"

echo "=== 移行プロセスが完了しました ==="

使い方は以下。

./migrate-wp.sh site1 VPSのユーザ@VPSのIPアドレス /home/VPSのユーザ/wordpress

これを実行すると、移行先に~/wordpress/site1ができる。すでにコンテナの実行までされている。

なので、あとはDNSなどを操作して移行元から移行先に向けるとか、ルーティングで必要なことをやれば移行完了。

以上。

この記事をいいなと思っていただけた方、よければ高評価・チャンネル登録……はないので、コメント・SNSでシェア・ブックマーク、RSSフィード登録を、よろしくお願い致します。

コメント

コメントする

目次