KUMODeck
EN

ホスティングとデプロイ

kumodeck deploy <dir>は、静的ファイルのフォルダ(ビルド済みのWebアプリやゲーム)を、環境の新しいバージョンとして公開します。すべてのバージョンは残り、切り替えは一瞬です。サーバーで画面を作るアプリ(Next.js・Astro・SvelteKit・Nuxt・React Router・TanStack Start・Honoなど)も公開できます(サーバーで画面を作るアプリ)。

ホスティングは任意です。アプリはどこに置いてもかまいません(自分のサーバー、itch.io、CDN)。その場合もKUMODeckのほかの機能はすべて使えます(ほかのサイトに公開鍵を使われたくない場合は、そのオリジンをweb.allowedOriginsに書きます)。ホスティングしたアプリはアプリ専用のサブドメイン(または自分のドメイン)で配信され、KUMODeckのブランド表示は入りません。

デプロイする#

kumodeck deploy dist --env production     # production(deploy の既定は development)
kumodeck deploy dist --env development -m "new boss fight"
kumodeck deployments                      # バージョンの一覧(* = 公開中)
kumodeck rollback 12                      # バージョン 12 を即座に公開状態へ戻す
環境URL
productionhttps://<slug>.kumodeck.app/
developmenthttps://<slug>--dev.kumodeck.app/
ローカルサーバーhttps://api.kumodeck.com/play/<slug>/とhttps://api.kumodeck.com/play/<slug>--dev/

フォルダにはindex.htmlが必要です。ドットファイルとnode_modulesは除外され(.well-known/は含まれます)、シンボリックリンクはたどりません。

サーバーで画面を作るアプリ#

サーバーでページを作るアプリ(vinextかOpenNextを使うNext.js=下、Cloudflareのアダプタを入れたAstro、SvelteKit、Nuxt、フレームワークの形のReact Router、TanStack Start、Hono、SolidStart)は、Cloudflare Workersに出すときと同じ形(Workerと静的アセット)で公開できます。既定はOFFですが、kumodeck deployがその環境のserverRendering(と、それに要るhosting)をONにし、1行で知らせます(静的なデプロイがhostingをONにするのと同じ)。自分でONにするならkumodeck features on serverRendering && kumodeck config push --env development(hostingも一緒にONになります)。

kumodeck deploy --env development --dry-run   # ビルドして、公開せずに KUMODeck で確かめる
kumodeck deploy --env development             # ビルドして、新しいものだけ上げて公開する

プロジェクトのフォルダで、フォルダを付けずに実行します。CLIは次の順に進めます。

  1. 見分ける: 直下にmainのあるwrangler.jsoncがあるか、package.jsonにサーバーの形のフレームワークがあるか。どちらでもないとき(またはkumodeck deploy dist・kumo.jsonのdeployDirがあるとき)は上の静的なデプロイです。--app・--staticで上書きできます。
  2. wrangler.jsoncがまだ無ければwrangler setup --yesを動かします(Cloudflare自身の設定の仕組みがアダプタを入れます)。
  3. 手元でビルドし(npm run build。ロックファイルがあればpnpm・yarn・bun)、wrangler deploy --dry-run --outdir .kumo/app-buildでまとめます。wranglerはCloudflareに何も送らず、KUMODeckもあなたのコードをビルドしません。
  4. KUMODeckで試しの確認をして(大きさ・上げるファイル・作るデータベース・警告)、新しいファイルだけを上げ、公開のバージョンを切り替えます。

プロジェクトにwranglerが入っている必要があります(npm install -D wrangler)。無いときはビルドの出力を静的なファイルとして上げ、そのことを1行で知らせます。--jsonには見分けの結果・ビルドのコマンド・送ったものが出ます。

  • 配る場所: https://<slug>.kumodeck.app/・https://<slug>--dev.kumodeck.app/・独自ドメイン。/play/の下では配りません。POST(フォーム・Server Actions)もアプリに届きます。
  • 静的かアプリか: 環境が配るのは、公開中のバージョンのどちらか一方です。kumodeck rollbackで静的とアプリのバージョンを即座に行き来できます。
  • データベースとファイル: wrangler.jsoncのD1・KV・R2・Queueの送り手は環境ごとに作られ、Functionsとbindingの名前で共有されます。
  • アプリのデータベース: 表を作るのはkumodeck db migrate DB、読み書きはkumodeck db query DB "SELECT …"(kumodeck functions db …と同じ)。FunctionsをONにする必要はありません。db migrateはアプリのwrangler.jsoncのそのデータベースのmigrations_dirのフォルダを読みます(既定migrations)。SQLの誤りはd1_query_errorとデータベースの文で返ります。SQLを直してください。
  • ログ: アプリがconsole.log / console.errorで出した行は7日間残ります。kumodeck logs(Functionsと時刻順に混ぜて。アプリだけなら--source app)かMCPツールfunctions_logsで読みます(ログ)。行はFunctionsのログと同じく原価で課金されます。kumodeck deploy --no-logsではその版のログを残しません。アプリにログが付く前にデプロイした版はapp_logs_unavailableを返します: もう一度デプロイしてください。起動で例外を投げるコードはapp_script_errorで返り、details.errorに例外の文が入ります。
  • 秘密の値: kumodeck functions secret put NAMEでFunctionsとアプリの両方に入ります。varsに秘密を書かないでください(秘密らしい名前にはデプロイが警告します)。
  • 定期実行: アプリのWorkerはcronを持てません。Functionsに置きます。
  • Cookie: KUMODeckはアプリのSet-CookieからDomain=を外すので、Cookieはアプリ自身のホストにだけ付きます。
  • まだ使えないもの: 画像の最適化(画像はそのまま配る)・ISR・Durable Objects・service binding・ネイティブのモジュール。代わりの方法はdeployのSkillにあります。
  • 料金: アプリのリクエストとCPUを、前払い残高から原価で。

Next.js#

Next.jsは、vinext(CloudflareがViteで作り直したNext.js)でビルドするのがおすすめです。OpenNext(@opennextjs/cloudflare)も逃げ道として残ります。どちらも今はISRなしです。kumodeck deployは、package.jsonにvinextがあればvinext、OpenNextだけが入っていればOpenNextを使います。どちらも無いときは止まり、両方の打つ行を表示します(next_adapter_choice)。1回のデプロイだけ選ぶなら--next vinext・--next opennextです。

vinext(おすすめ) — Node.js 22.18以上が要ります。

  1. 入れます: npm install -D vinext(pnpm・yarn・bunならadd -D vinext)。
  2. npx vinext checkを動かし、✗の付いた所を直します。
  3. 一度だけ次を動かします(vite.config.tsとcloudflare.config.tsを書きます。3つの選択を付けないと、止まって聞いてきます)。

``sh npx vinext init --platform=cloudflare --cdn-cache=none --data-cache=none --image-optimization=none ``

  1. kumodeck deploy。CLIは(上の2〜3の代わりに)vinext checkとvite buildを動かし、.cloudflare/output/v0を上げます。あなたのファイルは書き換えません。Cloudflareのアカウントも要りません。
  • vinext checkがvinextの対応しない物を見つけると、デプロイがそれを並べます。OpenNextが入っていれば今回はOpenNextでデプロイします。並んだ所を直してもう一度デプロイすると、vinextを使います。OpenNextが無ければ止まります(vinext_check_failed)。それでもvinextで試すならkumodeck deploy --next vinextです。
  • 画像の最適化(imagesOptimizer・bindings.images())があるとデプロイは止まります。vinextはそれが無いと実行時に落ちるので、外して送れません。--image-optimization=noneでinitしてください。画像はそのまま配られます。
  • アセットのbindingの名前はASSETSのままにします(vinext initが書くとおり)。

OpenNext(逃げ道) — vinextがまだ対応しないアプリや、vinextで動かないとき用です。OpenNextのとき、上の3はopennextjs-cloudflare build(中でnext buildを動かす)になり、CLIがビルド時に作ったページをアセットに写します(.open-next/cache → .open-next/assets/cdn-cgi/_next_cache)。

  1. @opennextjs/cloudflareとwranglerを入れます。wrangler.jsoncやopen-next.config.tsが無ければ、CLIが要る最小のものを書いて知らせます(上書きはしません)。アセットのbindingの名前はASSETSです。
  2. 前からあるopen-next.config.tsは、アセットから読むだけのキャッシュを使う必要があります。そうでなければCLIはビルドの前に止まります(あなたのファイルは書き換えません)。

```ts import { defineCloudflareConfig } from "@opennextjs/cloudflare"; import staticAssetsIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";

export default defineCloudflareConfig({ incrementalCache: staticAssetsIncrementalCache }); ```

  1. next.configにimages: { unoptimized: true }を書きます(画像の最適化はまだ無く、画像はそのまま配られます)。
  2. kumodeck deploy(vinextも入っているならkumodeck deploy --next opennext)。
  • revalidateはまだ効きません。サーバーで作るページとビルド時に作ったページは動きます。ISR用のR2・KV・D1のキャッシュとキュー(NEXT_INC_CACHE_*・NEXT_TAG_CACHE_*・NEXT_CACHE_*)は断られます。
  • OpenNextのwrangler.jsoncのservices(WORKER_SELF_REFERENCE)とimagesは送りません(デプロイがそう知らせます)。
  • Edgeのミドルウェアは動きます。Node.jsのミドルウェアには警告が出ます(OpenNextでも試験的)。動かなければEdgeに戻してください。

どちらでも: Route HandlersとServer Actionsもアプリに届きます。静的な書き出し(output: "export"のあとkumodeck deploy out)もこれまでどおり使えます。Next.jsにはNode.jsの互換が要ります。compatibility_dateが2026-08-04以降なら最初から有効です(vinext initもnodejs_compatを書きます)。それより前の日付ならKUMODeckがnodejs_compatを足して知らせます(next_nodejs_compat_added)。手元の実行も同じになるよう、wrangler.jsoncのcompatibility_flagsにも足してください。

If Next.js does not work#

(Next.jsが動かないとき)KUMODeckのNext.jsはベータです。本番の実行環境ではまだ確かめていません。Next.jsのデプロイでは毎回そう知らせます(警告は、vinextならvinext_beta、OpenNextならnext_beta。デプロイが失敗したときは、エラーのdetails.fallbackもここを指します)。デプロイしたアプリが動かないときは、次のやり方でデプロイし直してください。

vinextでデプロイしたなら、OpenNextでデプロイし直す — OpenNextがまだ入っていなければ入れてから:

npm install -D @opennextjs/cloudflare wrangler
kumodeck deploy --next opennext   # 開発用(deploy の既定)

それでも動かないときは、次のどちらかを試してください。

1. 静的なサイトとして書き出す — リクエストのたびにサーバーのコードが要らないアプリ向けです(Route Handlers・Server Actions・ミドルウェア・サーバーでのCookieの読み取りを使っていない)。next.configに:

const nextConfig = { output: "export", images: { unoptimized: true } };
export default nextConfig;
npx next build        # out/ にサイトを書き出す
kumodeck deploy out    # 開発用(deploy の既定)

それでもサーバーのコードが要る所は、プロジェクト自身のFunctionsに移せます。

2. ページをリクエストごとに描く — ISRを外します。ページとレイアウトのexport const revalidate = …と、fetchのnext: { revalidate: … }を消し(新しいデータが要る所はcache: "no-store")、wrangler.jsoncからNEXT_INC_CACHE_*・NEXT_TAG_CACHE_*・NEXT_CACHE_*のbindingを外します。そのあと、これまでどおりデプロイします。

kumodeck deploy        # 開発用(deploy の既定)

それでも動かないときは、kumodeck deploy --jsonのエラーのcodeとdetailsを控えて伝えてください。

独自ドメイン#

本番のアプリを、自分が持っているドメイン(例: play.mygame.com)で配信できます。利用者・共有リンク・Xのカード(カードのタグと画像のURL)もそのドメインになり、KUMODeckのURLは見えません。証明書と所有の確認はKUMODeckが行い、あなたはDNSのレコードを2つ置くだけです。既定はOFF、productionだけです。

kumodeck features on customDomains && kumodeck config push --env production
kumodeck hosting domains add play.mygame.com     # 置くDNSのレコードを表示
kumodeck hosting domains status play.mygame.com  # 置いたあとに確認し直す
kumodeck hosting domains                         # 一覧
kumodeck hosting domains remove play.mygame.com  # 確認してから消す(スクリプトでは --yes)

addは、DNSの画面にそのまま写せる形で2つのレコードを表示します。

CNAME  play.mygame.com               <表示されたCNAME先>
TXT    _kumo-verify.play.mygame.com  kumo-verify=<アカウントごとの値>

CNAMEは名前をKUMODeckに向け、TXTはドメインの持ち主であることの証明です(値はアカウントのどのドメインでも同じ)。ドメインを管理しているところ(買ったレジストラやDNSの会社)に2つを同時に追加してください。KUMODeckは1時間ごとに確認し、見つかると配信を始めます(ふつうは数分、長いと数時間)。<slug>.kumodeck.appのURLもそのまま使えるので、すでに投稿したリンクは切れません。

  • 見るところは2つ: status(pending → active、だめならfailed)とverified(TXTで持ち主を確認できたか・最後に確認した日時)。足りないものがある間は、次にやることが表示されます。
  • TXTは公開中になった後も消さないでください: KUMODeckは毎日確認し直し、無くなるとそのドメインでの配信を止めます。
  • 親のドメインに1つ置けば、その下はすべて通ります: _kumo-verify.mygame.comがあればplay.mygame.comやwww.mygame.comも証明できるので、サブドメインを増やすときはCNAMEだけで足ります。
  • 他の人が先に申し込んだだけのドメインはその人のものになりません。TXTで持ち主を証明できた方が使えます。「使用中」で断られるのは、このアプリがそのドメインをもう一方の用途(Functionsかホスティング)ですでに使っているときだけです。
  • ルートのドメイン(mygame.com): DNSの会社によってはルートにCNAMEを置けません。ALIAS / ANAME / CNAMEフラット化があればそれを使うか、play.mygame.comのようなサブドメインにしてください。
  • activeになると変わること: kumodeck deployが返すURL、共有リンク、Xのカードのタグと画像のURLがあなたのドメインになります(すでに<head>に書いたカード用のタグは、kumodeck share tags --env productionで取り直して置き換えます)。ログインの戻り先とweb.allowedOriginsは自動で許可されます(httpsだけ)。
  • 上限: 1つのプロジェクトに5個まで。developmentは--devのURLのままです。
  • 料金: 独自ドメインは日割りで原価を前払いから引きます。使わなくなったものは消してください。
  • customDomainsをOFFにすると、独自ドメインでの配信は止まります(一覧と削除はできます)。

ダッシュボード(ホスティング)とMCPのツールhosting_domains_list / hosting_domain_add / hosting_domain_removeでも同じことができます。

URLスラッグを変える#

スラッグは、ゲームのURL(<slug>.kumodeck.app)に使われる名前です。あとから変えられます(30日に1回)。24時間以内に直前の変更を取り消すのは回数に数えません。

kumodeck slug                                        # 今のスラッグ・次に変えられる日・古いスラッグと転送
kumodeck slug check sky-racers-2                     # 使えるか・何が変わるか(URL・下の2択)
kumodeck slug change sky-racers-2 --keep-redirect    # または --no-redirect(どちらかを必ず選びます)
kumodeck slug redirect sky-racers on                 # 古いスラッグの転送をONにする(offで止める)

変えるときに、古いスラッグを使ったリンクの扱いを選びます(既定はありません)。

  • 転送を残す(--keep-redirect): 古いURLは新しいURLへ301で転送されます(パスとクエリを保つので、共有リンクの計測もそのまま)。古いスラッグ1つにつき月$1。転送を残している間、日割りで前払い残高から引きます。残高が足りなくなっても転送は止まらず、止まるのは自分で外したときだけです。
  • 転送を残さない(--no-redirect): 古いURLは中立の「見つかりません」のページになります。料金はかかりません。

どちらでも、古いスラッグはあなたのゲームのために取っておかれ、ほかの人は使えません。あとから転送をON / OFFにできます。独自ドメインは変わりません。

スラッグの変更と転送の切り替えでは、本人の確認(パスワード、またはGoogleなどでのログインのやり直し)があります。CLIは端末でパスワードを聞きます。パスワードの無いアカウントはダッシュボード(ホスティング → URLスラッグ)で変えてください。MCPのツールproject_slug_get / project_slug_checkは読むだけで、AIアシスタントがスラッグを変えることはできません。

アップロードの仕組み#

  1. CLIがすべてのファイルのハッシュ(sha256)を計算し、一覧を送ります。
  2. サーバーはこのプロジェクトでまだ持っていないハッシュを返し、そのファイルだけがアップロードされます(8並列、失敗時は再試行)。
  3. finalize + activateで、公開中のバージョンを原子的に切り替えます。

大きなアプリを少し変えて再デプロイしても、アップロードされるのは変わったファイルだけです。developmentとproductionはアップロードを共有するので、同じビルドを昇格させるコストはかかりません。

キャッシュ#

ファイルCache-Control
*.htmlno-cache(読み込みのたびに再検証。デプロイやロールバックはすぐに反映)
assets/、static/、chunks/の下のハッシュ付きファイル(例: app.3f9a1c.js)immutable、1年
それ以外max-age=0, must-revalidate(安価な304)

ETagは内容のハッシュです。RangeとHEADに対応しています。x/index.htmlがある場合、/xは/x/にリダイレクトされます。存在しないパスには、ルートの404.htmlが使われます。

セキュリティヘッダー#

各アプリはAPIやダッシュボードとは別の専用のサブドメインから配信されるので、アプリ同士がお互いのストレージや開発者のセッションを読むことはできません。緩めのCSPで、CDN、eval、WebAssemblyのエンジンは動かしつつ、プラグインと安全でない(http:)読み込みはブロックします。frame-ancestorsの指定は無いので、itch.ioのようなほかのサイトにアプリやゲームを埋め込めます。developmentのデプロイにはX-Robots-Tag: noindexが付きます。

上限#

上限値
1回のデプロイのファイル数5,000
合計サイズ500 MB
1ファイル50 MB
パスの長さ512文字
完了していないデプロイプロジェクトあたり20件(24時間で失効)
サーバーで画面を作るアプリ: Worker64 MiB(圧縮前)
サーバーで画面を作るアプリ: アセットの1ファイル25 MiB
サーバーで画面を作るアプリ: 1リクエストCPU 1,000ms・サブリクエスト50回

CI#

kumodeck loginは省略し、秘密鍵を渡します。環境は鍵から決まります。

KUMO_API_URL=https://api.kumodeck.com KUMO_SECRET_KEY=$KUMO_SECRET_KEY npx kumodeck deploy dist

準備中 SPA向けのフォールバックルーティング、プロジェクトごとのヘッダー(SharedArrayBuffer用のCOOP/COEP)を予定しています。