コンテンツにスキップ

systemdでインストールする(RHEL系)

AlmaLinux 10 / Rocky Linux 10 / RHEL 10 を想定した、engawaをゼロから構築する手順です。9系以前には対応していません。

Ubuntu・Debianをお使いの場合は systemdでインストールする(Ubuntu / Debian) を参照してください。

項目 目安
サーバー メモリ4GB以上を推奨。ビルド時にメモリを多く使います
ドメイン 例: example.com。サーバーのIPアドレスを指すAレコード(IPv6ならAAAAレコード)を先に設定しておきます
メールサーバー 必須ではありませんが、ユーザー登録の確認メールを送るなら必要です
オブジェクトストレージ 必須ではありません。あとから管理画面で設定できます
  1. 必要なソフトウェアを入れる(Node.js・PostgreSQL・Valkey)
  2. engawa専用のユーザーとデータベースを作る
  3. ソースコードを取得してビルドする
  4. 設定ファイルを書く
  5. systemdサービスとして登録する
  6. リバースプロキシ(nginx)を立ててHTTPS配信する(SELinux・firewalldの設定を含む)

以下のコマンドは、sudo が使える一般ユーザーで実行してください。

1. 基本的なパッケージを入れる

Section titled “1. 基本的なパッケージを入れる”

システムを最新にして、ビルドに必要なツールを入れます。

ターミナルウィンドウ
sudo dnf upgrade -y
sudo dnf group install -y "Development Tools"
sudo dnf install -y python3 curl git

Development Tools と python3 は、engawaが使う一部のライブラリをビルドするために必要です。入れずに進むと、後の pnpm install で失敗します。

あとで使うEPELリポジトリも、この時点で追加しておきます。EPELのパッケージはCRBリポジトリに依存することがあるため、先にCRBを有効にします。

AlmaLinux・Rocky Linuxの場合:

ターミナルウィンドウ
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --set-enabled crb
sudo dnf install -y epel-release

dnf config-manager は dnf-plugins-core に含まれるコマンドです。最小構成の環境では入っていないことがあるため、先に入れておきます。

RHEL本体の場合(epel-release が標準リポジトリにないため、EPELが配布するRPMを直接入れます):

ターミナルウィンドウ
sudo subscription-manager repos --enable codeready-builder-for-rhel-10-$(arch)-rpms
sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm

engawaは動画を扱うために ffmpeg と ffprobe のコマンドをそのまま呼び出します。RHEL系の標準リポジトリにはffmpegが含まれていないため、別途追加する必要があります。

手軽なのはEPELの ffmpeg-free です。

ターミナルウィンドウ
sudo dnf install -y ffmpeg-free

特許で保護されたコーデックを含む完全版が必要な場合は、RPM Fusionを追加します。

ターミナルウィンドウ
sudo dnf install -y https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-10.noarch.rpm
sudo dnf install -y ffmpeg

どちらで入れた場合も、コマンド名は ffmpeg と ffprobe です。確認しておきます。

ターミナルウィンドウ
ffprobe -version

engawaにはNode.js 24以上が必要です。標準リポジトリのNode.js 24(nodejs24)は node ではなく node-24 というコマンド名で入り、以降の手順と合わないため、NodeSourceのリポジトリを追加します。

ターミナルウィンドウ
curl -fsSL https://rpm.nodesource.com/setup_24.x | sudo bash -
sudo dnf install -y nodejs

入ったか確認します。

ターミナルウィンドウ
node -v

v24. から始まるバージョンが表示されればOKです。

次に、パッケージマネージャーの pnpm を有効にします。engawaは npm や yarn ではなく pnpm を使います。

ターミナルウィンドウ
sudo corepack enable
ターミナルウィンドウ
pnpm -v

engawaにはPostgreSQL 15以上が必要です。この手順では、新しいバージョン(ここでは18)を使えるよう、PostgreSQL公式のYumリポジトリ から入れます。

ターミナルウィンドウ
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-$(uname -m)/pgdg-redhat-repo-latest.noarch.rpm
ターミナルウィンドウ
sudo dnf install -y postgresql18-server postgresql18-contrib

Ubuntuと違い、RHEL系では初期化が自動では行われません。公式リポジトリ版では、バージョンごとの専用コマンドを使います。

ターミナルウィンドウ
sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
sudo systemctl enable postgresql-18
sudo systemctl start postgresql-18

psql などのコマンドは /usr/bin からも使えるようにリンクされます。このページでは、複数のバージョンが入っていても確実に同じ版を使うよう、/usr/pgsql-18/bin/ からのフルパスで書いています。

初期設定では、ローカル接続がパスワードなしの認証(ident)になっています。このままだとengawaからの接続に失敗するので、設定を変更します。

ターミナルウィンドウ
sudo nano /var/lib/pgsql/18/data/pg_hba.conf

ファイルの下の方にある、127.0.0.1/32 と ::1/128 の行の最後の列を scram-sha-256 に書き換えます。

# IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256

保存したら、設定を読み込ませます。

ターミナルウィンドウ
sudo systemctl reload postgresql-18

RHEL 10系の標準リポジトリにはRedisがなく、互換実装のValkeyが入っています。engawaからはRedisとして接続できるので、これを使います。

ターミナルウィンドウ
sudo dnf install -y valkey
sudo systemctl enable --now valkey

動いているか確認します。

ターミナルウィンドウ
valkey-cli ping

PONG と返ってくればOKです。

engawaをrootで動かすのは避けたいので、専用のユーザーを作ります。

ターミナルウィンドウ
sudo useradd -m -s /bin/bash engawa

以降、engawa本体に関する作業はこのユーザーで行います。切り替えは次のコマンドです。

ターミナルウィンドウ
sudo -iu engawa

元のユーザーに戻るときは exit と入力します。このページでは、どちらのユーザーで実行するコマンドなのかを都度書いています。

元のユーザー(sudo が使えるユーザー)に戻ってから実行します。

ターミナルウィンドウ
sudo -u postgres /usr/pgsql-18/bin/psql

PostgreSQLのプロンプト(postgres=#)が出たら、次の3行を順に実行します。example-pass の部分は自分で決めたパスワードに置き換えてください。あとで設定ファイルに書くので、控えておきます。

CREATE ROLE engawa WITH LOGIN PASSWORD 'example-pass';
CREATE DATABASE engawa OWNER engawa;
\q

\q でプロンプトを抜けます。接続できるか、engawaユーザーの資格情報で確認しておくと安心です。

ターミナルウィンドウ
/usr/pgsql-18/bin/psql -h 127.0.0.1 -U engawa -d engawa -c '\conninfo'

パスワードを聞かれて接続できれば、手順3の認証設定は正しく反映されています。

7. ソースコードを取得してビルドする

Section titled “7. ソースコードを取得してビルドする”

ここからは engawaユーザー で作業します。

ターミナルウィンドウ
sudo -iu engawa

リポジトリを取得します。

ターミナルウィンドウ
git clone --branch develop https://github.com/bettaku/engawa.git engawa
cd engawa

依存パッケージを入れます。数分かかります。

ターミナルウィンドウ
pnpm install --frozen-lockfile

サンプルをコピーして編集します(engawaユーザーのまま)。

ターミナルウィンドウ
cp .config/example.yml .config/default.yml
nano .config/default.yml

最低限、次の項目を自分の環境に合わせます。

# 公開するURL。末尾のスラッシュは必要です
url: https://example.com/
# engawaが待ち受けるポート。nginxからここに中継します
port: 3000
db:
host: localhost
port: 5432
db: engawa
user: engawa
pass: example-pass # 手順6で決めたパスワード
redis:
host: localhost
port: 6379
# 手順11で立てるリバースプロキシを信頼します。
# これがないと、すべてのアクセス元IPがプロキシのIPとして記録されます
trustProxy:
- '127.0.0.1/32'
- '::1/128'
# サーバーを作った後は変更しないでください
id: 'aidx'

nano での保存は Ctrl+O → Enter、終了は Ctrl+X です。

他の項目もすべてコメント付きでサンプルに書かれているので、一度目を通しておくことをおすすめします。設定ファイルと環境変数の関係については バックエンドの環境変数、データベース接続の細かい調整については db.extra で指定できる設定 を参照してください。

9. ビルドしてデータベースを初期化する

Section titled “9. ビルドしてデータベースを初期化する”

engawaユーザーのまま、リポジトリのルートで実行します。

ターミナルウィンドウ
NODE_ENV=production pnpm build

ビルドが終わったら、データベースにテーブルを作ります。

ターミナルウィンドウ
pnpm migrate

ここまで成功したら、一度手動で起動して動作を確認します。

ターミナルウィンドウ
pnpm start

Now listening on port 3000 のような行が出れば成功です。Ctrl+C で止めて、次に進みます。

エラーが出た場合は、データベースのパスワードやValkeyの設定を見直してください。

10. systemdサービスとして登録する

Section titled “10. systemdサービスとして登録する”

exit でengawaユーザーを抜けて、元のユーザーに戻ります。

サービス定義ファイルを作ります。

ターミナルウィンドウ
sudo nano /etc/systemd/system/engawa.service

次の内容を貼り付けて保存します。

[Unit]
Description=engawa daemon
After=network-online.target postgresql-18.service valkey.service
[Service]
Type=simple
User=engawa
Group=engawa
UMask=0027
WorkingDirectory=/home/engawa/engawa
ExecStart=/usr/bin/node /home/engawa/engawa/packages/backend/built/boot/entry.js
Environment="NODE_ENV=production"
TimeoutSec=60
StandardOutput=journal
StandardError=journal
SyslogIdentifier=engawa
Restart=always
[Install]
WantedBy=multi-user.target

読み込んで起動します。

ターミナルウィンドウ
sudo systemctl daemon-reload
sudo systemctl enable --now engawa

状態を確認します。

ターミナルウィンドウ
sudo systemctl status engawa

active (running) と表示されればOKです。ログを見たいときは次のコマンドを使います。

ターミナルウィンドウ
sudo journalctl -u engawa -f

Ctrl+C で抜けられます。

11. リバースプロキシを立ててHTTPS配信する

Section titled “11. リバースプロキシを立ててHTTPS配信する”

engawaは localhost:3000 で動いていますが、このままでは外部からアクセスできません。nginxを前段に置いて、HTTPSでの配信と証明書の管理を任せます。

設定ファイルは、リポジトリの contrib/ に本番用のものが用意されています。ここではそれをそのまま使います。contrib/README.md も一度目を通してください。

ACMEモジュールが使えるのはnginx 1.29.0以降で、AppStreamのnginxには含まれていません。nginx公式リポジトリを追加します。

ターミナルウィンドウ
sudo tee /etc/yum.repos.d/nginx.repo > /dev/null <<'EOF'
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

AppStreamのnginxが既に入っている場合は、先に外しておきます。入っていなければ「一致するものが見つかりません」と出るだけなので、そのまま次へ進んでください。

ターミナルウィンドウ
sudo dnf remove -y nginx-core

公式リポジトリからインストールします。

ターミナルウィンドウ
sudo dnf install -y nginx nginx-module-acme

バージョンを確認します。

ターミナルウィンドウ
nginx -v

nginx/1.29.0 以上であればOKです。

/etc/nginx/nginx.conf を開きます。

ターミナルウィンドウ
sudo nano /etc/nginx/nginx.conf

ファイルの先頭付近、http { より外側に次の1行を追加します。

load_module modules/ngx_http_acme_module.so;

リポジトリの contrib/nginx.sample.conf を、nginxの conf.d にコピーします。

ターミナルウィンドウ
sudo cp /home/engawa/engawa/contrib/nginx.sample.conf /etc/nginx/conf.d/engawa.conf

ドメインと連絡先を自分のものに置き換えます。

ターミナルウィンドウ
sudo sed -i 's/engawa\.example\.com/example.com/g; s/admin@example\.com/you@example.com/g' /etc/nginx/conf.d/engawa.conf

中身を確認し、次の項目が環境に合っているかも見ておきます。

ターミナルウィンドウ
sudo nano /etc/nginx/conf.d/engawa.conf
項目 既定値 説明
resolver 1.1.1.1 1.0.0.1 ACMEモジュールが使うDNSサーバーです。社内DNSがあればそちらに変更します
ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt 上記のとおり /etc/pki/tls/certs/ca-bundle.crt に変更します
client_max_body_size 256m アップロード上限です。engawa側の maxFileSize と揃えます

nginx公式パッケージには、80番ポートを受ける既定の設定が付属しています。競合するので消しておきます。

ターミナルウィンドウ
sudo rm -f /etc/nginx/conf.d/default.conf

証明書とアカウント鍵の保存先を、nginxのworkerユーザーが読み書きできるように作ります。

ターミナルウィンドウ
sudo install -d -m 700 -o nginx -g nginx /var/lib/nginx/acme-engawa
sudo restorecon -R /var/lib/nginx/acme-engawa

restorecon は、SELinuxのラベルを正しい状態に直すためのコマンドです。

RHEL系では、既定のままだとnginxが他のプロセス(ここではengawa)へ中継することをSELinuxが禁止します。これを許可します。

ターミナルウィンドウ
sudo setsebool -P httpd_can_network_connect 1
ターミナルウィンドウ
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

80番はHTTPSへのリダイレクトだけでなく、証明書の初回取得と更新(HTTP-01認証)にも使われます。閉じないでください。

設定の文法を確認してから起動します。

ターミナルウィンドウ
sudo nginx -t
sudo systemctl enable --now nginx

syntax is ok と test is successful が出てから起動してください。すでに起動している場合は sudo systemctl reload nginx です。

初回の証明書発行には数十秒かかります。その間、HTTPSはまだ使えません。進行状況やエラーはnginxのログで確認できます。

ターミナルウィンドウ
sudo tail -f /var/log/nginx/error.log
ターミナルウィンドウ
curl -I http://example.com/

HTTP/1.1 308 Permanent Redirect が返ればHTTPからのリダイレクトは正常です。

ターミナルウィンドウ
curl -I https://example.com/

HTTP/2 200 が返れば、証明書の発行とengawaへの中継ができています。

ブラウザで https://example.com を開いて、初期設定画面が出れば完了です。最初に作ったアカウントが管理者になります。

手順11の代替: Caddy でHTTPS配信する

Section titled “手順11の代替: Caddy でHTTPS配信する”

nginxの代わりにCaddyを使う手順です。手順11を実行した場合、このセクションは不要です。 どちらも80番・443番を使うので、両方を同時に動かすことはできません。

Caddyは証明書の取得・更新とHTTPからのリダイレクトを標準機能で行うため、追加のモジュールは要りません。

RHEL系の標準リポジトリにはCaddyが含まれていないため、COPRから入れます。

ターミナルウィンドウ
sudo dnf install -y 'dnf-command(copr)'
sudo dnf copr enable -y @caddy/caddy
sudo dnf install -y caddy

バージョンを確認します。

ターミナルウィンドウ
caddy version

v2. から始まるバージョンが表示されればOKです。

ターミナルウィンドウ
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=443/udp
sudo firewall-cmd --reload

80番は証明書の取得と更新(HTTP-01認証)に使われるので、閉じないでください。443番のUDPはHTTP/3用です。使わない場合は省いて構いません。

nginxの場合と違い、Caddyでは httpd_can_network_connect の設定は通常必要ありません。Caddyのバイナリはnginxのようにウェブサーバーとしてラベル付けされておらず、SELinuxの制限を受けない状態で動作するためです。

もし502エラーが出る場合は、SELinuxが原因かどうかを次のコマンドで確認してください。

ターミナルウィンドウ
sudo ausearch -m AVC -ts recent

リポジトリの contrib/Caddyfile をコピーします。

ターミナルウィンドウ
sudo cp /home/engawa/engawa/contrib/Caddyfile /etc/caddy/Caddyfile

ドメインと連絡先を自分のものに置き換えます。連絡先は、証明書に関する通知がLet’s Encryptから届くアドレスです。

ターミナルウィンドウ
sudo sed -i 's/engawa\.example\.com/example.com/g; s/admin@example\.com/you@example.com/g' /etc/caddy/Caddyfile

中身を確認しておきます。

ターミナルウィンドウ
sudo nano /etc/caddy/Caddyfile

request_body の max_size(268435456 = 256 MiB)は、engawa側の maxFileSize と揃える値です。変更するときは両方を直してください。

Caddyには書式の整形と検証のコマンドがあります。起動前に通しておくと確実です。

ターミナルウィンドウ
caddy fmt --diff /etc/caddy/Caddyfile

差分が表示された場合は、書式の乱れがあるという意味です(動作しないわけではありません)。

ターミナルウィンドウ
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile

Valid configuration と出ればOKです。

ターミナルウィンドウ
sudo systemctl enable --now caddy

すでに起動している場合は sudo systemctl reload caddy です。

初回の証明書発行には数十秒かかります。進行状況やエラーはログで確認できます。

ターミナルウィンドウ
sudo journalctl -u caddy -f
ターミナルウィンドウ
curl -I http://example.com/

HTTP/1.1 308 Permanent Redirect が返ればHTTPからのリダイレクトは正常です。CaddyはHTTPからHTTPSへのリダイレクトを自動で設定します。

ターミナルウィンドウ
curl -I https://example.com/

HTTP/2 200 が返れば、証明書の発行とengawaへの中継ができています。

ブラウザで https://example.com を開いて、初期設定画面が出れば完了です。最初に作ったアカウントが管理者になります。

新しいバージョンが出たら、engawaユーザーで次の手順を実行します。

ターミナルウィンドウ
sudo systemctl stop engawa
sudo -iu engawa
cd engawa
git pull
pnpm install --frozen-lockfile
NODE_ENV=production pnpm build
pnpm migrate
exit
sudo systemctl start engawa

リリースノートに個別の作業が書かれている場合は、そちらを優先してください。

症状 確認すること
502 Bad Gateway まず sudo setsebool -P httpd_can_network_connect 1 が実行済みか確認します。RHEL系で最も多い原因です
外部からまったくつながらない firewalldでhttp/httpsを開けたか(sudo firewall-cmd --list-services)確認します
HTTPSにつながらない・証明書が発行されない ssl_trusted_certificate を /etc/pki/tls/certs/ca-bundle.crt に変えたか、80番が外部から到達できるかを確認します。詳細は /var/log/nginx/error.log に出ます
module ... is already loaded で起動しない load_module の行が nginx.conf と modules-enabled/ で重複しています。どちらか一方にしてください
アクセス元IPがすべて同じになる 設定ファイルの trustProxy が抜けています
サービスがすぐ落ちる sudo journalctl -u engawa -n 50 でエラーを確認します。設定ファイルの書式ミスが多いです
データベースに接続できない /var/lib/pgsql/18/data/pg_hba.conf が scram-sha-256 になっているか、sudo systemctl reload postgresql-18 を実行したか確認します
タイムラインが自動更新されない nginxのWebSocket設定(Upgrade と Connection のヘッダー)が抜けていないか確認します
ビルドが途中で止まる メモリ不足です。手順9のスワップ追加を試してください
Caddyを使っていて様子がおかしい sudo journalctl -u caddy -n 50 でログを確認します
動画のサムネイルが出ない ffprobe -version でffmpegが入っているか確認します。入れた後はengawaの再起動が必要です

SELinuxが原因かどうかは、次のコマンドで拒否ログを見ると判断できます。

ターミナルウィンドウ
sudo ausearch -m AVC -ts recent

設定ファイルを書き換えたときは、必ず sudo systemctl restart engawa で再起動してください。起動中のプロセスには反映されません。