おひとりさまPleromaの運用

2023-12-06T14:45:05.059Z

これは一関高専 Advent Calendar 2023の7日目の記事です。

はじめに

おひとりさまPleromaを建ててから4年以上経ちました。

今年はDBのデータを吹き飛ばすやらかしをして、別ドメインで新規鯖を動かすことにしたり、せっかくだしと構成を変えて2~3日つながらなかったりしていましが、いろいろと弄っているのも落ち着いたので現在の状況をまとめようと思います。

初期セットアップスクリプトとかの動作確認はしていないです。使う場合は注意してください。

使っているサービス

Vultr

Cloud Compute (100GB NVMe) + Backup Service

Marketplace Apps の Dockerのイメージから作成しています。

おひとりさまPleromaとしてはスペック高めですが、CodiMDやDicordBot、n8nなどが同居しているからです。

Amazon S3

メディア関係の保存先として使っています。

Cloudflare Pages

追加のフロントエンド(Soapbox-fe)のホスティングをしています。

環境

基本的に先駆者様に倣って作っています。Pleroma OTPリリース用のDocker設定ファイル群

プロダクション環境でDockerを使っています。Dockerネットワークは2つ用意します。

caddy

Caddyとアプリケーションが接続する

backend

DBとアプリケーションが接続する

Caddy Proxy

composeでCaddyでリバースプロキシを動かします。
他のコンテナのLabelを元にリバースプロキシの設定ができるので便利です。
wakuwakup/dc-caddy-proxy

DB

別のcomposeでPostgresを立ち上げています。
マネージドDBは大体ジョブキューでレートリミットに引っかかって死ぬのでやめましょう。試しにVultrのマネージドDBを使って死んだので危ないです。

version: '3'
volumes:
  postgresql-data:
    driver: local
networks:
  backend:
    external: true
services:
  postgres:
    image: postgres:latest
    container_name: postgresql
    restart: always
    volumes:
      - postgresql-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    networks:
      - backend

Pleroma

docker 関連のファイルと書き換えた静的ファイルを扱うディレクトリを用意しています。
docker 関連の方はリポジトリ内に秘匿情報が含まれてしまっているためプライベートになっています。

pl.waku.dev-custom

pleroma
| pl.waku.dev            <---- docker関連
|  | docker
|  |  | images
|  |  |  | otp
|  |  |  |  | Dockerfile
|  | compose-init.yml
|  | compose.yml
|  | pleroma.sh
| pl.waku.dev-custom     <---- カスタムした静的ファイル群

OTPリリースからコードを取得してDocker Imageを作っています。

// pleroma/pl.waku.dev/docker/images/otp/Dockerfile

FROM alpine:latest AS builder

ARG PLEROMA_VER=stable

ARG FLAVOUR=amd64-musl

#RUN export FLAVOUR=`arch="$(uname -m)";if [ "$arch" = "x86_64" ];then arch="amd64";elif [ "$arch" = "armv7l" ];then arch="arm";elif [ "$arch" = "aarch64" ];then arch="arm64";else echo "Unsupported arch: $arch">&2;fi;if getconf GNU_LIBC_VERSION>/dev/null;then libc_postfix="";elif [ "$(ldd 2>&1|head -c 9)" = "musl libc" ];then libc_postfix="-musl";elif [ "$(find /lib/libc.musl*|wc -l)" ];then libc_postfix="-musl";else echo "Unsupported libc">&2;fi;echo "$arch$libc_postfix"`

RUN apk add --no-cache \
    curl \
    unzip

RUN echo $FLAVOUR \
    && echo $PLEROMA_VER

ARG NOW_DATETIME
RUN echo $NOW_DATETIME

RUN curl https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/${PLEROMA_VER}/download?job=${FLAVOUR} -o /tmp/pleroma.zip \
    && unzip /tmp/pleroma.zip -d /tmp/pleroma/ \
    && rm /tmp/pleroma.zip

FROM alpine:latest

RUN apk -U upgrade \
    && apk add --no-cache \
    ncurses \
    file-dev \
    imagemagick \
    ffmpeg \
    exiftool \
    unzip \
    libcrypto1.1

ARG UID=911
ARG GID=911
ENV MIX_ENV=prod

RUN addgroup -S -g ${GID} pleroma \
    && adduser --system --shell /bin/false --home /opt/pleroma -D -G pleroma -u ${UID} pleroma

COPY --from=builder --chown=pleroma:root /tmp/pleroma/release/ /opt/pleroma

RUN mkdir --parents /var/lib/pleroma /etc/pleroma \
    && chown -R pleroma /var/lib/pleroma /etc/pleroma

USER pleroma

VOLUME ["/var/lib/pleroma/uploads", "/var/lib/pleroma/static", "/etc/pleroma"]

ENTRYPOINT ["/opt/pleroma/bin/pleroma"]

CMD ["start"]

EXPOSE 4000/tcp

composeは上で作ったイメージと追加のフロントエンドのglitch-lilyをnginxで動かしています。

webのvolumesでpl.waku.dev-customを持ってきています。
labelsではcaddyの設定を書いています。記法はこちらを参照してください。
https://github.com/lucaslorentz/caddy-docker-proxy

2.5.0で消えたマルチカラムUIのMasto-FEの代替としてglitch-lilyを使っています。
アップデート後に使えないと嘆いていましたが、どうにかなりました。

// pleroma/pl.waku.dev/compose.yml

version: "3.4"

services:
  web:
    build: docker/images/otp/.
    restart: always
    environment:
      MIX_ENV: prod
    ports:
      - "4000:4000"
    volumes:
      - ./data/pleroma/content/uploads:/var/lib/pleroma/uploads
      - ../pl.waku.dev-custom/static:/var/lib/pleroma/static
      - ./data/pleroma/config:/etc/pleroma
      - ~/ca/postgres.crt:/postgres.crt
    networks:
      - caddy
      - backend
    labels:
      caddy: "${PLEROMA_HOSTNAME}"
      caddy.1_@glitch-lily.path_regexp: "^/((500.html|embed.js|logo-cybre-glitch.gif|robots.txt|oops.gif|sw.js|background-cybre.png|oops.png|web-push-icon_expand.png|emoji/sheet_13.png|emoji/1f602.svg|badge.png|web-push-icon_favourite.png|clock.js|inert.css|riot-glitch.png|web-push-icon_reblog.png)|(web|assets|ocr|sounds|avatars|packs).*)"
      caddy.2_handle: "@glitch-lily"
      caddy.2_handle.reverse_proxy: "glitch-lily:80"
      caddy.3_handle.reverse_proxy: "web:4000"

  glitch-lily:
    image: nginx:latest
    container_name: glitch-lily
    restart: always
    tty: false
    volumes:
      - ./docker/setting/glitch-lily/templates:/etc/nginx/templates:ro
      - ../pl.waku.dev-custom/static/frontends/glitch-lily/servant:/var/www/html:ro
    networks:
      - caddy

networks:
  caddy:
    external: true
  backend:
    external: true

初期セットアップ用の追加のcomposeです。設定ファイル等をVolumeで保持するために使います。

// pleroma/pl.waku.dev/compose-init.yml

version: "3.4"
services:
  web:
    volumes:
      - ./data/pleroma/config:/tmp/config

管理用スクリプト pleroma.sh を作り、セットアップやバージョンアップなどのタスクを書いています。

#!/bin/sh
CMD=$1

cd "$(dirname "$0")"

usage() {
cat <<USAGE
Usage: $0 [command]
        setup            - build, configure, initialize
        build            - build images
        configure        - generate config files
        initialize       - initialize database
        start            - start Pleroma
        stop             - stop Pleroma
        update-code      - update script
        update-build     - update Pleroma images
        update-container - update Pleroma containers
        update           - update Pleroma images and containers
USAGE
}

build() {
        echo
        echo Building images
        docker compose build db
        docker compose build --build-arg NOW_DATETIME=$(date +%Y%m%d%H%M%S) --build-arg UID=$(id -u) --build-arg GID=$(id -g) web
}

mk_pleroma_config() {
        echo
        echo Generating Pleroma config
        echo "Pleromaのlisten address は 0.0.0.0 にしてください"
        echo
        mkdir -p data/pleroma/config/
        mkdir -p data/pleroma/content/uploads/
        mkdir -p data/pleroma/content/static/emoji/
        sudo chown -R 911:911 data/pleroma/content/uploads/
        sudo chown -R 911:911 data/pleroma/content/static/emoji/
        touch data/pleroma/config/config.exs
        PLEROMA_CFG_CMD='/opt/pleroma/bin/pleroma_ctl instance gen --force --output /tmp/config/config.exs --output-psql /tmp/config/setup_db.psql'
        docker compose -f compose.yml -f compose-init.yml run --no-deps --user root --entrypoint /bin/sh --rm web $PLEROMA_CFG_CMD
}

mk_config() {
        mk_pleroma_config
}

init_db() {
        echo
        echo Initializing database
        docker compose run --rm --entrypoint='/opt/pleroma/bin/pleroma_ctl migrate' web
        docker compose stop postgres
        docker compose rm --force postgres
}

start() {
        docker compose up -d
        docker compose ps
}

stop() {
        docker compose stop
}

update_code() {
        git pull
        git pull --recurse-submodules
}

update_build() {
        docker compose build --build-arg NOW_DATETIME=$(date +%Y%m%d%H%M%S) --build-arg UID=$(id -u) --build-arg GID=$(id -g) web
}

update_container() {
        docker compose down
        docker compose run --rm --entrypoint=/opt/pleroma/bin/pleroma_ctl web migrate
        docker compose up -d
}

if [ -z "$CMD" ]; then
        usage
        exit 1
fi
case "$CMD" in
        setup)
                build
                mk_config
        ;;
        build)
                build
        ;;
        configure)
                mk_config
        ;;
        pleroma-config)
                mk_pleroma_config
        ;;
        initialize)
                init_db
        ;;
        start)
                start
        ;;
        stop)
                stop
        ;;
        update-code)
                update_code
        ;;
        update-build)
                update_build
        ;;
        update-container)
                update_container
        ;;
        update)
                update_code
                update_build
                update_container
        ;;
        *)
                usage
                exit 1
        ;;
esac

Soapbox-FE

Soapbox-FEはGithub ActionsでビルドしてCloudflare Pagesにデプロイしています。

soapboxは.envにBACKEND_URLを書いてやると指定したバックエンド向けの静的ファイル群をビルドできます。ファイルを作ってビルドするコマンドを作ってやればCIにデプロイを任せられます。

詳細はこちらのリポジトリを見てください。
https://github.com/WakuwakuP/soapbox-builder

./builder.sh build <BACKEND_URL>

管理コマンド

## イメージビルドとコンフィグ生成
./pleroma.sh setup

## DB初期化
psql -f data/pleroma/config/setup_db.psql

## DBマイグレーション
./pleroma.sh initialize

## 起動
./pleroma.sh start

## 停止
./pleroma.sh stop

## 更新
./pleroma.sh update

おわりに

misskeyとかがよく話題に上がっていたりしますが、Pleromaコスト面でかなり優秀なのでおひとりさまを建てる場合は参考になればと思います。

分散SNS面白いのでぜひ界隈参入してみてください。まあ、弊鯖はおひとりさまなので新規登録を受け付けていないですが……

Miyulab