Railsアプリケーションのデータベースのバックアップを本番環境でとる方法として、Backupを用いる方法があります。 この導入方法について解説します。

技術スタック

この記事では、以下の環境におけるバックアップ方法について解説します。 ただ、データベースやストレージが変わっても、基本的な手順は同じなので、ある程度参考になると思います。

  • データベース:PostgreSQL
  • ストレージ:Amazon S3
  • 通知先:Slack

動作環境

この記事の内容は、以下の各バージョンにて動作を確認しています。

  • Backup v4.2.2
  • PostgreSQL v9.5.1

手順

はじめに、注意すべき点として、BackupはRailsアプリケーションのGemfileでは管理してはいけません(理由は後述します)。 別のプロジェクトとして以下を行ないます。

1. インストールする

まず、Gemをインストールします。

$ gem install backup

2. 設定ファイルを生成する

使用する技術をオプションとして渡し、Backupの設定ファイルを生成します。

$ backup generate:model --trigger backup --databases='postgresql' --storages='s3' --notifiers='slack'

これにより、~/Backup/config.rb~/Backup/models/backup.rbが生成されます。

3. 設定ファイルを更新する

設定ファイルは、コメントなどを除くと以下のような内容になっています。 必要な箇所を適切な値に更新します。

~/Backup/models/backup.rb:

Model.new(:backup, 'Description for backup') do
  database PostgreSQL do |db|
    db.name               = "my_database_name"
    db.username           = "my_username"
    db.password           = "my_password"
    db.host               = "localhost"
    db.port               = 5432
    db.additional_options = ["-xc", "-E=utf8"]
  end

  store_with S3 do |s3|
    s3.access_key_id     = "my_access_key_id"
    s3.secret_access_key = "my_secret_access_key"
    s3.region            = "us-east-1"
    s3.bucket            = "bucket-name"
    s3.path              = "path/to/backups"
    s3.keep              = 5
  end

  notify_by Slack do |slack|
    slack.on_success  = true
    slack.on_warning  = true
    slack.on_failure  = true
    slack.webhook_url = 'xxxxxxxxxxxxxxxxxxxxxxxx'
  end
end

~/Backup/config.rbは、特に更新する必要はありません。

4. バックアップをとってみる

次項で自動化について解説しますが、まずは正常に動作するかどうかを手動で確認します。 以下のコマンドでバックアップを取得できます。

$ backup perform --trigger backup

正しく動作した場合、Slackに通知が行なわれ、S3のバケットにバックアップファイルが保存されています。

5. 自動化する

あとは4のコマンドをcronで定期的に実行すればよいです。 Railsアプリケーションの場合、Wheneverを用いることで簡単に実現できます(導入方法は省略します)。

毎週日曜の4:00にバックアップをとる場合、以下のような内容になります。

config/schedule.rb:

every :sunday, at: '4:00am' do
  command 'backup perform --trigger backup'
end

備考

Railsとは切り離して管理する

Backupには多くの依存ライブラリがあるため、公式ドキュメントにもあるとおり、Gemfileで管理することは推奨されません。 Railsアプリケーション側ではなく、別のプロジェクトとして設定しましょう。

バックアップという行為自体がインフラ層の責務なので、アプリケーション側より構成管理ツール側(Itamaeなど)で行なう方がよいと思います。

PostgreSQLのバージョンを合わせる

PostgreSQLのサーバとクライアントのバージョンが異なると、以下のようにエラーが発生してしまい、バックアップが取れません。

pg_dump: server version: 9.5.1; pg_dump version: 8.4.20
pg_dump: aborting because of server version mismatch

この場合、pg_dumpのパスを設定することで対応できます。

~/Backup/config.rb:

Utilities.configure do
  pg_dump '/usr/pgsql-9.5/bin/pg_dump'
end

おわりに

以上のように、BackupとWheneverを用いることで簡単にバックアップを取ることができます。 バックアップはサービスの運営に必須だと思うので、参考にしてみてください。