QNAPのDockerでWordPressを自動バックアップする方法【全サイト対応・CRON設定付き】

QNAPのDockerでWordPressを自動バックアップする方法【全サイト対応・CRON設定付き】

はじめに

QNAPのContainerStationでWordPressを運用している場合、定期的なバックアップは必須です。

この記事では、WordPressのファイルとデータベースを自動でバックアップするシェルスクリプトと、QNAPのCRONを使った自動実行の設定方法を解説します。

実際の運用環境で発見した問題点と解決策も合わせて紹介します。


バックアップの対象

WordPressのバックアップには2種類必要です。

対象内容スクリプト
ファイルテーマ・プラグイン・画像などのWordPressファイル一式backup_wp_files.sh
データベース投稿・設定・ユーザー情報などのDBデータbackup_wp_db.sh

どちらか一方だけでは完全な復元ができません。両方セットでバックアップしてください。


バックアップの保存先フォルダ構成

your_site/
└── backup/
    ├── files/
    │   ├── backup_wp_files.sh   ← ファイルバックアップスクリプト
    │   ├── files_backup.log     ← 実行ログ
    │   └── wp_files_backup_YYYYMMDD_HHMMSS.tar.gz
    └── db/
        ├── backup_wp_db.sh      ← DBバックアップスクリプト
        ├── db_backup.log        ← 実行ログ
        └── db_backup_YYYYMMDD_HHMMSS.sql

Step 1:フォルダを作成する

mkdir -p /share/docker/your_site/backup/files
mkdir -p /share/docker/your_site/backup/db

Step 2:ファイルバックアップスクリプトを作成する

#!/bin/bash
# 保存先ディレクトリ
BACKUP_DIR="/share/docker/your_site/backup/files"
TARGET_DIR="/share/docker/your_site"

# 日時付きファイル名
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/wp_files_backup_${DATE}.tar.gz"

# ディレクトリ作成
mkdir -p "$BACKUP_DIR"

# バックアップ実行(不要なフォルダを除外)
tar \
  --exclude="./backup/files" \
  --exclude="./backup/db" \
  --exclude="./db_data" \
  --exclude="*.tar.gz" \
  -czf "$BACKUP_FILE" \
  -C "$TARGET_DIR" .

# 直近7件以外を削除
ls -1t "$BACKUP_DIR"/wp_files_backup_*.tar.gz | tail -n +8 | xargs rm -f

echo "✅ WordPressファイルのバックアップ完了: $BACKUP_FILE"

実行権限を付与します:

chmod +x /share/docker/your_site/backup/files/backup_wp_files.sh

各設定の意味:

設定意味
--exclude="./backup/files"バックアップ先フォルダ自体を除外(無限ループ防止)
--exclude="./db_data"データベースの生データを除外(別途mysqldumpで取得)
--exclude="*.tar.gz"既存バックアップファイルを除外
-czfgzip圧縮してtar.gz形式で保存
tail -n +8 | xargs rm -f直近7件以外を自動削除

不要なフォルダは必ず除外する WordPressのキャッシュフォルダやバックアッププラグインのフォルダが大きい場合は除外してください。 除外しないとバックアップが巨大になり時間がかかります。

例:ewww(画像最適化キャッシュ)やupdraft(UpdraftPlusのバックアップ)が数GB以上ある場合:

--exclude="./wp/wp-content/ewww" \
--exclude="./wp/wp-content/updraft" \

Step 3:データベースバックアップスクリプトを作成する

#!/bin/bash
# 保存先ディレクトリ
BACKUP_DIR="/share/docker/your_site/backup/db"
DB_CONTAINER="mariadb_your_site"
DB_NAME="your_database"
DB_USER="your_user"
DB_PASSWORD="your_password"
DATE=$(date +"%Y%m%d_%H%M%S")

mkdir -p "$BACKUP_DIR"

/share/CACHEDEV4_DATA/.qpkg/container-station/bin/docker exec "$DB_CONTAINER" \
  mysqldump -u"$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" \
  > "$BACKUP_DIR/db_backup_$DATE.sql"

# 直近7件以外を削除
ls -1t "$BACKUP_DIR"/db_backup_*.sql | tail -n +8 | xargs rm -f

echo "✅ DBバックアップ完了: $BACKUP_DIR/db_backup_$DATE.sql"

実行権限を付与します:

chmod +x /share/docker/your_site/backup/db/backup_wp_db.sh

dockerコマンドはフルパスで指定する CRONの実行環境ではdockerコマンドのパスが通っていません。 必ずフルパスで指定してください: /share/CACHEDEV4_DATA/.qpkg/container-station/bin/docker

dockerのパスを確認するコマンド:

which docker

自動削除を必ず追加する 自動削除の行を入れないとバックアップファイルが無制限に蓄積されます。 実際に自動削除なしで運用していたところ、毎日蓄積し続けて230件以上のファイルが溜まっていました。

【画像:db/フォルダのlsで大量のファイルが表示されている画面】

以下のコマンドで既存の不要ファイルを一括削除できます:

ls -1t /share/docker/your_site/backup/db/db_backup_*.sql | tail -n +8 | xargs rm -f

【画像:削除後に件数が減った画面のスクリーンショット】


Step 4:手動で動作確認する

CRONに登録する前に手動実行して動作を確認します。

# DBバックアップのテスト
/share/docker/your_site/backup/db/backup_wp_db.sh

# ファイルバックアップのテスト
/share/docker/your_site/backup/files/backup_wp_files.sh

バックアップファイルのサイズを確認します:

ls -lh /share/docker/your_site/backup/db/
ls -lh /share/docker/your_site/backup/files/

0バイトのファイルができた場合 DBバックアップが0バイトになる場合はdockerコマンドのパスが通っていない可能性があります。 ログファイルを確認してください:

cat /share/docker/your_site/backup/db/db_backup.log

docker: command not foundが出ていればdockerのフルパス指定が必要です。


Step 5:CRONで自動実行する設定

QNAPのCRON設定ファイルに追記します。sudoが必要です。

sudo sh -c 'echo "0 3 * * * /share/docker/your_site/backup/db/backup_wp_db.sh >> /share/docker/your_site/backup/db/db_backup.log 2>&1" >> /etc/config/crontab'
sudo sh -c 'echo "10 3 * * * /share/docker/your_site/backup/files/backup_wp_files.sh >> /share/docker/your_site/backup/files/files_backup.log 2>&1" >> /etc/config/crontab'

複数サイトある場合は時刻をずらして追加します:

# サイト2(20分・30分にずらす)
sudo sh -c 'echo "20 3 * * * /share/docker/your_site2/backup/db/backup_wp_db.sh >> /share/docker/your_site2/backup/db/db_backup.log 2>&1" >> /etc/config/crontab'
sudo sh -c 'echo "30 3 * * * /share/docker/your_site2/backup/files/backup_wp_files.sh >> /share/docker/your_site2/backup/files/files_backup.log 2>&1" >> /etc/config/crontab'

CRON設定の意味:

設定意味
0 3 * * *毎日午前3時0分に実行
10 3 * * *毎日午前3時10分に実行
>> *.log 2>&1実行ログをファイルに追記

DBバックアップを先に実行する理由 DBバックアップ(3:00)→ファイルバックアップ(3:10)の順番で実行します。 DBのダンプファイルをファイルバックアップに含めるためDBを先に取得しています。

CRONを反映させます:

sudo /etc/init.d/crond.sh restart

Step 6:設定を確認する

追加したCRON設定を確認します:

grep "your_site" /etc/config/crontab

UpdraftPlusと併用する場合

WordPressのバックアッププラグイン(UpdraftPlusなど)と併用する場合の注意点です。

シェルスクリプトUpdraftPlus
保存場所NAS本体Google Driveなど
NAS障害時復元できない復元できる
操作の手軽さSSHWordPress管理画面

おすすめの構成:

  • シェルスクリプト:7件保持(NAS本体に高速バックアップ)
  • UpdraftPlus:2〜3件保持(クラウドに保存・件数を減らしてストレージ節約)

UpdraftPlusのwp-content/updraftフォルダに注意 UpdraftPlusのバックアップファイルはNAS上のwp-content/updraft/に一時保存されます。 このフォルダが数GBになる場合はシェルスクリプトのtarから除外してください。 そのまま含めると二重バックアップになりバックアップが巨大になります。


まとめ

WordPressの自動バックアップ設定をまとめます:

# 1. フォルダ作成
mkdir -p /share/docker/your_site/backup/files
mkdir -p /share/docker/your_site/backup/db

# 2. スクリプト作成・実行権限付与
chmod +x /share/docker/your_site/backup/files/backup_wp_files.sh
chmod +x /share/docker/your_site/backup/db/backup_wp_db.sh

# 3. 手動実行で動作確認
/share/docker/your_site/backup/db/backup_wp_db.sh
/share/docker/your_site/backup/files/backup_wp_files.sh

# 4. CRONに追加
sudo sh -c 'echo "0 3 * * * /share/docker/your_site/backup/db/backup_wp_db.sh >> /share/docker/your_site/backup/db/db_backup.log 2>&1" >> /etc/config/crontab'
sudo sh -c 'echo "10 3 * * * /share/docker/your_site/backup/files/backup_wp_files.sh >> /share/docker/your_site/backup/files/files_backup.log 2>&1" >> /etc/config/crontab'

# 5. CRON反映
sudo /etc/init.d/crond.sh restart

よくあるトラブルと解決策:

  • DBバックアップが0バイト → dockerのフルパス指定が必要
  • バックアップが巨大 → 不要フォルダ(ewww・updraft等)を除外
  • ファイルが蓄積し続ける → 自動削除の行を追加する

関連記事