Misskeyサーバーを建ててみた

WEBサービス

Misskeyってなに?

Misskeyは分散型マイクロブログSNSを構築するオープンソースのソフトウェアです。
簡単に言えばTwitterのようなサービスを自分のサーバーで動かせるようにできるもので、類似のものとしてはMastdonなどがあります。

特徴としては分散型SNSとなっており別のサーバーのユーザーをフォローできたりします。
プロトコルにはActivityPubというオープンな規格を採用しているので前述したMastdonやその他同様のプロトコルを採用したサービスとも相互に連携することができます。

もちろん各ソフトウェアごとに独自の機能があったりするのでそういった部分では各自特色があるのですがフォローやいいね、Twitterで言うところのリツイート、引用などの基本機能は提供されています。

オープンソースなので色々な方が独自にサーバーを建てているのですが最大手として準公式的な扱いのMisskey.ioというサーバーがあります。
こちらのサーバーに2月はじめに登録してしばらく使っててとても居心地が良かったので自分でサーバーを立ててみることにしました。

その時の構築手順を備忘録として記載します。

参考記事としてのえるさんの記事がとてもわかりやすき一番よく参照しました。

サーバー構成

サーバーはVPS上に構築するようにしてDockerを使用して立ち上げるようにします。
またユーザーが投稿した写真などのメディアファイルの保管にはオブジェクトストレージを使用するようにします。(Misskeyにはファイル保管場所としてサーバー上に直接保存するかオブジェクトストレージに保存するか設定することが出来ます)

アクセスは基本HTTPSで行うようにします。
オブジェクトストレージは通常 https://【バケット名】.【Vultrのアドレス】といった形でアクセスできるのですが、今回はルートドメインをMisskeyのドメインと合わせたかったため

  • Misskeyサーバー https://misskey.example.com
  • オブジェクトストレージ https://misskey-drive.example.com

のような形でアクセスできるようにNginxでリバースプロキシを構成することにしました。

サーバー環境

VPSのサービスはVultrというところを利用しました。
初めて聞く会社でしたが、Misskey.ioの管理人である村上さんの推しているところだったので良さそうだと思い契約しました。
上述ののえるさん記事で契約画面詳細載っているので良ければそちらもご参照ください。

日本のリージョンも選べ東京と大阪を選択できます。
今回は東京リージョンを選択しました。
スペックは一番ベーシックなレギュラーパフォーマンスで以下の通り

  • 契約プラン:Vultr Cloud Compute Regular Performance
  • リージョン:Tokyo
  • OS:Ubuntu 22.04 LTS
  • CPU:1 vCPU
  • メモリ:2GB
  • SSD:55GB

別途追加料金でオートバックアップ等の機能もあるのですが今回は使用しませんでした。
このスペックで月$10(現在のレートで約1300円くらい)なので結構安いかと。

またサーバーとは別途オブジェクトストレージも契約しました。
有名所はAmazon S3ですが今回はこれもVultrのサービスを使用しています。APIはS3がデファクトスタンダードになっていることもあり問題なく使用することが出来ます。
こちらは1TBで月$5です。とても安い!

ただオブジェクトストレージは日本リージョンがないので一番地理的に近いシンガポールを選びました。

サーバーセットアップ

VultrのVPS契約ページでプランやOSを選ぶと設定が始まり、完了すると接続情報が表示されます。
まずはSSHでサーバーにアクセスし最低限の環境をセットアップすることから始めます。

ユーザー作成

デフォルトだとrootユーザーしかないのでまずは通常ユーザー作るところからですね。
Ubuntuなのでadduserコマンド使えます。(いつもuseraddとどっちか迷う)

adduser 【ユーザー名】 #パスワード入力になるので設定する
gpasswd -a 【ユーザー名】 sudo #sudo権限付与

passwordを設定したらユーザー切り替えができるか確認します。

su 【ユーザー名】

SSH設定

安全にSSH接続できるように公開鍵を登録します。(秘密鍵は事前にローカル環境で生成)

mkdir ~/.ssh
vi ~/.ssh/authorized_keys #生成した公開鍵をコピペする
chmod -R -rwx,u+rwX .ssh #パーミッション変更(file:rw, dir:rwx)

鍵を登録したら公開鍵認証で接続できるかテストしてみます。
もしこのとき不備があったら再接続できなくなる可能性もあるので、元の接続は残したまま新しいシェルから確認したほうが安全でしょう。

ssh -i /path/to/private_kay 【username】@【ip_address】

問題なく接続できたら次にrootでのログインとパスワード認証を無効化して公開鍵認証を有効化します。

sudo vi /etc/sshd_config

# 設定ファイル中の下記の部分を設定変更
PasswordAuthentication no
PermitRootLogin no

設定を変更したらSSHデーモンを再起動

sudo systemctl restart sshd.service

再度接続できるか確認してみましょう。
このときも設定に不備があると接続できなくなるので元の接続は残したまま新しいシェルから確認しましょう。

Dockerインストール

今回はDockerでMisskeyを導入したいのでDockerをインストールします。
下記の参考サイトを元にコマンドを実行します。

まずはインストールに必要なツールの導入

sudo apt update -y & sudo apt install -y ca-certificates curl gnupg lsb-release

Dockerのリポジトリを追加するためのキーを登録します。

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

aptでDockerを入れる準備ができたのでインストールします。

sudo apt update -y
sudo apt install -y docker-ce

インストールできたらDockerが入っていることを確認します。

sudo docker -v

このままだとDocker実行にsudoしないといけないのでsudoなしで動くようにグループを追加します。

sudo usermod -aG docker $USER

一旦ログインし直してsudoなしでDockerが動くことを確認します。

Nginxインストール

Misskey動かすだけでしたらDocker内でもNginx動くので必須ではありませんが、前述の通りリバースプロキシで動かしたいので導入しておきます。
aptで入れれるのでコマンドを実行します。

sudo apt install -y nginx

Misskeyインストール

サーバーのセットアップが終わったのでMisskeyをインストールします。
基本的にはMisskey公式資料のDockerインストール手順そのままで問題ありませんでした。
自分がインストールしたのは3月初旬でその時のバージョンは13.9.2でした。

また下記ののえるさんのブログ記事もv11の頃のものながらとてもわかり易いので参考になりました。

Misskeyリポジトリクローン

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

git clone -b master https://github.com/misskey-dev/misskey.git
cd misskey
git checkout master

設定ファイル変更

設定ファイルのサンプルをコピーして必要な設定を変更します。

cp .config/docker_example.yml .config/default.yml
cp .config/docker_example.env .config/docker.env
cp ./docker-compose.yml.example ./docker-compose.yml

変更箇所は以下の通り

default.yml

  • URLを自分のMisskeyで使用するドメインに変更
  • DBのユーザー、パスワードを変更

docker.env

  • DBのユーザー、パスワードをdefault.ymlに合わせて変更

docker build

設定ファイルの変更ができたのでdocker buildします。
イメージを構築するまで数十分時間がかかるので気長に待ちます。

docker compose build

DB初期化

docker buildが完了するとDBの初期化のためにコマンドを実行します。

docker compose run --rm web pnpm run init

Misskey起動

初期設定が終わったのでMisskeyを起動します。

docker compose up -d

コンテナが起動してしばらく経過するとHTTPで3000番にアクセスできるようになります。
この時点ではまだリバースプロキシを設定していないのでhttpsでの接続はできません。
手っ取り早く動いているか確認するためにcurl叩いてみました。

curl http://localhost:3000

オブジェクトストレージ設定

オブジェクトストレージを使えるように設定しておきます。
ここらへんの設定ものえるさん記事を大いに参考にしました。
Vultrのオブジェクトストレージ側の設定はそちらをご参照ください。

Misskey用のバケットを一つ作成しておきます。

bucketのポリシー設定

オブジェクトストレージはMisskeyにアップロードした各ユーザーのファイル(写真など)を保管するために使用します。
そのため保存したファイルを誰からでも参照できるように設定を変更する必要があります。

前述したようにVultrのストレージはS3 APIなので操作するためのツールをインストールします。

sudo apt install -y s3cmd

Vultrのオブジェクトストレージにアクセスできるように設定します。

s3cmd --configure

VultrのオブジェクトストレージページにあるAccess Key、 Secret Key、 S3 Endpointを入力して勧めていけば設定できます。

設定変更用のファイルを作成してVultrに送信します。

vi misskey-media_policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AddPerm",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::【バケット名】/*"
    }
  ]
}
s3cmd setpolicy misskey-media_policy s3://【バケット名】

DNS、CDN設定

ドメイン契約及びDNS、CDNとしてCloudflareを使用しているのでブラウザでログインして各種設定します。
設定詳細は省きますが最低限下記の設定をすれば動くかと

DNSレコードの設定

DNSレコードでMisskeyサーバーに指定したいドメインのAレコード(IPv4)、AAAAレコード(IPv6)を設定する。
プロキシの設定は有効にするようにしてください。

SSL設定

SSLの設定画面で暗号化モードをフル(厳密)にする。
この設定にするとサーバー上でもSSLの証明書認証が必要になるので後ほど設定します。

キャッシュをスキップするルールの設定

Misskey公式資料に従いのURLのうちapiはキャッシュしてほしくないのでスキップする設定にします。
ルールの設定からページルールを表示します。
ページルールを作成ボタンを押して

  • URL : [Misskeyサーバーのドメイン]/api/*
  • 動作 : キャッシュレベル:スキップ

と設定する。

SSL設定

Cloudflare側の設定ができたのでサーバー側のSSL設定を行います。
公式資料のcertbot設定の項目をもとに設定します。

certbotのインストール

SSL証明書の更新はcertbotで行うためaptで導入します。

sudo apt install -y certbot python3-certbot-dns-cloudflare

Cloudflare APIキー取得

CloudflareのページでAPIキーを取得します。
https://dash.cloudflare.com/profile/api-tokens

  • Global API KeyのViewを選択
  • パスワードを入力しhCaptchaを解除、Viewを選択

設定ファイル作成

Cloudflareの情報を記載した設定ファイルを作成します。

mkdir /etc/cloudflare
vi /etc/cloudflare/cloudflare.ini

設定ファイルの記載は次の通り

dns_cloudflare_email = [Cloudflareに登録しているメールアドレス]
dns_cloudflare_api_key = [取得したAPIキー]

ファイルのパーミッションを変更します。

sudo chmod 600 /etc/cloudflare/cloudflare.ini

Certbot実行

certbotコマンドを実行します。

sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare/cloudflare.ini --dns-cloudflare-propagation-seconds 60 --server https://acme-v02.api.letsencrypt.org/directory -d 【Misskeyのドメイン】 -d 【オブジェクトストレージのドメイン】

Nginx設定

リバースプロキシ用のNginxを設定します。
/etc/nginx/conf.d/以下にMisskeyドメインとオブジェクトストレージドメイン用それぞれの設定ファイルを作成します。

sudo vi /etc/nginx/conf.d/misskey.conf #Misskey用の設定
# 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 【Misskeyのドメイン】;

    # 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 【Misskey】;

    ssl_session_timeout 1d;
    ssl_session_cache shared:ssl_session_cache:10m;
    ssl_session_tickets off;

    # To use Let's Encrypt certificate
    ssl_certificate     /etc/letsencrypt/live/【Misskeyのドメイン】/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/【Misskeyのドメイン】/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 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_stapling on;
    ssl_stapling_verify 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_http_version 1.1;
        proxy_redirect off;

        # If it's behind another reverse proxy or CDN, remove the following.
        #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;

        # 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;
        proxy_force_ranges on;
        add_header X-Cache $upstream_cache_status;
    }
}

sudo vi /etc/nginx/conf.d/misskey-media.conf #オブジェクトストレージ用の設定
server {
    listen 80;
    listen [::]:80;
    server_name 【オブジェクトストレージのドメイン】;

    location / { return 301 https://$host$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name 【オブジェクトストレージのドメイン】;
    ssl_session_cache shared:ssl_session_cache:10m;

    ssl_certificate     /etc/letsencrypt/live/【オブジェクトストレージのドメイン】/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/【オブジェクトストレージのドメイン】/privkey.pem;

    ssl_protocols TLSv1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA;
    ssl_prefer_server_ciphers on;

    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://【バケット名】.sgp1.vultrobjects.com$request_uri;
      expires max;
    }
}

やっていることはまず80番(HTTP)で来た場合はHTTPSにリダイレクト
443に来た場合はSSLの設定と、Misseyの場合は3000番ポートにリダイレクト、オブジェクトストレージの場合はVultrのバケットにリダイレクトする設定です。

設定できたらnginxを再起動します。

sudo systemctl reload nginx

アクセス確認

ここまで完了するとMisskeyにアクセスできるようになります。
設定したドメインに繋いでみましょう。

初めてアクセスしたときはまずMisskeyサーバーの初期設定(サーバー名や管理アカウントの登録)画面になると思うので設定しましょう!
お一人様サーバーの場合は他の訪問者に勝手に登録されたくないと思うのでユーザーの登録を制限したり適切に設定しましょう。

オブジェクトストレージの利用設定

初期状態ではオブジェクトストレージは設定されていないのでサーバーに保存されるようになっているので、オブジェクトストレージに行くように設定しましょう。
(なにかファイルを保存したあとに設定変更してもそれ以前のファイルはサーバー側にあるため移動できないので注意)

管理ユーザーでMisskeyにアクセスすると右側メニューに「コントロールパネル」というボタンがあります。
クリックするとサーバー設定画面が出てくるのでその中のオブジェクトストレージを選択します。
画面の説明に従って設定するとオブジェクトストレージを使用する設定になります。
AccessKey、SecretはVultrのページで確認して入力しましょう。

楽しいMisskeyライフを!

これで全ての設定は終わりました。
あとはioなど他のサーバーのユーザーをフォローすれば相手の情報が流れてくるようになると思います。
自分だけのサーバーの完成です。

好きなカスタム絵文字を追加したりサーバーの説明を拡充したりして楽しみましょう!
余裕があればサーバーを開放して他のユーザーを受け入れて独自の文化を築いても楽しいでしょう。

自分のサーバーは3月はじめには建てていて忘れないようにテキストで備忘録書いていたのですがなかなかブログに記載できなくて数ヶ月経過してしまいました。
まだとりとめのない記述で初稿ですが一旦公開して置こうと思います。

コメント

タイトルとURLをコピーしました