Oracle Cloud Always Free に Dolphin サーバーを立てる

# はじめに
インフラ素人です。
Oracle Cloud Always Free で分散 SNS の Dolphin を立ち上げることができたので記事を書くことにしました。

 <ins>[2021/01/02 追記] 内容や画像を2021年1月2日現在のものに差し替えました。</ins>

# 目標
Oracle Cloud Always Free で作成したインスタンスに、分散 SNS の [Dolphin](https://github.com/syuilo/dolphin) をインストールして CloudFlare を介して公開します。

Always Free では 2 つの VM インスタンスが無料で利用できるので、WEB AP サーバーと DB サーバーの 2 つのサーバーを立ち上げます。

オブジェクト・ストレージが <del>10 GB</del> <ins>20 GB</ins> まで無料で利用できるので、こちらも利用します。
<ins>参考: [Always Freeリソースの詳細](https://docs.oracle.com/cd/E97706_01/Content/FreeTier/resourceref.htm)</ins>

# 前提条件
* [Oracle Cloud Always Free で VM インスタンスを作成する](https://qiita.com/xianon/items/199e6794160e2c6da911)に従って VM インスタンスとオブジェクト・ストレージが作成されている
* 独自ドメインを購入している
* [CDNサービス「Cloudflare」を利用](https://deep-blog.jp/engineer/7072/)等を参考に独自ドメインで Cloudflare のネームサーバーを利用するように設定されている

<ins>執筆当時の Dolphin のバージョンは 1.4.0 です。</ins>

# 参考記事
この記事は [Dolphin の README](https://github.com/syuilo/dolphin/blob/develop/README.md) のインストール方法を基本として、足りない部分を Misskey Wiki の [Misskeyインストール方法詳説](https://join.misskey.page/ja/wiki/developers/installation) や [Misskeyのサーバを設置する（v11系） - noellabo's tech blog](https://blog.noellabo.jp/entry/2019/08/14/8i3RHuZ1wJNDinIn) 等を参考にして補足しています。

# DB サーバーの設定
まず DB サーバーから設定していきます。

DB サーバーに SSH 接続してください。

```shell:terminal
$ ssh dolphin-db
```

まずは apt でソフトウェアを最新の状態にします。

```shell:terminal
$ sudo apt update
$ sudo apt upgrade
```

この記事ではテキストエディタとして nano を使用します。
nano をインストールします。

```shell:terminal
$ sudo apt install nano
```

## PostgreSQL のインストール
PostgreSQL をインストールします。

```shell:terminal
$ sudo apt install postgresql
```

PostgreSQL のインストール時に Time zone の場所が聞かれる場合がありますので Asia/Tokyo を番号で選んでください。
Time zone が聞かれない場合でも`sudo dpkg-reconfigure tzdata`を実行すると Time zone を設定できます。

## ユーザーとデータベースの作成
PostgreSQL に`dolphin`ユーザーと`dolphin`データベースを作成します。

`psql`を実行して PostgreSQL に接続します。

```shell:terminal
$ sudo -u postgres psql
```

PostgreSQL に接続できるとプロンプトが`postgres=#`に変わります。

`dolphin`ユーザーをパスワード付きで作成し、`dolphin`ユーザーがオーナーの`dolphin`データベースを作成します。
パスワード(password)は適宜変更してください。

```sql:terminal
postgres=# CREATE ROLE dolphin LOGIN CREATEDB PASSWORD 'password';
postgres=# CREATE DATABASE dolphin OWNER dolphin;
```

このパスワードは後で使用しますので、控えておいてください。

PostgreSQL から切断します。

```sql:terminal
postgres=# \q
```

## PostgreSQL の設定変更
DB サーバーは WEB AP サーバーからアクセスされますが、PostgreSQL のデフォルトの設定では localhost からしか接続できないため、他サーバーからでもアクセスできるように設定します。

`postgresql.conf`ファイルを開きます。

```shell:terminal
$ sudo nano /etc/postgresql/12/main/postgresql.conf
```

`#listen_address = 'localhost'`の行を探し、次のように変更します。

```config:/etc/postgresql/12/main/postgresql.conf
listen_addresses = '*'          # what IP address(es) to listen on;
```

次に`pg_hba.conf`ファイルを開きます。

```shell:terminal
$ sudo nano /etc/postgresql/12/main/pg_hba.conf
```

最後の行の下に、次の設定を追加します。

```config:/etc/postgresql/12/main/pg_hba.conf
host    dolphin         dolphin         10.0.0.0/24             md5
```

設定を反映させるため PostgreSQL を再起動します。

```shell:terminal
$ sudo systemctl restart postgresql.service
```

## ファイアウォールの設定
WEB AP サーバーからアクセスできるように、ファイアウォールで PostgreSQL のポートを開けます。

iptables のルールファイルを開きます。

```shell:terminal
$ sudo nano /etc/iptables/rules.v4
```

ルールファイルから`-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT`の行を探し、その下に次の設定を追加します。

```config:/etc/iptables/rules.v4
-A INPUT -p tcp -m state --state NEW -m tcp --dport 5432 -j ACCEPT
```

ルールファイルの設定変更を反映させます。

```shell:terminal
$ sudo netfilter-persistent reload
```

以上で DB サーバーの設定は完了です。
`exit`で SSH 接続を切断してください。

```shell:terminal
$ exit
```

# WEB AP サーバーの設定
WEB AP サーバーを設定します。

WEB AP サーバーに SSH 接続してください。

```shell:terminal
$ ssh dolphin
```

まずは nano をインストールします。

```shell:terminal
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install nano
```

## スワップファイルの追加
Dolphin は Misskey から機能が大幅に削られて軽量になっているので私の環境ではメモリ 1 GB でも動作していますが、念の為にスワップファイルを 1 GB 追加しておきます。

```shell:terminal
$ sudo fallocate -l 1G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
```

`swapfile`が使用されているかどうか確認します。

```shell:terminal
$ free
              total        used        free      shared  buff/cache   available
Mem:        8165132      237156     7272456         964      655520     7681560
Swap:       1048572           0     1048572
```

Swap の total が 0 ではないので`swapfile`が使用されています。

このままではインスタンスを再起動した際にスワップファイルが使用されないため、起動時にスワップファイルを有効にする設定をします。

`fstab`ファイルを開いて次の設定を追加してください。

```shell:terminal
$ sudo nano /etc/fstab
```

```config:/etc/fstab
/swapfile	none	swap	sw	0 0
```

## 依存関係のインストール
Dolphin が依存するソフトウェアや、ビルドする際に必要となるソフトウェアをインストールします。

まずは apt でインストールできるものをインストールします。

```shell:terminal
$ sudo apt install build-essential git nginx python redis-server
```

## Node.js のインストール
Dolphin が依存しているソフトウェアの一つに Node.js がありますが、Ubuntu の apt でインストールできるバージョンは少し古いようです。

 <ins>[2021/01/02 追記]</ins>

 <del><a href="https://qiita.com/seibe/items/36cef7df85fe2cefa3ea">Ubuntuに最新のNode.jsを難なくインストールする</a>を参考にして n package で Node.js をインストールします。</del>

<del>```shell:terminal
$ sudo apt install npm
$ sudo npm install -g n
$ sudo n stable
$ sudo apt purge npm
$ sudo apt autoremove --purge
```</del>

Dolphin v1.4.0 で依存している Node.js のバージョンは 11.7.0 以上の指定なのですが、新しいバージョン 14 系だと正しく動きませんでした。
そのため、バージョン 12 系の Node.js を [NodeSource](https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions) からインストールします。

```shell:terminal
$ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt-get install -y nodejs
```

Node.js のバージョン確認コマンドで正しくインストールされたかどうか確認します。

```shell:terminal
$ node -v
v12.20.0
```

バージョンが返ってきたら正しくインストールされています。

## ファイアウォールの設定
WEB サーバーに外部からアクセスできるように、ファイアウォールで WEB のポートを開けます。

iptables のルールファイルを開きます。

```shell:terminal
$ sudo nano /etc/iptables/rules.v4
```

ルールファイルから`-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT`の行を探し、その下に次の設定を追加します。

```config:/etc/iptables/rules.v4
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
```

ルールファイルの設定変更を反映させます。

```shell:terminal
$ sudo netfilter-persistent reload
```

## ドメインの設定
Cloudflare でサブドメインの追加設定を行います。

CloudFlare にログインして、登録したドメインの DNS のページを開いてください。

![CloudFlare DNS](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535205/a9f5dbaf-4269-d64f-7cd0-c2f0e8e607eb.png)

独自ドメインに`dolphin`というサブドメインを設定します。

[こちら](https://qiita.com/xianon/items/199e6794160e2c6da911#web-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AB-ssh-%E6%8E%A5%E7%B6%9A)を参考にして Dolphin インスタンスのパブリック IP アドレスを控えてください。

「＋レコードを追加」ボタンをクリックし、次の値を入力してください。

| 項目                | 値                                           |
|:--------------------|:---------------------------------------------|
| タイプ              | A                                            |
| 名前                | dolphin                                      |
| IPv4 アドレス       | Dolphin インスタンスのパブリック IP アドレス |
| TTL                 | 自動                                         |
| プロキシ ステータス | プロキシ済み                                 |

入力したら「保存」ボタンをクリックして`dolphin`サブドメインの設定を保存します。

同様に、オブジェクト・ストレージ用の`dolphin-media`というサブドメインも設定します。
「＋レコードを追加」ボタンをクリックし、次の値を入力してください。

| 項目                | 値                                           |
|:--------------------|:---------------------------------------------|
| タイプ              | A                                            |
| 名前                | dolphin-media                                |
| IPv4 アドレス       | Dolphin インスタンスのパブリック IP アドレス |
| TTL                 | 自動                                         |
| プロキシ ステータス | プロキシ済み                                 |

入力したら「保存」ボタンをクリックして`dolphin-media`サブドメインの設定を保存します。

続けて CloudFlare の暗号化モードを設定します。
SSL/TLS のページを開いてください。

![CloudFlare SSL/TLS](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535205/7f565b28-369e-e7fe-82d9-77afcaeac896.png)

CloudFlare を介した全行程で SSL を有効にするため暗号化モードを「フル (厳密)」に設定します。

フル(厳密)の設定はイメージに表示されているように、サイトを利用するユーザーのブラウザから CloudFlare までと、CloudFlare から WEB サーバーまでの通信を SSL で暗号化します。

フル(厳密)にした場合、WEB サーバー側で SSL 証明書が必要となりますので Let’s Encrypt を利用します。

## Let’s Encrypt で証明書の取得
[Let&#39;s Encrypt（certbot）で、TLS-SNI-01の削除により証明書の更新に失敗する問題への対応 - noellabo&#39;s tech blog](https://blog.noellabo.jp/entry/2019/04/17/54MFy6cuWRsKUhQg)の「これからはdns-01を使おう」を参考にして Let's Encrypt で証明書を発行してもらいます。

`certbot`と`dns_cloudflare`プラグインをインストールします。

```shell:terminal
$ sudo apt install certbot python3-certbot-dns-cloudflare
```

`dns_cloudflare`プラグインを使用するためには CloudFlare にログインする E メールと、Cloudflare API の Global API Key が必要です。

Global API Key は CloudFlare の [API トークン](https://dash.cloudflare.com/profile/api-tokens) のページの Global API Key の「表示」ボタンから取得できます。

![CloudFlare API Tokens](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535205/4f8ffdc5-ad9d-8078-52c3-582dd6338fc0.png)

CloudFlare にログインする E メールと Global API Key を資格情報ファイルに記述します。

```shell:terminal
$ sudo nano /etc/letsencrypt/.cloudflare_credentials
```

```config:/etc/letsencrypt/.cloudflare_credentials
# Cloudflare API credentials used by Certbot
dns_cloudflare_email = CloudFlareにログインするEメール
dns_cloudflare_api_key = Global API Key
```

資格情報ファイルを root 以外のユーザーから見られないようにします。

```shell:terminal
$ sudo chmod 600 /etc/letsencrypt/.cloudflare_credentials
```

`certbot`で証明書を発行してもらう前に`--dry-run`オプションを付けて動作を確認します。
ここでは独自ドメインを`example.tld`、E メールを`admin@example.tld`としていますので適宜変更してください。

```shell:terminal
$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/.cloudflare_credentials -d dolphin.example.tld -d dolphin-media.example.tld -m admin@example.tld --manual-public-ip-logging-ok --agree-tos --no-eff-email --dry-run
```

`--dry-run`付きで`certbot`を実行して出力された文字列に The dry run was successful. のような文字があれば成功です。

`--dry-run`を外して実際に証明書を発行してもらいます。

```shell:terminal
$ sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/.cloudflare_credentials -d dolphin.example.tld -d dolphin-media.example.tld -m admin@example.tld --manual-public-ip-logging-ok --agree-tos --no-eff-email
```

出力された文字列に Congratulations! とあれば成功です。
fullchain.pem と privkey.pem ファイルのパスも一緒に表示されています。

Let’s Encrypt の証明書有効期限は 90 日間で、60 日ごとに自動的に更新するように設定することが推奨されているようです。
`certbot`のインストール時に`/etc/cron.d/certbot`にもファイルが保存されていて、有効期限が 30 日を切ると自動的に更新するように設定されています。

証明書が更新されても`nginx`は更新された証明書を読み込まないようなので、証明書が自動更新された際に`nginx`サービスをリロードするように設定します。

```shell:terminal
$ sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload.sh
```

```config:/etc/letsencrypt/renewal-hooks/deploy/reload.sh
#!/bin/bash
systemctl reload nginx.service
```

```shell:terminal
$ sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload.sh
```

## nginx の設定
Dolphin のリポジトリには`nginx`の設定ファイルのサンプルはないようなので、Misskey のリポジトリの設定ファイルを流用します。

```shell:terminal
$ sudo curl -Lo /etc/nginx/sites-available/dolphin.example.tld https://github.com/syuilo/misskey/raw/master/docs/examples/misskey.nginx
$ cd /etc/nginx/sites-enabled
$ sudo ln -s ../sites-available/dolphin.example.tld
$ sudo nano /etc/nginx/sites-available/dolphin.example.tld
```

設定ファイルのサーバー名の箇所を書き換えます。
以下、ダウンロード元の misskey.nginx の 2021年1月2日 時点のものからの変更したものを載せています。

```/etc/nginx/sites-available/dolphin.example.tld
# Sample nginx configuration for Misskey
#
# 1. Replace example.tld to your domain
# 2. Copy to /etc/nginx/sites-available/ and then symlink from /etc/nginx/sites-enabled/
#    or copy to /etc/nginx/conf.d/

# For WebSocket
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache1:16m max_size=1g inactive=720m use_temp_path=off;

server {
    listen 80;
    listen [::]:80;
    server_name dolphin.example.tld;    # Dolphin を設置するドメインに書き換える

    # For SSL domain validation
    root /var/www/html;
    location /.well-known/acme-challenge/ { allow all; }
    location /.well-known/pki-validation/ { allow all; }
    location / { return 301 https://$server_name$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name dolphin.example.tld;    # 書き換える
    ssl_session_cache shared:ssl_session_cache:10m;

    # To use Let's Encrypt certificate
    ssl_certificate     /etc/letsencrypt/live/dolphin.example.tld/fullchain.pem;    # 書き換える
    ssl_certificate_key /etc/letsencrypt/live/dolphin.example.tld/privkey.pem;    # 書き換える

    # To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate)
    #ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
    #ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    # SSL protocol settings
    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA;
    ssl_prefer_server_ciphers on;

    # Change to your upload limit
    client_max_body_size 80m;

    # Proxy to Node
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_http_version 1.1;
        proxy_redirect off;

        # For WebSocket
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Cache settings
        proxy_cache cache1;
        proxy_cache_lock on;
        proxy_cache_use_stale updating;
        add_header X-Cache $upstream_cache_status;
    }
}
```

続けて[Misskeyのサーバを設置する（v11系） - noellabo's tech blog](https://blog.noellabo.jp/entry/2019/08/14/8i3RHuZ1wJNDinIn)の「オブジェクトストレージにnginxでプロキシ接続」を参考にしてオブジェクト・ストレージ用の設定ファイルを作成します。

オブジェクト・ストレージのエンドポイントの URL へのアクセスを`https://dolphin-media.example.tld/`でプロキシします。
オブジェクト・ストレージのエンドポイントは[こちら](https://qiita.com/xianon/items/199e6794160e2c6da911#%E3%82%A8%E3%83%B3%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E7%A2%BA%E8%AA%8D)を参照してください。

先程作成した`dolphin.conf`を元にして書き換えます。

```shell:terminal
$ sudo cp /etc/nginx/sites-available/dolphin.example.tld /etc/nginx/sites-available/dolphin-media.example.tld
$ cd /etc/nginx/sites-enabled
$ sudo ln -s ../sites-available/dolphin-media.example.tld
$ sudo nano /etc/nginx/sites-available/dolphin-media.example.tld
```

```config:/etc/nginx/sites-available/dolphin-media.example.tld
   # proxy_cache_path まで不要
server {
    listen 80;
    listen [::]:80;
    server_name dolphin-media.example.tld;    # オブジェクト・ストレージ用のドメインに書き換える

    # For SSL domain validation
    root /var/www/html;
    location /.well-known/acme-challenge/ { allow all; }
    location /.well-known/pki-validation/ { allow all; }
    location / { return 301 https://$server_name$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name dolphin-media.example.tld;    # 書き換える
    ssl_session_cache shared:ssl_session_cache:10m;

    # To use Let's Encrypt certificate
    ssl_certificate     /etc/letsencrypt/live/dolphin.example.tld/fullchain.pem;    # Dolphin を設置するドメインに書き換える
    ssl_certificate_key /etc/letsencrypt/live/dolphin.example.tld/privkey.pem;    # 書き換える

    # To use Debian/Ubuntu's self-signed certificate (For testing or before issuing a certificate)
    #ssl_certificate     /etc/ssl/certs/ssl-cert-snakeoil.pem;
    #ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

    # SSL protocol settings
    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA;
    ssl_prefer_server_ciphers on;

    # Change to your upload limit
    client_max_body_size 80m;

    # Proxy to Node
    location / {    # ここからまるごと書き換える
        proxy_ignore_headers set-cookie;
        proxy_hide_header set-cookie;
        proxy_set_header cookie "";
        proxy_hide_header etag;
        resolver 8.8.8.8 valid=100s;
        proxy_pass https://エンドポイント$request_uri;    # オブジェクト・ストレージのエンドポイントを書き換えます
        expires max;
    }
}
```

作成した設定ファイルが間違っていないか確認します。

```shell:terminal
$ sudo nginx -t
```

ok や successful が表示されれば正しく設定されています。
failed が表示された場合は間違っている箇所を修正してください。

設定ファイルが正しいことが確認できたら`nginx`サービスをリロードします。

```shell:terminal
$ sudo systemctl reload nginx.service
```

## Dolphin ユーザーの作成
Dolphin サーバーを実行するための`dolphin`ユーザーを作成します。

```shell:terminal
$ sudo adduser --disabled-password --disabled-login dolphin
```

Full Name やら何やら色々聞かれますが、全て空欄のまま Enter でよいと思います。

## Dolphin のインストール
Dolphin をインストールするため`dolphin`ユーザーに切り替えます。

```shell:terminal
$ sudo -iu dolphin
```

Dolphin のリポジトリをクローンします。

```shell:terminal
$ git clone -b master git://github.com/syuilo/dolphin.git
```

dolphin ディレクトリにクローンされたので dolphin ディレクトリに移動します。

```shell:terminal
$ cd dolphin
```

Dolphin が依存しているパッケージをインストールします。

```shell:terminal
$ npm install
```

## Dolphin の設定ファイルの作成
設定ファイルのひな形をコピーして設定ファイルを編集します。

```shell:terminal
$ cp .config/example.yml .config/default.yml
$ nano .config/default.yml
```

以下、編集が必要な箇所のみ示します。

```config:.config/default.yml
#   ┌──────────┐
#───┘ Instance └────────────────────────────────────────────────

# Your instance name
name: 'Dolphin'    # Dolphin の名前 (サイトのタイトル)

# Your name
maintainerName: 'Your name'    # あなたの名前

#   ┌─────┐
#───┘ URL └─────────────────────────────────────────────────────

# Final accessible URL seen by a user.
url: https://dolphin.example.tld/    # Dolphin を設置する URL

#   ┌───────────────────────┐
#───┘ Port and TLS settings └───────────────────────────────────

# To use option 1, uncomment below line.
port: 3000    # A port that your Dolphin server should listen.

#   ┌──────────────────────────┐
#───┘ PostgreSQL configuration └────────────────────────────────

db:
  host: dolphin-db.privatesubnet.dolphinvcn.oraclevcn.com    # DB サーバーのプライベート IP アドレス
  port: 5432

  # Database name
  db: dolphin    # データベース名

  # Auth
  user: dolphin    # データベースのユーザー名
  pass: password    # データベースのユーザーのパスワード

#   ┌────────────────────────────────────┐
#───┘ File storage (Drive) configuration └──────────────────────

#drive:
#  storage: 'fs'    # こちらの設定はコメントアウト

# OR

drive:
  storage: 'minio'
  bucket: dolphin    # オブジェクト・ストレージのバケット名
  prefix: files    # オブジェクト・ストレージに保存される際の接頭辞
  baseUrl: https://dolphin-media.example.tld/dolphin    # オブジェクト・ストレージへアクセスするベースの URL
  endpoint: エンドポイント    # オブジェクト・ストレージのエンドポイント
#  port:
  useSSL: true
  accessKey: アクセス・キー    # オブジェクトストレージのアクセス・キー
  secretKey: 秘密キー    # オブジェクトストレージの秘密キー
```

File storage (Drive) configuration の設定について補足します。

`endpoint`はオブジェクト・ストレージのエンドポイントを指します。
オブジェクト・ストレージのエンドポイントは[こちら](https://qiita.com/xianon/items/199e6794160e2c6da911#%E3%82%A8%E3%83%B3%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E7%A2%BA%E8%AA%8D)を参照してください。
https:// は不要です。

`accessKey`と`secretKey`はオブジェクト・ストレージのアクセス・キーと秘密キーを指します。
オブジェクト・ストレージのアクセス・キーと秘密キーは[こちら](https://qiita.com/xianon/items/199e6794160e2c6da911#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%82%AD%E3%83%BC%E3%81%A8%E7%A7%98%E5%AF%86%E3%82%AD%E3%83%BC%E3%81%AE%E5%8F%96%E5%BE%97)を参照してください。

`baseUrl`に値を設定しないと Dolphin で生成されるメディアの URL がエンドポイントに直接アクセスするものになってしまいます。
メディアの URL も独自ドメインで生成されるようにするため、`baseUrl`を次のように設定してください。

`https://dolphin-media.example.tld/<バケット名>`

## Dolphin のビルド
次のコマンドで Dolphin をビルドします。

```shell:terminal
$ NODE_ENV=production npm run build
```

## データベースの初期化
次のコマンドでデータベースを初期化します。

```shell:terminal
$ npm run init
```

このコマンドで DB サーバーに接続してデータベースの初期化が行なわれます。

 <ins>[2021/01/02 追記] Node.js のバージョンを 14 系でインストールしてしまうとこのコマンドでエラーも出ずに何もされないまま終了してしまいます。14 系をインストールしてしまった場合は 12 系をインストールし直してください。</ins>

エラーとなってしまった場合は DB サーバーに接続できていない可能性があります。
[Oracle Cloud Always Free で Dolphin 用の VM インスタンスを作成する](https://qiita.com/xianon/items/199e6794160e2c6da911)で仮想クラウド・ネットワークの設定や、このページで設定した設定ファイルが間違っていないか確認してください。

## Dolphin の起動
Dolphin を通常起動します。

```shell:terminal
$ NODE_ENV=production npm start
```

起動すると Dolphin のバージョン等いくつかの情報が表示され、最後に
Now listening on port 3000 on https://dolphin.example.tld
の表示が出ていれば正常に起動できています。

この状態でブラウザから`https://delphin.example.tld/`にアクセスすると Welcome to Dolphin! のページが表示されます。

このままではインスタンスを起動するたびに Dolphin の起動コマンドを打たなくてはならないので、Dolphin をデーモン化します。

`Ctrl+C`で一旦 Dolphin を終了します。

`dolphin`ユーザーからログアウトします。

```shell:terminal
$ exit
```

## Dolphin のデーモン化
systemd で Dolphin をデーモン化します。

```shell:terminal
$ sudo nano /etc/systemd/system/dolphin.service
```

```config:/etc/systemd/system/dolphin.service
[Unit]
Description=Dolphin daemon

[Service]
Type=simple
User=dolphin
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/dolphin/dolphin
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=dolphin
Restart=always

[Install]
WantedBy=multi-user.target
```

systemd の設定ファイルを変更したので反映させるためにリロードします。

```shell:terminal
$ sudo systemctl daemon-reload
```

systemd で Dolphin を起動します。

```shell:terminal
$ sudo systemctl start dolphin.service
```

`systemctl status dolphin.service`を実行すると、サービスの状態が表示されます。

`journalctl -u dolphin.service`を実行すると、Dolphin を通常起動した際に標準出力されていた文字が表示されます。

正常に起動できている場合はブラウザから`https://delphin.example.tld/`にアクセスすると Dolphin のページが表示されます。

正常に起動できたらサービスを有効にしてインストール完了です。

```shell:termianl
$ sudo systemctl enable dolphin.service
```

## Dolphin を最新バージョンにアップデートする方法
基本は下に書いた流れでアップデートできますが、依存するソフトウェアのバージョンが上がったり増えたりして場合によっては手順が異なることがあるかもしれません。

そのような場合は [GitHub の Dolphin](https://github.com/syuilo/dolphin) のページを見るようにしてください。

アップデートは次のようにします。

Dolphin をインストールするため`dolphin`ユーザーに切り替えます。

```shell:terminal
$ sudo -iu dolphin
```

Dolphin のディレクトリに移動します。

```shell:terminal
$ cd dolphin
```

Dolphin のソースを最新版に更新します。

```shell:terminal
$ git pull
```

Dolphin が依存しているパッケージで差分があればインストールします。

```shell:terminal
$ npm install
```

Dolphin をビルドします。

```shell:terminal
$ NODE_ENV=production npm run build
```

データベースに更新があれば適用します。

```shell:terminal
$ npm run migrate
```

`dolphin`ユーザーからログアウトして、Dolphin サービスを再起動します。

```shell:terminal
$ exit
$ sudo systemctl restart dolphin.service
```

# まとめ
Oracle Cloud Always Free に Dolphin をインストールしました。

PostgreSQL の他サーバーからの接続の設定は Mastodon や Pleroma をインストールする場合でも使えると思います。

オブジェクト・ストレージは <del>10 GB</del> <ins>20 GB</ins> まで使用できますが、私の環境では 20 日程で 2.78GiB になりました。

 <del>Dolphin の設定でリモートのファイルをキャッシュしないようにしたり、アカウントごとのファイルのキャッシュ容量が変更できたりするので、容量が足りなくなったら調整すると良いでしょう。</del>

 <ins>Dolphin の設定でリモートのファイルをキャッシュできますが、Oracle Cloud Always Free で使える容量の 20GB はすぐに埋まってしまうので、リモートのファイルはキャッシュしないのをおすすめします。</ins>