mastodonのDB(PostgreSQL)を外出しする方法。(Google Cloud Plathomeでの場合)

#はじめに#

「サクッと立ち上げる」系の記事を読んでなんとかかんとか立ち上げたmastodon。Google Compute Engineで無料プラン使って立ち上げるといろいろ楽なかわり、なにやってるのかわからないですよね。

いろいろ検索してみても、もうちょっとまともでプリミティブな感じで開発している人の情報が見えるくらい。sudoつけたら全部できちゃうから楽だなー、って程度の人には何が何だか、ということで悩んでいたのです。

正直、mastodonで使われているPostgreSQLを外出しするときにMySQLで代用できるのかどうかも微妙にわからない、っていうか、Amazon ECSにはPostgreSQLを外出しするサービスがあるのですが、GCEではデフォルトのRDBはmySQLなのですよ。無理矢理立ち上げてポート合わせてアクセスすれば意外とうまく行っちゃうかなーとか思っていたところ、β版ですがGCEでもPostgreSQLサーバが立ち上げられることがわかったので、GCE上で立ててるmastodonのDBをそっちに移してしまいました。

#誰向け？#

この記事は、

- GCEでなんとなく(docker使って)mastodonを立てた。
- なんとなく固定IPアドレスを取ってしまった。
- せっかくだから負荷のかかりそうな処理は他のサーバにまかせてみたい

というひと向けのSQL移行方法です。

#まず、SQLサーバを立ち上げる#

1. 例のコンソールパネルの左側にはメニューがあって、セクションごとに分かれているところの下の方っていうか中の方、ストレージ(storage)セクションの2番めに「SQL」ってメニューがありますね。これをクリックします。
2. 「インスタンスを作成する」で新しいインスタンスを作ります。
3. 「データベースエンジンの選択」ではPostgreSQL(ベータ版)を選びます。次に進むまで少し時間がかかります。
4. 「インスタンスID」は別に使わないので適当に間違えなさそうな名前をつけます。(ただし、このインスタンスを削除しても同じ名前はつけられないみたいです。)
5. 「場所」はまあ今のVMインスタンスがあるところと同じところを選びたいですが、意外と限られています。私はVMインスタンスを無料で始めたかったのでus-westにいたのですがここでは今のところPostgreSQLサーバは立てられない感じでした。できれば同じところを選ぶと捗ります。
6. コア数は下から2番め、メモリは一番少なめを選びます。コア数が一番低いのは実験用なのでお勧めじゃないそうです。この設定、はやい話がデフォルトです。
7. ストレージは、私はSSD 10GBを選びました。自動増量も有効化していますがこの辺は好みです。
8. 自動バックアップとかその辺は適切におまかせします。
9. postgresユーザーのパスワードをいれます。これあとで必要になります、たぶん。なので別途メモっておきます。
10. 承認済みネットワークには、自分のVMインスタンス(mastodonを入れた仮想マシン)の固定IPアドレスを入れておきます。100.257.257.1/32みたいな感じですね。[^1]
11. 「作成」を押すと外部IPを割り振られてSQLマシンが出来上がります。
12. インスタンス一覧にある外部IPはSQLアクセスに必要なものなのでメモっておきます。

#今のpostgresのバックアップを取ろう#

- pg_dump,pg_dumpall どちらでもいいのですが、どちらもたぶん今のVMには入っていません。なのでインストールします。

```
$sudo apt-get update
$sudo apt-get install postgresql-client-common
```

- バックアップには、pg_dumpを使う方法がいっぱい見つかりますが、私はpg_dumpallを使いました。

```
$sudo docker exec mastodon_pg_1 pg_dumpall -U postgres > ./mastodon_backup.sql
```
ここでいうmastodon_pg_1はdockerコンテナの名前です。
``$sudo docker-compose ps`` で実行しているdockerコンテナ一覧が見えるので、適切なものを書き込みます。なにも変更していなければpostgreSQLを動かしているのは上記の名前でいいはず。

#外部SQL化の設定をしよう#

- .env.productionのDB関連をいじって、外部SQLサーバに向かうようにします。
DB_HOST = [SQLの外部IPアドレス]
DB_PASS = [さっき設定したpostgresのパスワード]
DB_USER = postgres (たぶんデフォルト値)
その他はこれまでのまま(デフォルト値)でいけます。

- docker-compose.yml のDB永続化関連をコメントアウトしておきます。(これはしなくてもいいかもしれない)
- mastodonを停止します。

```
$sudo docker-compose down
```
- DBを再構築します。

```
$sudo docker-compose run --rm web rails db:migrate
```

#バックアップを書き戻そう#

- mastodon関連コンテナのうち、db関連だけを立ち上げます。いちど停止したほうがいいかもしれません。

```
$sudo docker-compose down
$sudo docker-compose up -d db
```

- 先ほど作ったバックアップファイルを、mastodon_db_1コンテナの中にコピーします。

```
$sudo docker cp ./mastodon_backup.sql mastodon_db_1:/tmp/for_restore.sql
```

- mastodon_db_1コンテナの中でbashを立ち上げます。

```
$sudo docker exec -it mastodon_db_1 /bin/bash
```
- postgreSQLサーバに接続できるか確かめます。

```
#psql -h [SQLの外部IP] -U postgres -l
```
もしくは

```
#psql -h [SQLの外部IP] -U postgres
>\l
>\q
```
のどちらかで、mastodonのデータベース一覧が出ます。たぶんpostgres,template0,template1の3つが見つかるはずです。\lでやった方は、表示させたあとに\qで終了しています。

- バックアップファイルを現在のデータベースにリストアします。

```
#psql -h [SQLの外部IP] -U postgres -f /tmp/for_restore.sql
```

- コンテナから出ます

```
#exit
```

##なんか間違ったかも、というとき##

うまく動かない場合は、一度データベースを削除してもう一度作ることもできます。(そのあとでリストアします)

```
#psql -h [SQLの外部IP] -U postgres -d template1
>drop database postgres;
>create database postgres;
>\q
```
私は別の理由[^2]で勘違いして何度もdbを作成し直したのでこの作業を行っていますが、おそらくリストアの際にデータベースの再作成は不要なはずです。


#再起動しよう#

- mastodonを起動します。

```
$sudo docker-compose down
$sudo docker-compose up -d
```

これで、外部SQL化したmastodonが動いているはずです。


[^1]: 見ればわかる通りこのIPアドレスは架空のものです
[^2]: postgreSQLのデフォルト接続先を示す環境変数が、コンテナ内のローカルファイルに向いています。ここを適切に変更するか-hで明示的に外部IPを指定しないと、psqlではそちらのDBをいじることになってしまいますし、それではmastodonの設定リストアにはなりません。