彷徨うキムンカムイ

家の鍵失くしちゃった

ド素人がMisskeyインスタンスをAWSで立ち上げた方法のまとめ②(Misskeyが起動するまで)

前回の記事では、VPCを作成したりEC2インスタンスを立ち上げたり、Cloudflareでドメインを管理したり……などといった事前準備を行った。今回は、Web+appサーバーとDBサーバーのそれぞれでMisskeyを立ち上げるまでの作業を一気に紹介しようと思う。

  • 全体の事前準備(クラウドネットワーク構築など)→前回の記事はこちら

  • Web+appサーバーとして使用するEC2インスタンスでの作業※

  • DBサーバーとして使用するEC2インスタンスでの作業※
  • Misskeyのビルド+デプロイ+デーモン作成※
  • 定期バックアップ実行などの後処理

※:今回の記事にする部分
以下「Web+appサーバーとして使用するEC2インスタンスでの作業」は「Web+appサーバーでの作業」とのように表記。
 
▼目次

なお、本記事での解説は、概ね下記の記事に沿って進めている。
Ubuntu版Misskeyインストール方法詳説│Misskey Hub
Misskeyを手動で構築する

Web+appサーバーでの作業

まずはMisskeyの実行・動作のため必要なパッケージをインストール。その後にウェブサーバー(nginx)のインストールとSSL証明書の取得を行う。 Misskey Hubではufwファイアウォール)をホワイトリスト形式にして接続ポートを許可する手順の案内があるものの、今回はAWSのセキュリティグループで通信を制御しているため設定しない。

必要なパッケージのインストール

Misskey Hubによれば、下記のパッケージのインストール+corepackを有効にする作業が必要とのこと。

  1. Node.js (20.4.x以上)
  2. PostgreSQL (15以上)
  3. Redis
  4. FFmpeg
  5. build-essential(Debian/Ubuntuの場合)

Web+appサーバーに2と3は必要ない。そこで、1・4・5+corepackを有効にする作業を行うことになる。

▼最初にやるおまじない
Ubuntuの更新。おなじみのおまじないコマンド。

sudo apt-get update
sudo apt-get upgrade

▼Node.jsのインストール作業
標準リポジトリからのインストールだとメジャーバージョンが入ってくれないので、GitHub掲載の方法 に従って導入する。 ついでにcorepackも有効にしておく。

# GPGキーを入れ直し、メジャーバージョン=20.xをインストール
sudo rm /usr/share/keyrings/nodesource.gpg;
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg;
NODE_MAJOR=20; echo "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list;
sudo apt update;
sudo apt install -y nodejs;

# Node.jsがインストールされたので、バージョンを確認する。
node -v

# corepackを有効にする
sudo corepack enable

FFmpegのインストール
Misskeyのアプリ内で画像や動画の処理をさせるため必要。ドキュメントも一応確認しながら次の操作を行う。

# インストール
sudo apt-get -y install ffmpeg

# バージョン確認
ffmpeg -version

▼build-essentialをインストール
開発パッケージ。gitでインストールしていく。

# インストールコマンド
sudo apt install -y git build-essential

以上で前提となるパッケージの導入は完了。続いて、Webサーバーの設定を行う。

nginxの導入+設定

まずはドキュメントUbuntuへのインストール手順に従い、導入を進める。

# 前提となるパッケージのインストール
sudo apt install -y curl ca-certificates gnupg2 lsb-release ubuntu-keyring

# 署名鍵のインポート
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# 下記のコマンドで出力に 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 とあるか確認
# フィンガープリントが上記と異なればファイルを削除する必要がある
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

# リポジトリ設定
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx

# nginxのインストール
sudo apt update
sudo apt install -y nginx

次にnginxが起動しているか確認し、永続化させる作業を行う。

#  systemctlでデーモンの状態を確認。
systemctl status nginx

# 起動していなければ起動させ、永続化
sudo systemctl start nginx
sudo systemctl enable nginx

SSL証明書の取得
使用するドメインSSL証明書を取得し、格納されたファイルの場所をメモしておく(Misskeyの設定で必要)
取得はcertbotとCloudflareプラグインを利用して行う。ドキュメントなどを参照しながら進めていく。まずはインストールから。

# cetbotとCloudflareプラグインをインストール
sudo apt install -y certbot python3-certbot-dns-cloudflare

次に、CloudflareのAPI情報を設定ファイルに格納する。管理画面を開きながら作業。

# 設定ファイルを格納するディレクトリを作成
mkdir /etc/cloudflare

# 設定ファイルを作成+編集画面に遷移
nano /etc/cloudflare/cloudflare.ini

# nanoの編集画面で下記情報を入れる。
# dns_cloudflare_emailはCloudflareに登録しているメールアドレス
# dns_cloudflare_api_keyはグローバルAPIキー(確認方法は後述)
dns_cloudflare_email = bar@fuga.foo
dns_cloudflare_api_key = xxxxxxxxxxxxxxxxxxxxxxxxxx

# 設定ファイルを保存したら、パーミッションを変更
sudo chmod 600 /etc/cloudflare/cloudflare.ini

CloudflareのグローバルAPIを確認するには、管理画面左上のアイコンから「マイプロフィール」に進む。左メニューのAPIトークンを選択し、ページ下の方にスクロールすると、Global API Keyを表示させる項目が出てくる。ここをクリックしてパスワードを入力すると、上記設定ファイルに入れるべきキーが表示される。

マイプロフィールの「APIトークン」でグローバルIPの確認ができる
CloudflareのグローバルIPを確認する方法

さて、いよいよSSL証明書の取得に移る。コマンドは次の通り。

# 最後から3行目と2行目にあるexample.tldはMisskeyで使用するドメインに置換する
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 example.tld
-d *.example.tld \
--key-type rsa

コマンドの内容は次の通り。

  1. certbotを管理者権限(sudo)で実行し、新しい証明書を取得
  2. DNS認証にCloudflareプラグインを使用
  3. loudflare APIの認証情報が記載されたファイルのパスを指定
  4. DNSレコードの伝播時間を60秒と指定
  5. Let's EncryptのACMEサーバーのURLを指定
  6. 証明書を発行するドメインを指定
  7. サブドメインを含むワイルドカード証明書を指定
  8. キータイプの変更

途中出てくる質問に適当に回答して実行し終えると、SSL証明書(pemファイル)が格納されているディレクトリが表示される。これをどこかにコピー&ペーストして保存しておくか、ターミナルを分割するなどしていつでも確認できるようにしておく。

DBサーバーでの作業

PostgreSQLとRedisをインストールする。PostgreSQLについては、ユーザーとデータベース作成のほかに、Web+appサーバーからのアクセス許可をする必要がある(重要) まずは基本的な手順を一通り済ませる。

PostgreSQLのインストール+ユーザー&データベース作成
おまじないアップデートから行ってインストール、起動しているか確認。

# おまじないアップグレード
sudo apt-get update
sudo apt-get upgrade

# PostgreSQLインストール
sudo apt install -y postgresql-common
sudo sh /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -i -v 15;

# systemctlでデーモンの状態を確認。
sudo systemctl status postgresql

# 起動していなかった場合
sudo systemctl start postgresql

次にユーザーとデータベースの作成に入る。仮にユーザーはmisskey、データベース名はmk1とする。

# psqlに入る
sudo -u postgres psql

# ユーザー名とパスワードを作成
CREATE ROLE misskey LOGIN PASSWORD 'hogehoge';

# 先に作成したユーザーをオーナーとしてデータベースを作成
postgres=# CREATE DATABASE mk1 OWNER misskey;

とりあえずここまでやって、アクセス許可の設定は後回し。

▼Redisのインストール
大体こんな感じ。

# インストール
sudo snap install redis

# systemctlでデーモンの状態を確認。
sudo systemctl status redis-server

# 起動していなかった場合
sudo systemctl start redis-server

PostgreSQLのアクセス許可設定
Web+appサーバーとDBサーバーで分割する上で、最も重要なステップ。前者からのアクセス許可がポスグレ上で行われていないと、Misskeyアプリからのデータベース操作ができないし、投稿も閲覧も不可能になる。
そこで変更したいのがpg_hba.confの記述内容。これまで説明したPostgreSQLのインストール方法に沿うと、通常は/etc/postgresql/15/main/にある。nanoで開きつつ、AWSのコンソール上でWeb+appサーバーのプライベートIPを確認しながら作業しよう。

# nanoで開く(開かない時はsudo権限で)
nano /etc/postgresql/15/main/pg_hba.conf

# 最後の行に下記を追加。
#分かりやすいようにコメントで”Web+appサーバーからのアクセス許可”などと追加しておいても良い。
host    mk1             misskey         Web+appサーバーのIP/プレフィックス長          md5
hostssl mk1             misskey         Web+appサーバーのIP/プレフィックス長          md5

# 保存したのち、ポスグレ再起動
sudo systemctl restart postgresql

Misskeyのビルド+デプロイ+デーモン作成(Web+appサーバーで作業)

いよいよMisskeyのインストールを立ち上げる。
まずはユーザーを作成してgit cloneし、必要なnpmパッケージをインストール

# misskey用のユーザーを作成
sudo adduser --disabled-password --disabled-login misskey

# misskey用のユーザーに切り替え
sudo su - misskey

# git cloneする
git clone -b master https://github.com/misskey-dev/misskey.git --recurse-submodules

# cloneしたディレクトリに入る
cd misskey

# masterブランチに切り替え
git checkout master

# 必要なnpmパッケージをインストール
NODE_ENV=production pnpm install --frozen-lockfile

まだビルドはしない。misskeyの設定とnginxのリバースプロキシの設定が必要になるからだ。

misskeyの設定

urlの記述のほかに、DBがどこにあるのか指定する必要がある。まずは設定ファイルを作って開く。

# misskeyディレクトリ内で実行
nano .config/default.yml

記述内容はexample.ymlの通りだが、変更すべきポイントがある。 DBサーバーのプライベートIPが必要なので、AWSのコンソールを開いておこう。

  • 66行目:url: https://example.tld/https以降をMisskeyで使用するドメインを使用したアドレスに置き換える
  • 97行目~106行目:PostgreSQLの場所を指定(データベースサーバーに向ける)
  • 135行目~137行目:Redisの場所を指定(同上)

仮に、Misskeyで使用するドメインをhogehoge.com、データベースのユーザーはmisskey(パスワードはhoge-hoge)、データベース名はmk1だとすると、記述内容は次のようになる。

# ---66行目---
url: https://hogehoge.com/

# ---97行目~106行目---
db:
  host: <DBサーバーのプライベートIP>
  port: 5432

  # Database name
  db: mk1

  # Auth
  user: misskey
  pass: hoge-hoge

# ---135行目~137行目---
redis:
  host: <DBサーバーのプライベートIP>
  port: 6379

nginxの設定

いったんルート権限に戻り、nginxのリバースプロキシ設定を書く。ここは公式の手順と大きな違いはない。

# ルート権限に戻る(AWSの場合はubuntuに戻る)
exit

# nginxの設定ファイルを作り、開く
sudo nano /etc/nginx/conf.d/misskey.conf

設定ファイルにはMisskeyのドキュメントの内容をコピペ、下記のように編集する。

  • 18行目と30行目のドメイン
  • 34-35行目の証明書へのパスをCertbotで取得したものに (基本的にexample.tldを置き換えるだけでOK)
  • 56行目 (If it's behind another reverse proxy or CDN, remove the following.) から4行を削除

同じくhogehoge.comをドメインとして使用すると仮定すると、以下のようになるはず。

# 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 hogehoge.com;   # hogehoge.comに置き換え

    # 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 hogehoge.com;   # hogehoge.comに置き換え

    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/hogehoge.com/fullchain.pem;   # SSL証明書取得時に表示されたpemキーの場所
    ssl_certificate_key /etc/letsencrypt/live/hogehoge.com/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;

       # ここにあったはずの4行は削除

        # 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;
    }
}

nginxの設定ファイルを保存したら、キチンと機能しているか確認する。 エラーが出たら「余計な行が入っている」などの可能性があるため、もう一度設定ファイルを開いて見直し。

# 機能確認
sudo nginx -t

# デーモン再起動
sudo systemctl restart nginx

# デーモンのステータスを確認。activeならOK
sudo systemctl status nginx

ここまで終わったら、いよいよMisskeyのビルド+デプロイに入る。

Misskeyのビルド+デプロイ

まずはmisskeyユーザーに変更し、ディレクトリ内に入る。

sudo su - misskey
cd misskey

Misskeyのビルド+デプロイへ

# データベースの初期化
pnpm run init

# Misskey起動
NODE_ENV=production pnpm run start

万一にもエラーが出たら、次の項目を確認する。

  • DBサーバーのpg_hba.confでアクセス許可設定を適切に行えているか?
  • DBサーバーのredis-serverは動いてるか?(systemctlで確認)
  • Misskeyのdefault.ymlの設定は適切か?

起動はしているようだがアクセスできない……そんなときはCloudflareの設定をチェックする。

  • DNSレコードはきちんと設定されているか?(Web+appサーバーのElasticIPに向けられているか)
  • SSL/TLS暗号化モードは「フル(厳格)」になっているか?

きちんと起動し、アクセスもできたら、いったんctrl+Cでキルしてexitでubuntuユーザーに戻る。いよいよ最後のステップ。

Misskeyデーモン作成

systemctlでステータスチェックや起動・停止・再起動ができるように、デーモンを作成しておく。 まずはubuntuユーザーで下記コマンドを入力し、nanoでファイルを開く。

sudo nano /etc/systemd/system/misskey.service

ファイルが開いたら、下記をコピー&ペースト。UserとWorkingDirectoryを適切に設定する。作成したMisskeyユーザーの名前が"misskey"だとすれば、次のようになる。

[Unit]
Description=Misskey daemon

[Service]
Type=simple
User=misskey  # 作成したユーザー名を入力
ExecStart=/usr/bin/npm start
WorkingDirectory=/home/misskey/misskey  #通常は/home/作成したユーザー名/misskeyになる
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=journal
StandardError=journal
SyslogIdentifier=misskey
Restart=always 

[Install]
WantedBy=multi-user.target

これでひとまずMisskeyで遊べるようになった。

Misskeyのアプリケーションの起動・停止・ステータスチェックの方法

デーモンを作成できたら、ubuntuユーザーから次のコマンドで起動・停止・ステータスチェックなどができるはず。

# Misskeyの起動
sudo systemctl start misskey

# Misskeyの停止(更新作業などの際に行う)
sudo systemctl stop misskey

# Misskeyの状態確認
sudo systemctl status misskey

# Misskeyの再起動(設定ファイルを変更した場合など)
sudo systemctl restart misskey

ここまでの作業を終えたら、あとはWebブラウザからMisskeyの管理者アカウントを作り、コントロールパネルでモデレーションをやっていくだけ。 その方法については続く記事で紹介する。