ChibisafeでセルフホストなStreamableを建てる

# 本記事の執筆背景

筆者は[streamable](https://streamable.com)を用いてゲームのクリップをよくDiscordで共有する。しかし、無料版だと250MB以内や7日で削除されてしまうという制約がある。そこで今回は[Chibisafe](https://github.com/chibisafe/chibisafe)をDocker+Caddy+Cloudflareでデプロイする。

# 動作環境
筆者の動作環境は以下の通りである。
- マシン: 以下の画像を参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/43e9af6c-cc98-4f07-a268-44a1c1c15ae7.png)
- Caddy: v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=
- Docker: 以下の画像を参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/f8b3e8fa-8742-4539-8f0c-ba9c0088b2bf.png)

# Caddyをインストールする
CaddyとはGoLangで作成されたWebサーバーである。(詳しくは[こちら](https://caddyserver.com)を参照)
インストール方法は公式ドキュメントと一緒だ。
特につまづくポイントはないので普通に実行する。

```bashsudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```

# Dockerをインストールする
特に難しくないのでこちらの記事を参考にインストール。
https://qiita.com/tf63/items/c21549ba44224722f301

# Chibisafeをインストールする
Chibisafeのインストールは少し特殊で、`docker pull`を利用しない。

1. `docker-compose.yml`と`Caddyfile`を作成する
今回はわかりやすくchibisafeというディレクトリを作成する。
```bash
mkdir chibisafe
```
`docker-compose.yml`を以下のように設定する。
```yml:docker-compose.yml
services:
  chibisafe:
    image: chibisafe/chibisafe:latest
    environment:
      - BASE_API_URL=http://chibisafe_server:8000
    expose:
      - 8001
    restart: unless-stopped

  chibisafe_server:
    image: chibisafe/chibisafe-server:latest
    volumes:
      - ./database:/app/database:rw
      - ./uploads:/app/uploads:rw
      - ./logs:/app/logs:rw
    expose:
      - 8000
    restart: unless-stopped

  caddy:
    image: caddy:2-alpine
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./uploads:/app/uploads:ro
    ports:
      - 24424:80
    environment:
      - BASE_URL=":80"
    restart: unless-stopped
```
Caddyfileを以下のように設定する
```bash:Caddyfile
{$BASE_URL} {
    route {
        file_server * {
                root /app/uploads
                pass_thru
        }

        @api path /api/*
        reverse_proxy @api http://chibisafe_server:8000 {
                header_up Host {http.reverse_proxy.upstream.hostport}
                header_up X-Real-IP {http.request.header.X-Real-IP}
        }

        @docs path /docs*
        reverse_proxy @docs http://chibisafe_server:8000 {
                header_up Host {http.reverse_proxy.upstream.hostport}
                header_up X-Real-IP {http.request.header.X-Real-IP}
        }

        reverse_proxy http://chibisafe:8001 {
                header_up Host {http.reverse_proxy.upstream.hostport}
                header_up X-Real-IP {http.request.header.X-Real-IP}
        }
    }
}
```

# Dockerのコンテナを起動する
いたってシンプルで`docker compose up`を実行するだけだ。
特に問題がなければ、`localhost:24424`でchibisafeが起動する。

# Caddyfileをさらに編集する
個人で見るだけなら起動で終わりだが、今回は共有をするためにリバースプロキシを設定する。
`/etc/caddy/Caddyfile`を編集していく。
```bash:Caddyfile
chibisafe.example.com {
    tls internal
    reverse_proxy localhost:24424 {
        trusted_proxies 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
        header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}
    }
}
```
Cloudflareを使用しない場合は、
```
chibisafe.example.com {
    reverse_proxy localhost:24424
}
```
でよい。

# ポートを開放する
今回は簡単なufwを使用する。
```bash
sudo ufw allow 80
sudo ufw allow 443
sudo ufw reload
```
Chibisafeは、Dockerで建てたChibisafeを自らのCaddyServerで束ねている。そのため、開放するポートは80番と443番のみでよい。

# Cloudflareを設定する
Discordで不特定多数に公開するということで、セキュリティ上の懸念が発生する。そのため、今回はCloudflareを使用してオリジンを隠し帯域を節約する。また、本記事では独自ドメインをCloudflareに登録する過程は省略する。

1. DNSを設定する
今回は以下のようにサブドメインでChibisafeのリバースプロキシを表示させる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/7b5d291d-fc20-490c-836c-3824a5ae114b.png)
2. SSL/TLSを設定する
今回はFullに設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/08cbcd9f-4d9c-4b9b-8dd9-61832190e2e5.png)

# Chibisafeの設定を編集する
特に問題がなければこれでChibisafeは自分のドメインでアクセスできるはずだ。
1. Chibisafeにログインする
自分のホストしたChibisafeにアクセスし、ログインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/17c4116b-ee57-45b2-9912-8370e6ebc0d3.png)
初期のログイン情報は
ユーザー名: `admin`
パスワード: `admin`
となっている。

2. パスワードを変更する
初期のパスワードは非常に脆弱なため、早急にパスワードを変更する。
Dashboard内のCredentialsに移動し、パスワードを変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/ccd22a9c-122a-4cea-a468-bed5dadddd93.png)

3. アップロードに必要な設定をする
アップロードの提供元を指定する必要があるため、設定する。
Admin内のSettingsに移動し、ドメインを指定する。`https://`を含む必要があることに注意する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/9b22b265-5abd-4fea-82a2-0fa7786f0f70.png)

4. アップロード上限を変更する
デフォルトでは1GBまでと個人的には少ないので最大サイズを変更する。
同じタブ内のUploadsのMax Sizeを変更する。
今回は5GB(`5000000000`)に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/66aa59e7-92af-4976-b1c4-dbb6edac6f06.png)

5. Customizationを編集する
こちらは必須ではないが、見栄えのため編集する。
同じタブ内のCustomizationに移動し、編集する。

6. 招待を発行する
デフォルトでは不特定多数に匿名でアップロードができないようになっている。
そのため、友人などがアカウントを登録する際は招待を発行する必要がる。
SettingsタブのInvitesに移動し、右上の`Create New Invite`をクリックし、招待を発行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/07a95b81-ccb6-4b38-b40e-804f79c6be65.png)

# 実際にアップロードをする
ルートディレクトリにアクセスすれば、ドラッグアンドドロップかファイル選択でアップロードができるはずだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/ca9dbd6c-ef0c-44a0-81d6-9b124243ba09.png)

# Q&A
Q. Dockerは起動しているのに、アクセスができない。
A. `/etc/caddy/Caddyfile`を修正する。
1. `ip a`を実行する
2. Dockerのインターフェースを探す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039129/bc42ff37-7d53-4084-ac7c-8bad72f89f90.png)
私の場合は`172.17.0.1`がDockerのインターフェースだった。
3. Caddyfileを編集する
```diff:Caddyfile
chibisafe.example.com {
    tls internal
--    reverse_proxy localhost:24424 {
++    reverse_proxy 172.17.0.1:24424 {
        trusted_proxies 173.245.48.0/20 103.21.244.0/22 103.22.200.0/22 103.31.4.0/22 141.101.64.0/18 108.162.192.0/18 190.93.240.0/20 188.114.96.0/20 197.234.240.0/22 198.41.128.0/17 162.158.0.0/15 104.16.0.0/13 104.24.0.0/14 172.64.0.0/13 131.0.72.0/22 2400:cb00::/32 2606:4700::/32 2803:f800::/32 2405:b500::/32 2405:8100::/32 2a06:98c0::/29 2c0f:f248::/32
        header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}
    }
}
```

Q. Cloudflareの料金は発生しますか
A. いいえ

Q. なんという会社のサーバーを使用していますか
A. ContaboのCloud VPS 6C 日本リージョンを使用しています。