😽

Docker環境で動かしているMisskeyデータベースのバックアップ自動化(rclone→GoogleDrive)

2025/01/11に公開

前書いた記事の方法でやると、Input/outputエラーが出るようになりGitHubで公開しているスクリプトも変えたので書き直しです。

この記事でやること
・Misskeyデータベースのバックアップ→GoogleDriveに投げるのを自動化
・バックアップ通知をDiscordに飛ばす

Discordウェブフックの作成方法はこの記事では説明しませんが簡単なので大丈夫!

rclone導入

sudo apt update
sudo apt install rclone

rclone設定

ザッと適当に説明していますが対話式なのであまり難しくない

rclone config
# nを選択

name> googledrive # 任意の名前を入力

# クラウドストレージの番号を選択(現時点では18)

# クライアントIDとシークレットの入力
# デフォルト(入力せずEnter)でok

# アクセスタイプの選択
# 1を選択(フルアクセス許可)

# あとは適当にEnter押してく

# ブラウザで色々したあと、表示された認証コードを貼り付ける

中身の確認

# リモートのファイル一覧を表示
rclone ls googledrive: # 設定で決めた任意の名前
# GoogleDriveにあるファイルが表示されていればok

一時的にバックアップファイル置く場所作る

# ホームディレクトリでok
mkdir mi_backup

バックアップスクリプトの作成

GitHubでスクリプトも公開harumaki2000/misskey_backupしているので、これを適当な場所でgit cloneして使う方が早いと思いますが一応説明も(GitHubとこの記事のスクリプトは中身同じです)

misskey_backup.sh

#!/bin/bash

BACKUP_FILE="db_dump_$(date +%Y%m%d_%H%M%S).sql" # バックアップファイル名
BACKUP_DIR="/home/misskey/mi_backup" # バックアップファイルの一時的な保存先
DOCKER_DIR="/home/misskey/misskey" # docker-compose.ymlがあるディレクトリ
CONTAINER_NAME="containar_name" # Postgresqlが動いているコンテナ名
DB_USER="your_db_user_name" # Postgresqlユーザー名
DB_NAME="your_db_database_name" # Postgresqlデータベース名
RCLONE_REMOTE="your_rclone_remote" # rcloneのリモート名(例: gdrive)

# Discord Webhook URL
DISCORD_WEBHOOK_URL="your_discord_webhook_url"

# sudoパスワード
PASSWORD="your_password"

# docker-compose.ymlがあるディレクトリに移動
cd "${DOCKER_DIR}"

# バックアップ開始通知
curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"📌 データベースのバックアップを開始します。\"}" "$DISCORD_WEBHOOK_URL"

# バックアップを作成
echo $PASSWORD | sudo -S docker compose exec "${CONTAINER_NAME}" pg_dump -U "${DB_USER}" "${DB_NAME}" > "${BACKUP_DIR}/${BACKUP_FILE}"

if [ $? -eq 0 ]; then
    echo "Database backup successful: ${BACKUP_FILE}"

    # rcloneでGoogle Driveにアップロード
    rclone copy "${BACKUP_DIR}/${BACKUP_FILE}" "${RCLONE_REMOTE}:misskey_backups/"

    if [ $? -eq 0 ]; then
        echo "Backup uploaded to Google Drive using rclone."

        # Discordに成功通知
        curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"✅ データベースのバックアップが完了し、Google Driveにアップロードされました: ${BACKUP_FILE}\"}" "$DISCORD_WEBHOOK_URL"
    else
        echo "Failed to upload backup to Google Drive using rclone."

        # Discordにエラー通知
        curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"⚠ データベースのバックアップアップロードに失敗しました: ${BACKUP_FILE}\"}" "$DISCORD_WEBHOOK_URL"
    fi

    # 7日以上前のバックアップを削除
    find "${BACKUP_DIR}" -type f -name "db_dump_*.sql" -mtime +7 -exec rm {} \;

    if [ $? -eq 0 ]; then
        echo "Old backups deleted successfully."
        curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"🧹 7日以上前のローカルバックアップファイルを削除しました。\"}" "$DISCORD_WEBHOOK_URL"
    else
        echo "Failed to delete old backups."
        curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"⚠ 7日以上前のローカルバックアップファイルの削除に失敗しました。\"}" "$DISCORD_WEBHOOK_URL"
    fi

else
    echo "Database backup failed."

    # Discordにエラー通知
    curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"❌ データベースのバックアップに失敗しました。\"}" "$DISCORD_WEBHOOK_URL"
fi

スクリプト実行権限付与

chmod +x backup.sh

cronに登録

crontab -e

# 毎朝4時に実行する場合
0 4 * * * /home/misskey/misskey_backup.sh

GoogleDrive上にmisskey_backupsというファイルが追加され、その中身にdb_dump_〜.sqlがあればok

Discussion