---
title: "ホスティングとデプロイ"
description: "`kumodeck deploy <dir>`は、静的ファイルのフォルダ（ビルド済みのWebアプリやゲーム）を、環境の新しいバージョンとして公開します。"
url: "/ja/docs/guides/hosting/"
lang: ja
index: "/ja/llms.txt"
---
# ホスティングとデプロイ

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

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

## デプロイする

```sh
kumodeck deploy dist --env production     # production（deploy の既定は development）
kumodeck deploy dist --env development -m "new boss fight"
kumodeck deployments                      # バージョンの一覧（* = 公開中）
kumodeck rollback 12                      # バージョン 12 を即座に公開状態へ戻す
```

| 環境 | URL |
|---|---|
| production | `https://<slug>.kumodeck.app/` |
| development | `https://<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＝[下](#nextjs)、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になります）。

```sh
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](/ja/docs/guides/functions/index.md)と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`で読みます（[ログ](/ja/docs/guides/functions/index.md#ログ)）。行は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](https://opennext.js.org/cloudflare)（`@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
   ```
4. `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 });
   ```
3. `next.config`に`images: { unoptimized: true }`を書きます（画像の最適化はまだ無く、画像はそのまま配られます）。
4. `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がまだ入っていなければ入れてから:

```sh
npm install -D @opennextjs/cloudflare wrangler
kumodeck deploy --next opennext   # 開発用（deploy の既定）
```

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

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

```ts
const nextConfig = { output: "export", images: { unoptimized: true } };
export default nextConfig;
```

```sh
npx next build        # out/ にサイトを書き出す
kumodeck deploy out    # 開発用（deploy の既定）
```

それでもサーバーのコードが要る所は、プロジェクト自身の[Functions](/ja/docs/guides/functions/index.md)に移せます。

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

```sh
kumodeck deploy        # 開発用（deploy の既定）
```

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

## 独自ドメイン

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

```sh
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時間以内に直前の変更を取り消すのは回数に数えません。

```sh
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 |
|---|---|
| `*.html` | `no-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時間で失効） |
| サーバーで画面を作るアプリ: Worker | 64 MiB（圧縮前） |
| サーバーで画面を作るアプリ: アセットの1ファイル | 25 MiB |
| サーバーで画面を作るアプリ: 1リクエスト | CPU 1,000ms・サブリクエスト50回 |

## CI

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

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

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