目次
はじめに
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" | 既存バックアップファイルを除外 |
-czf | gzip圧縮して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/dockerdockerのパスを確認するコマンド:
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障害時 | 復元できない | 復元できる |
| 操作の手軽さ | SSH | WordPress管理画面 |
おすすめの構成:
- シェルスクリプト: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等)を除外
- ファイルが蓄積し続ける → 自動削除の行を追加する
