Immichの画像をOneDriveとGoogleドライブにバックアップ

Immichの画像バックアップですが、googleフォトだとAPI制限が多いのでgoogleドライブを利用する方法に。OneDriveと含めて。Amazonフォトはrcloneでは難しいので、この2つにしています。

rcloneのインストール

まずはrcloneのインストールから。

sudo -v && curl https://rclone.org/install.sh | sudo bash

ImageMagickのインストール

Googleフォトへ低画質で保存するために、ImageMagickをインストールします。

sudo apt install imagemagick -y

rclone リモート設定

rclone config

OneDriveの設定。

n) New remote
name> onedrive
Storage> onedrive        # "Microsoft OneDrive" を選択(番号で入力、現時点は30)
client_id>               # 空白のままEnter
client_secret>           # 空白のままEnter
region> 1                # global (デフォルト)
Edit advanced config? n
Use auto config? y       # ブラウザが開くので認証する
```
ブラウザでMicrosoftアカウントにログインして認証後、ターミナルに戻って:
```
Your choice> 1           # OneDrive Personal or Business
Chose drive> 3           # 表示されたドライブを選択
Is that okay? y
y) Yes this is OK
q) Quit config

GoogleDriveの設定

n (New remote)
name: gdrive
type: drive (Google Drive)   # 番号で入力、現時点24)
client_id:                   # そのままEnter
client_secret:               # そのままEnter
scope: 1                     # (Full access)
root_folder_id:              # そのままEnter
service_account_file:        # そのままEnter
Edit advanced config? n
Use web browser to authenticate y
ブラウザでGoogleアカウントにログイン・許可
Not a Shared Drive n
y (確認)

接続確認

rcloneの設定を終えたら、接続確認です。

rclone lsd onedrive:
rclone lsd gdrive:

バックアップ先フォルダ作成

OneDriveにはバックアップ先のフォルダをあらかじめ作成しておきます。

rclone mkdir onedrive:ImmichBackup
rclone mkdir onedrive:ImmichBackup/library
rclone mkdir onedrive:ImmichBackup/db-dumps

スクリプトを作成

cat > /opt/docker/immich/backup-to-cloud.sh << 'EOF'
#!/bin/bash
# === Immich 完全バックアップスクリプト ===
# バックアップ先:OneDrive(写真+DB)/ Googleドライブ(写真・低画質)
LOG="/opt/docker/immich/rclone-backup.log"
IMMICH_DIR="/opt/docker/immich"
LIBRARY_SRC="$IMMICH_DIR/library/library"
DB_DUMP_DIR="$IMMICH_DIR/db-dumps"
GPHOTOS_FLAT="$IMMICH_DIR/gphotos-flat"
DEST_LIBRARY="onedrive:ImmichBackup/library"
DEST_DB="onedrive:ImmichBackup/db-dumps"
DATE=$(date '+%Y-%m-%d_%H-%M-%S')
DB_FILE="$DB_DUMP_DIR/immich-db-$DATE.sql.gz"

log() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG"
}

mkdir -p "$DB_DUMP_DIR" "$GPHOTOS_FLAT"
log "===== バックアップ開始 ====="

# --- 1. PostgreSQL ダンプ ---
log "PostgreSQL ダンプ開始..."
docker exec immich_postgres pg_dumpall -U postgres | gzip > "$DB_FILE"
if [ $? -eq 0 ]; then
  log "PostgreSQL ダンプ完了: $DB_FILE"
else
  log "PostgreSQL ダンプ失敗 - バックアップを中断します"
  exit 1
fi
find "$DB_DUMP_DIR" -name "immich-db-*.sql.gz" -mtime +7 -delete
log "古いDBダンプを削除(7日以上前)"

# --- 2. OneDrive:写真+DB同期 ---
log "OneDrive 写真ライブラリ同期開始..."
rclone sync "$LIBRARY_SRC" "$DEST_LIBRARY" \
  --transfers 4 --checkers 8 \
  --log-file "$LOG" --log-level INFO
[ $? -eq 0 ] && log "OneDrive 写真同期完了" || log "OneDrive 写真同期失敗"

log "OneDrive DBダンプ同期開始..."
rclone sync "$DB_DUMP_DIR" "$DEST_DB" \
  --transfers 2 \
  --log-file "$LOG" --log-level INFO
[ $? -eq 0 ] && log "OneDrive DBダンプ同期完了" || log "OneDrive DBダンプ同期失敗"

# --- 3. Googleドライブ:フラットにリサイズ→アップロード ---
log "Googleドライブ用リサイズ開始(長辺2048px・品質60%)..."
find "$LIBRARY_SRC" -type f \
  \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) | \
while read -r SRC_FILE; do
  DEST_FILE="$GPHOTOS_FLAT/$(basename "$SRC_FILE")"
  if [ -f "$DEST_FILE" ] && [ "$DEST_FILE" -nt "$SRC_FILE" ]; then
    continue
  fi
  convert "$SRC_FILE" \
    -resize "2048x2048>" \
    -quality 60 \
    "$DEST_FILE"
done
log "リサイズ完了"

log "Googleドライブ アップロード開始..."
rclone copy "$GPHOTOS_FLAT" gdrive:ImmichBackup \
  --transfers 4 \
  --log-file "$LOG" --log-level INFO
[ $? -eq 0 ] && log "Googleドライブ アップロード完了" || log "Googleドライブ アップロード失敗"

log "===== バックアップ完了 ====="
EOF

chmod +x /opt/docker/immich/backup-to-cloud.sh

スクリプトの内容確認。

cat /opt/docker/immich/backup-to-cloud.sh

動作確認。もし初回なら、まだgoogleドライブ用にリサイズしていないので、まずリサイズを実行。

LIBRARY_SRC="/opt/docker/immich/library/library"
GPHOTOS_FLAT="/opt/docker/immich/gphotos-flat"
mkdir -p "$GPHOTOS_FLAT"

find "$LIBRARY_SRC" -type f \
  \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) | \
while read -r SRC_FILE; do
  DEST_FILE="$GPHOTOS_FLAT/$(basename "$SRC_FILE")"
  if [ -f "$DEST_FILE" ] && [ "$DEST_FILE" -nt "$SRC_FILE" ]; then
    continue
  fi
  convert "$SRC_FILE" \
    -resize "2048x2048>" \
    -quality 60 \
    "$DEST_FILE"
done

echo "リサイズ完了"

リサイズしたファイルがあるなら、それぞれ手動テストします。

rclone sync /opt/docker/immich/library/library onedrive:ImmichBackup/library \
  --dry-run --progress

rclone copy /opt/docker/immich/gphotos-flat gdrive:ImmichBackup \
  --dry-run --progress

動作が問題ないようならスケジュール設定します。

cronでスケジュール設定

スケジュール設定します。

crontab -e

毎日3時に自動実行するなら下記を一番下に追記します。

0 3 * * * /opt/docker/immich/backup-to-cloud.sh

内容を確認するなら次のコマンドです。

crontab -l

ログ確認

tail -f /opt/docker/immich/rclone-backup.log