本文へ移動

Vercelに置く(サーバー版) ​

サーバー版のAxeで遊ぶための部屋のサーバーを、Vercelに置く手順です。Cloudflare版と同じ部屋のサーバーが、VercelとRedisとVercel Blobの上で動きます。かかる時間は、アカウント作りを含めて1時間ほどです。

どちらにするか迷ったら、長く安定して置けるCloudflare版をすすめます(→ どれを置くか)。Cloudflare版との違いは、次のとおりです。

項目Cloudflare版Vercel版
部屋の状態部屋ごとのDurable ObjectRedis。部屋のWebSocketを受けたインスタンスの1つが部屋を受け持ち、ほかのインスタンスはそこへ中継する
部屋のアセットR2Vercel Blob(private)
WebSocketの長さ切れないFunctionの最大実行時間(無料のプランは300秒)まで。その前に部屋のサーバーが閉じて、Axeが静かにつなぎ直す
1回のアップロード種類ごとの上限(画像2MiB、音声10MiB)まで4,000,000バイトまで。それより大きい音声は、AxeがBlobへ直接上げる
時間が過ぎた部屋を消す部屋ごとのアラーム一覧・作る・入るのついでと、1日1回のVercel Cron
画像と音声のキャッシュデータセンターに置く(カスタムドメインのとき)無い

つなぎ直しのあいだも、ほかの人には、出たことも入ったことも見えません。ただし、つなぎ直す一瞬に届いた効果音やダイスを転がす演出などは、まれにその人の画面に出ないことがあります。卓の物はつなぎ直したあとにそろいます。費用の目安は費用と上限にあります。

VercelのWebSocketはベータです

部屋のサーバーは、VercelのWebSocketを使います。VercelのWebSocketは、2026年10月の時点でベータです。

Vercelの画面は英語です

Vercelの画面は英語だけです。このページでは、ボタンやメニューの名前を画面の表示のまま英語で書きます。

0. 用意するもの ​

途中で、次の値を入れたり控えたりします。パソコンの中にメモのファイルを1つ作り、そこに貼り付けながら進めると迷いません(→ 秘密の値の扱い)。

値手に入れるところ使う手順
AxeのOrigin設置の準備手順3
DiscordのClient ID手順1手順3
DiscordのClient Secret手順1手順3
SESSION_SECRET設置の準備手順3
部屋のサーバーのURL手順8手順8、9、10

1. Discordのアプリを作る ​

部屋に入るときのログインに、Discordを使います。Discordのアプリを作るの手順で、アプリを作り、Client IDとClient Secretを控えます。

Discordのアプリに登録する戻り先のURL(Redirects)は、サーバーのURLが決まってから足します(手順8)。ここでは、Client IDとClient Secretを控えるところまで進めます。

2. Deployボタンを押す ​

下のボタンを押します。トークン発行のボタンとは、入れる環境変数が違います。

Deploy with Vercel

このリポジトリapps/vercelプログラムの元。ここは書き換わらない
Deployボタン
あなたのGitHub複製されたリポジトリボタンが作る、あなたのもの。ここが変わると、デプロイし直される
自動でデプロイ
あなたのVercel
  • Function部屋のサーバーのプログラム
  • Redis部屋と一覧とアカウント(あとでつなぐ)
  • Vercel Blob画像と音声(あとでつなぐ)
できあがるサーバーのURLhttps://my-udonarium-rooms-vercel.vercel.app
Deployボタンを押すと、この順に作られます

New Projectの画面が開くので、複製先のリポジトリを作ります。画面の進みかたは、Vercelに置く(SkyWay版)の手順3と同じです。リポジトリの名前の欄には、my-udonarium-rooms-vercelが入っています。そのままで構いません。

3. 環境変数を入れる ​

Add Environment Variablesのカードに、環境変数を入れる欄が4つ出ます。左のNameには名前が入っているので、右のValueに値を入れます。

名前入れる値
ACCESS_CONTROL_ALLOW_ORIGINAxeのOrigin(例:https://axe.example.com)。*は使えない
DISCORD_CLIENT_ID手順1で控えたClient ID
DISCORD_CLIENT_SECRET手順1で控えたClient Secret
SESSION_SECRET自分で作った64文字の乱数(→ 設置の準備)

ACCESS_CONTROL_ALLOW_ORIGINに*と書くと、Discordから戻る先として認めないので、だれもログインできません。AxeのOriginを、名前で書いてください。

4. デプロイする ​

Deployを押し、ビルドが終わるのを待ちます(1〜2分ほど)。「Deployment completed.」と出て、デプロイできたことを知らせる画面に変わったら、ダッシュボードへ進むボタンを押して、プロジェクトの画面に進みます。

この時点では、まだRedisとBlobのストアがつながっていません。そのため、部屋のサーバーはconfig-invalidを返します。次の手順でつなげば直ります。

5. Redisをつなぐ ​

Redisは、部屋の状態、部屋の一覧、ログインした人のアカウントを置くデータベースです。VercelのMarketplaceから、Upstashの無料のRedis(Upstash for Redis)を作ってつなぎます。

  1. プロジェクトの画面で、左のサイドバーのStorageを開きます。
  2. データベースを作るボタン(Create DatabaseかCreate Storage)を押し、Marketplaceのデータベースの一覧を出します。
  3. 一覧から、Upstash for Redis(Upstashの行)を選びます。名前がRedisだけの行は、Redis Cloudという別のサービスなので選びません。
  4. Installを押します。初めてUpstashを使うときは「Install Upstash」の画面が出るので、Create New Upstash Accountを選んでContinueを押します。
  5. Primary Region(置く場所)で、東京(Tokyo、hnd1)を選びます。部屋のサーバーも東京で動くので、近くに置くと速くなります。あとから変えられません。
  6. Read Regionsは空のまま、Evictionはオフのままにします。Evictionをオンにすると、データベースがいっぱいになったときに、部屋のデータが消されることがあります。
  7. プラン(料金の種類)は、無料のFreeを選び、Continueを押します。Prod PackとAuto Upgradeは有料のものなので、選びません。
  8. Database Nameに名前(例:udonarium-rooms)を入れ、Createを押します。
  9. できたデータベースの画面で、Connect Projectを押します。
  10. 「Connect Project」の画面で、このプロジェクトを選びます。Environmentsは、Development、Preview、Productionのすべてにチェックが入ったままにします。Custom Prefixの欄は空のままにします。
  11. Connectを押します。

Freeのプランで作れるデータベースは、1つのUpstashのアカウントに1つまでです。1か月に使えるコマンドの数などにも上限があります。部屋に人がつながっているだけでも1時間に1,900回ほど使い、同じ部屋の人が別々のインスタンスにつながると、やりとりもRedisを通るので、卓1つで使い切ることもあります(→ 費用と上限)。

つないだら、変数が入ったかを確かめます。

  1. 左のサイドバーのEnvironment Variablesを開きます。
  2. 一覧に、REDIS_URLかKV_URLがあるかを見ます。ほかにKV_REST_API_URLなどの変数も入りますが、部屋のサーバーは使いません。

どちらかがあれば、次に進みます。どちらも無いときは、REDIS_URLを手で足します。Upstashのデータベースの画面に出ている、rediss://で始まる接続先の文字列をコピーし、NameをREDIS_URL、Valueをその文字列にしてSaveを押します。https://で始まるもの(REST APIのURL)は使えません。

6. Blobのストアをつなぐ ​

Vercel Blobは、部屋に置いた画像と音声の置き場です。

  1. 左のサイドバーのStorageを開き、Create Storageを押します。
  2. Blobを選び、Continueを押します。
  3. アクセスの種類をPrivateにします。Publicにすると、URLを知っている人ならだれでも画像と音声を読めてしまいます。あとから変えられないので、間違えたときは作り直します。
  4. 置く場所(リージョン)を選ぶ欄で、東京(Tokyo、hnd1)を選びます。これも、あとから変えられません。
  5. 名前(例:udonarium-rooms-assets)を入れて、Create a new Blob storeを押します。
  6. つなぐ環境を尋ねられます。最初はProductionとPreviewにチェックが入っているので、そのままにします。

つなぐと、BLOB_STORE_IDとBLOB_READ_WRITE_TOKENなどの変数がプロジェクトに入ります。Environment Variablesの一覧で、BLOB_STORE_IDがあるかを確かめます。Vercelの上では、これで読み書きできます。

7. デプロイし直す ​

RedisとBlobの変数は、いま動いているデプロイには入っていません。デプロイし直して、読み込ませます。やりかたは、Vercelに置く(SkyWay版)の「設定を直す」の、デプロイし直す手順と同じです。Deploymentsのいちばん上のデプロイの … からRedeployを選び、ビルドのキャッシュは使わずにデプロイし直します。

8. URLを控えて、Discordに戻り先を登録する ​

プロジェクトの画面の最初のページ(Overview)に、本番のドメインが出ています。my-udonarium-rooms-vercel.vercel.appのような名前です。この前にhttps://を付けたものが、部屋のサーバーのURLです。

Discordのアプリに戻り先を登録します(→ Discordのアプリを作る)。登録するURLは、部屋のサーバーのURLの後ろに/v1/login/discord/callbackを付けたものです。

text
https://my-udonarium-rooms-vercel.vercel.app/v1/login/discord/callback

*-git-*.vercel.appのような、プレビューのデプロイのURLは使えません。プレビューのURLはデプロイのたびに替わるので、そこからはログインできません。

9. 動いているか確かめる ​

ブラウザで、部屋のサーバーのURLを開きます。

text
https://my-udonarium-rooms-vercel.vercel.app/

{"message":"Hello udonarium-backend-vercel!"}と出れば、サーバーは動いています。

続いて、設定が読めているかを確かめます。次のURLを開きます。

text
https://my-udonarium-rooms-vercel.vercel.app/v1/login/discord
出たもの意味
{"error":"invalid-request"}正しく動いています。ログインに要る情報をブラウザから付けていないので断っています。Axeから開くときは、Axeが付けます
{"error":"login-unavailable"}ログインの3つ(DISCORD_CLIENT_ID、DISCORD_CLIENT_SECRET、SESSION_SECRET)が入っていません
{"error":"config-invalid"}設定が足りないか、形が違います。下のログを見てください

config-invalidのときは、左のサイドバーのLogsを開きます。足りない設定の名前が、ログに出ています。無料のプランでは、ログは1時間しか残らないので、URLを開いた直後に見てください。直したら、手順7のとおりデプロイし直します。

ターミナルが使えるなら、Originを付けて確かめることもできます(→ 設置の準備)。{"providers":["discord"]}と返れば、ログインが使えます。

sh
curl -H "Origin: https://axe.example.com" https://my-udonarium-rooms-vercel.vercel.app/v1/auth/config

10. Axeにつなぐ ​

Axeを配信している場所のassets/config.jsonを開き、transportを"server"にして、backend.urlに部屋のサーバーのURLを書きます。書きかたは設置の準備にあります。

json
{
  "transport": "server",
  "backend": {
    "url": "https://my-udonarium-rooms-vercel.vercel.app"
  }
}

書き換えたconfig.jsonを配信先に置き直して、Axeを開きます。

  1. ロビーの上に「Discordでログイン」が出ていれば、Axeが部屋のサーバーにつながっています。
  2. 「Discordでログイン」を押し、Discordの画面で許可します。Axeに戻り、ログインした名前が出れば、ログインは成功です。
  3. 部屋を作ります。作った人がGMになります。
  4. ほかのブラウザ(または別の人)から同じ部屋に入れれば、完成です。ログインしていない人は、見学として入ります。

Axe側の設定の詳しい意味は、Axeの設定にあります。

掃除の鍵を入れる(任意) ​

時間が過ぎた部屋と、消し残した画像や音声を消す掃除は、vercel.jsonに書いたVercel Cronが1日1回呼びます(/internal/sweep)。ADMIN_STORAGE_ALERT_GBを入れていれば、掃除のあとに置き場所の使用量も数えます(→ ADMIN_STORAGE_ALERT_GB)。環境変数CRON_SECRETに乱数を入れておくと、Vercel Cronのほかからは呼べなくなります。入れないときは、だれでも呼べるので、掃除は12時間に1回までです。それより早く呼ばれると、掃除せずに429を返します。

  1. 設置の準備と同じ方法で、乱数を作ります。SESSION_SECRETとは別のものにします。
  2. 左のサイドバーのEnvironment Variablesで、NameをCRON_SECRET、Valueを作った乱数にし、種類をSecretにしてSaveを押します。
  3. 手順7のとおりデプロイし直します。

SkyWayのトークン発行と一緒に置く ​

同じプロジェクトにSKYWAY_APP_IDとSKYWAY_SECRETも入れれば、SkyWay版のトークン発行も受け持ちます。別々のプロジェクトに分けても構いません。環境変数の足しかたは、Vercelに置く(SkyWay版)の「設定を直す」と同じです。

独自ドメインで公開する ​

自分のドメインで公開するときは、プロジェクトのSettingsのDomainsから足します。足したあとは、次の3つをそろえて新しいドメインに変えます。

  • Axeのbackend.url
  • Discordのアプリに登録した戻り先のURL(新しいドメインのものを足す)
  • 確かめるときに開くURL

Discordの戻り先は、Axeのbackend.urlと同じドメインで登録します。ドメインが違うと、DiscordがInvalid OAuth2 redirect_uriを出して、ログインできません。

更新するとき ​

Vercelに置く(SkyWay版)の「更新するとき」と同じです。新しいプロジェクトを作り直すときは、古いプロジェクトにつないでいたRedisとBlobのストアを、新しいプロジェクトにつなぎます(手順5と手順6の、つなぐところ)。つなげば、部屋と画像はそのまま使えます。Discordの戻り先とAxeのbackend.urlも、新しいURLに変えます。

うまくいかないとき ​

サーバー版で困ったときを見てください。

MITライセンスで公開しています