Pleromaインストールバトル ～GCP無料枠編～

[Pleroma]はActivityPubで連合する分散SNSサーバーです。サーバーはElixirで実装されていて、軽量であることを特徴としています。GCP [Always Free] で使える、Google Compute Engine の無料枠を使って、Pleroma サーバーを設置してみました。

## GCE インスタンスの準備

GCPの無料枠でインスタンスを準備します。今回は、すでに設置していた未使用のGCPインスタンスをサーバーに使うことにしました。

- インスタンスタイプ: f1-micro
- リージョン: us-west1
- イメージ: Debian 10 (debian-10-buster-v20190813)
- ブートディスク容量: 10GB

無料枠では30GB以内の永続ストレージが使えるので、別途データディスクを追加すると良さそうですが、今回は行いませんでした。

## ドメイン名の準備

公開するWebサービスを作るには、ドメイン名が必要です。

私はドメイン名 `ryusei.dev` を持っていたので、このドメイン名の下で `pleroma.ryusei.dev` というFQDNを持つサーバーを公開することにしました。 

ドメイン名 `ryusei.dev` を管理する権威DNSサーバーの設定を書き換えて `pleroma.ryusei.dev` からGCEインスタンスのIPアドレスを引けるようにします。わたしはZEIT DNSを使っていたので、次のようなコマンドで設定しました。

```
now dns add ryusei.dev pleroma A 35.185.xxx.xxx
```

## Pleroma のインストール

インストールは[Installing on Debian Based Distributions]に沿ってやっていきます。日本語訳の[Pleromaの入れ方]もありますが、手順が少し違っています。私は英語版の手順に沿って進めていきました。

### 依存パッケージのインストール

依存パッケージをインストールしていきます。`wget` はインストールされていないので、かわりに `curl` を使いました。

```sh
sudo apt update
sudo apt full-upgrade
sudo apt install git build-essential
curl -o /tmp/erlang-solutions_1.0_all.deb https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i /tmp/erlang-solutions_1.0_all.deb
sudo apt update
sudo apt install elixir erlang-dev erlang-parsetools erlang-xmerl erlang-tools erlang-ssh
```

### ユーザー作成

Pleroma サーバーを動かすユーザー `pleroma` を作成します。

```sh
sudo useradd -r -s /bin/false -m -d /var/lib/pleroma -U pleroma
```

### Pleroma リポジトリのクローン

正規の手順では、以下のように `/opt/pleroma` に `stable` ブランチをクローンしてきます。

```sh
sudo mkdir -p /opt/pleroma
sudo chown -R pleroma:pleroma /opt/pleroma
sudo -Hu pleroma git clone -b stable https://git.pleroma.social/pleroma/pleroma /opt/pleroma
```

しかし、f1-microインスタンスでこのまま作業を進めると、メモリ不足でPleromaビルド時にエラーになってしまいました。そこで、ビルドまではローカル環境上で作業を進めてしまい、ビルド済みのファイルをサーバーに転送する方針にしました。ローカルで同様の環境を準備し、ここまでと同じように、依存パッケージをインストール、ユーザー作成、リポジトリのクローンを行います。私はWSL上のUbuntuで作業を行いました。

### Pleroma のビルド

`mix deps.get` コマンドでElixirの依存パッケージを取得し、`mix pleroma.instance gen`でビルドと設定ファイルの生成を行います。途中で`Hex`と`rebar3`のインストール確認があるので、両方`yes`と回答します。（このビルドをf1-microインスタンス上で行おうとすると、メモリ不足になります。）あとは、設定ファイルに関する質問があるので、適宜答えていきます。通知用のメールアドレスとか聞かれますが、これも適当に設定しました。後で直します。

```sh
cd /opt/pleroma
sudo -Hu pleroma mix deps.get
sudo -Hu pleroma mix pleroma.instance gen
```

設定ファイルが生成されたら、ファイルを移動し編集します。

```sh
cd /opt/pleroma
mv config/generated_config.exs config/prod.secret.exs
vim config/prod.secret.exs
```

`registrations_open` オプションをfalseに設定して、他の人の登録ができないようにしておきます。

```
  registrations_open: false
```

ここまでやったら `/opt/pleroma` 以下をtarballに固めて、f1-microインスタンスにコピーします。

### PostgreSQL のセットアップ

PostgreSQLをインストール・セットアップします。

```sh
sudo apt install postgresql postgresql-contrib
cd /opt/pleroma
sudo -Hu postgres psql -f config/setup_db.psql
sudo -Hu pleroma MIX_ENV=prod mix ecto.migrate
```

### certbot のセットアップ

初回はstandaloneメソッドで証明書を取得します。

```
sudo apt install certbot
sudo mkdir -p /var/lib/letsencrypt/ # このディレクトリはあとでwebrootメソッド使用時にに使う
sudo certbot certonly --email mandel59@gmail.com -d pleroma.ryusei.dev --standalone
```

### Nginx のセットアップ

Nginxをインストールし、設定ファイルをコピー・編集します。

```
sudo apt install nginx
sudo cp /opt/pleroma/installation/pleroma.nginx /etc/nginx/sites-available/pleroma.nginx
sudo vim /etc/nginx/sites-available/pleroma.nginx
```

certbotがHTTP-01メソッドで認証を受けられるように `/etc/nginx/sites-available/pleroma.nginx` の `location ~ /\.well-known/acme-challenge` 以下をアンコメントします。

```nginx
server {
    server_name    pleroma.ryusei.dev;

    listen         80;
    listen         [::]:80;

    # Uncomment this if you need to use the 'webroot' method with certbot. Make sure
    # that the directory exists and that it is accessible by the webserver. If you followed
    # the guide, you already ran 'mkdir -p /var/lib/letsencrypt' to create the folder.
    # You may need to load this file with the ssl server block commented out, run certbot
    # to get the certificate, and then uncomment it.
    #
    location ~ /\.well-known/acme-challenge {
        root /var/lib/letsencrypt/;
    }
    location / {
      return         301 https://$server_name$request_uri;
    }
}
```

設定を有効化します。

```sh
sudo ln -s /etc/nginx/sites-available/pleroma.nginx /etc/nginx/sites-enabled/pleroma.nginx
sudo systemctl reload nginx
```

証明書をwebrootメソッドで取得しなおします。（取得しなおさないで、`/etc/letsencrypt/renewal/pleroma.ryusei.dev.conf` を直接編集してもよいですが、確認のためにも、取得しなおしたほうがいいと思います。）

```sh
sudo certbot certonly --email mandel59@gmail.com -d pleroma.ryusei.dev --webroot -w /var/lib/letsencrypt/
```

rootのcrontabに毎日renewを掛ける設定を書いておき、証明書の期限切れに備えます。

```
0 0 * * * certbot renew -q --no-self-upgrade --deploy-hook 'systemctl reload nginx'
```

### Pleroma のサービス化

設定ファイルをコピーし、Pleromaをsystemdサービスにします。いちどサービス化してしまえば、他のサービスと同様に`systemctl`コマンドでサービスを管理できるようになります。

```
sudo cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
```

Pleromaを有効化・起動します。

```
sudo systemctl enable --now pleroma.service
```

### Pleroma ユーザー作成

Pleromaが起動した状態で、ユーザーを作成します。

```
sudo -Hu pleroma MIX_ENV=prod mix pleroma.user new mandel59 mandel59@gmail.com --admin
```

これで Pleroma のインストールは完了です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Pleromaインストールバトルに勝った <a href="https://t.co/kmvG6OFUTM">pic.twitter.com/kmvG6OFUTM</a></p>&mdash; Ryusei (@mandel59) <a href="https://twitter.com/mandel59/status/1184329141648158720?ref_src=twsrc%5Etfw">October 16, 2019</a></blockquote>

## カスタマイズ

`docs/config/static_dir.md` の記述に従い、`priv/static/` 以下のファイルを書き換えて、カスタマイズします。マージコンフリクトが気になる人は `instance/static/` に置いてもいいそうですが、どうなんでしょうか？ 別ディレクトリに設定を置くのは、動的にマージしているのと同じようなものだし、コンフリクトは手動で解決したほうがいいようにも思います。

[Always Free]: https://cloud.google.com/free/docs/gcp-free-tier?hl=ja#always-free
[Pleroma]: https://pleroma.social/
[Installing on Debian Based Distributions]: https://docs.pleroma.social/debian_based_en.html
[Pleromaの入れ方]: https://docs.pleroma.social/debian_based_jp.html