pleroma.ioというPleromaインスタンスを立てた

というわけで立てた.別におひとりさまインスタンスというわけじゃなく,新規登録も開放しています.特にテーマはない. ioドメインが取れたので, pleroma.io にしました.まぁゆるく .io のあたりから察していただけると.

https://pleroma.io

建てたっていうことを書きたかっただけなのだけど,一応中身の話を少し書いておく.

リポジトリ

Pleromaは, git.pleroma.social

ソースコードがある.おそらくこれは作者がホスティングしているGitLabサーバになるだろう. コントリビュートすることも考えて,もちろんここにアカウントは作成してあるのだが,ここからforkして自分のサーバのソースを管理するのはちょっと不便だった.

GitHubがいい. というわけで,ミラーリポジトリがある.

github.com

これをforkして使っている.

github.com

開発環境

とりあえず手元で動かしてデバッグを結構やったので,開発環境を作ってある.

Elixirのdocker開発環境は前から何度も作ったことがあるので,いつもどおりのdocker-compose.ymlを書く.

version: "3.0"
services:
  elixir:
    image: h3poteto/phoenix:1.7.3
    working_dir: /var/opt/app
    environment:
      MIX_ENV: dev
    volumes:
      - .:/var/opt/app
    ports:
      - "4000:4000"
    links:
      - db:db

  db:
    image: postgres:10-alpine
    environment:
      POSTGRES_USER: pleroma
      POSTGRES_PASSWORD: pleroma
      POSTGRES_DB: pleroma_dev
    volumes:
      - storage:/var/lib/postgres/data
      - ./config:/var/opt/pleroma/config

volumes:
  storage:

h3poteto/phoenix はいつも俺がphoenixの開発環境を作るときに使っている,ErlangとElixir,あとmysql-client等がインストールされたDocker image.

これであとは起動すればいい.

$ docker-compose run --rm --service-ports elixir /bin/bash
$ mix deps.get
$ mix migrate
$ mix phx.server

Pleromaは基本SPAでできているが,フロントはPleromaFEという別リポジトリで管理されており,ここでフロントエンドのJavaScriptコンパイルする必要はない. すでにコンパイル済みのものがリポジトリに含まれている.

本番

本番ももちろんDocker化してある.最近自分で運用するサービスはすべてDocker化した.これによりデプロイ方法が統一化されてだいぶ楽になった.

Dockerfileに関してはいろんな人がすでに公開しているので,特に目新しいことはない.

https://github.com/h3poteto/pleroma/blob/develop/dockerfiles/phoenix/Dockerfile

構成

基本的にすべてAWS ECSの上に載せている. なお,ECSの構成や各種TaskDefinitionはterraformで管理している.

ただし,環境変数,特に暗号化が必要になるパスワード等は,SSM Parameter Storeを利用し,そいつをKMSで暗号化している. その復号化処理をentrypointに差し込んでいる.

https://github.com/h3poteto/pleroma/blob/develop/dockerfiles/phoenix/entrypoint.sh

ECSのバックエンドは,SpotFleetを負荷に応じてAutoScaleさせたECS Clusterとなっている.

デプロイ

AWS ECSのデプロイとなる. CIとしてCircleCIを使っているので,developブランチにマージした際にはCircleCIからデプロイが走る.

https://github.com/h3poteto/pleroma/blob/develop/.circleci/config.yml

デプロイそれ自体は,俺が作っているECSのデプロイツールであるecs-goployを使っている.

github.com

で,こんな設定を書くとデプロイできる.

    steps:
      - run: &prepare_goploy
          name: Preparing ecs-goploy
          command: |
            wget https://github.com/h3poteto/ecs-goploy/releases/download/v0.4.0/ecs-goploy_v0.4.0_linux_amd64.zip
            unzip ecs-goploy_v0.4.0_linux_amd64.zip
            ./ecs-goploy version
      - run:
          name: migrate
          command: |
            set -ex
            NEW_TASK_DEFINITION=`./ecs-goploy update task-definition --base-task-definition ${RUN_TASK_DEFINITION} --image ${PHOENIX_ECR}:$CIRCLE_SHA1`
            ./ecs-goploy run task --verbose --cluster ${CLUSTER_NAME} --container-name phoenix --timeout 600 --task-definition $NEW_TASK_DEFINITION --command "mix ecto.migrate"
      - run:
          name: deploy
          command: |
            ./ecs-goploy update service --verbose --cluster ${CLUSTER_NAME} --service-name ${SERVICE_NAME} --image ${PHOENIX_ECR}:$CIRCLE_SHA1 --timeout 600 --enable-rollback --skip-check-deployments

証明書

MastodonもPleromaも,ドキュメントにはLet's Encryptを使う方法が書いてあり,みんなこれを頑張って更新しているらしい.

が,ECSに乗せている以上,当然ALBを使っているわけで,ACMを使えば証明書の管理からは開放される.というわけ自動更新です,はい.

アプリケーションの設定

既存の設定ファイルを変更し,fork元のrebaseで手間取りたくなかったので,自分の設定は別ファイルに切り出している. 幸いPhoenixにはsecetな設定を書くファイルを読み込む仕組みがあるので,

https://github.com/h3poteto/pleroma/blob/develop/config/prod.secret.exs

みたいな形で別ファイルに分離している.

Media Proxy

config :pleroma, :media_proxy,
  enabled: true,
  redirect_on_failure: true
  #base_url: "https://cache.pleroma.io"

たとえば,Federation network越しにリモートフォローした人が投稿したメディア等を,自分のサーバでキャッシュするかどうかを選択できる. もちろんこのキャッシュを入れると自分のサーバの容量はどんどん食われていく.

ただし,Mastodonも基本これはONになっている. また,他鯖に迷惑をかけないという意味でもキャッシュしておいたほうがいいような気がしている.

Upload

config :pleroma, Pleroma.Uploaders.S3,
  bucket: System.get_env("S3_BUCKET"),
  public_endpoint: "https://s3-ap-northeast-1.amazonaws.com"

config :ex_aws, :s3,
  access_key_id: [{:system, "AWS_ACCESS_KEY_ID"}, :instance_role],
  secret_access_key: [{:system, "AWS_SECRET_ACCESS_KEY"}, :instance_role],
  region: "ap-northeast-1",
  scheme: "https://"

config :pleroma, Pleroma.Upload,
  uploader: Pleroma.Uploaders.S3,
  strip_exif: false

ex_awsについては以前から触っていたので,設定はいつもどおり. 気をつけなきゃいけないのは, Pleroma.Uploaders.S3public_endpoint だ.

ファイルのアップロード先は,bucket で指定される. が,このアップロードされたファイルに外部からアクセスする際のURLを public_endpoint として設定している.

これは,たとえばCloudFrontを使ってS3の内容をキャッシュするような場合には,public_endpoint はCloudFrontのエンドポイントにしておく必要がある.

そういう意味で,

public_endpoint: "https://s3-ap-northeast-1.amazonaws.com"

と書いている.まぁこれはap-northeast-1のS3を直接見に行かせているだけなのだが.

感想

普通のPhoenixアプリケーションで,そこまで気をつけることもなかった.なんの問題もなく動いている. Elixirのアプリケーションを普段からデプロイしていれば,特に困ることはない.

アプリケーション固有の設定に関しては,公式のリポジトリに十分な説明が書いてあり,特に困ることはなかった.

負荷に関して言うと,Pleromaを建てたことにより特にインスタンスのスケールアップが発生していないところを見ると,本当に軽いんだろうな. アーキテクチャ的に考えても,並行処理でCPUは使うだろうけど,Railsみたいにいきなり500MB以上メモリを要求してくるようなことはない.

というわけでメインを https://mstdn.jp/@h3_poteto から https://pleroma.io/users/h3poteto に移住しました.