# デプロイ

リポジトリは、コンソールのデプロイ画面にある Webhook アドレスを GitHub に登録し、**最初の push をすると**接続されます。
その後は push のたびにビルドされ、デプロイされます。

```
list_apps    接続したリポジトリ、本番ブランチ、ビルドするフォルダー
update_app   本番ブランチ、ビルドするフォルダー、フレームワークプリセット、ビルド・出力・インストール設定、実行ユーザー(run_as)を変更
delete_app   アプリ1つを削除: アドレスを外しデプロイを削除 (confirmにアプリ名)
```

- **本番ブランチ**に push すると、プロジェクトのメインアドレスが更新されます。他のブランチは、ブランチ名の付いたプレビューアドレスに行きます。
  新しいリポジトリは、GitHub リポジトリのデフォルトブランチで始まります。
- **モノレポ**なら、`root_directory` にアプリのフォルダー（例: `apps/web`）を入れてください。リポジトリ全体は `.` です。
- フレームワークはビルド時に自動検出します。検出が違うときは `framework` でプリセットを選び、必要なら `build_command`・`output_directory`・`install_command` で上書きしてください（コンソールのビルド設定と同じ値です）。null はプリセットの既定値、空のコマンドはその手順を飛ばします。
  リポジトリの `blackwall.json` に同じ項目があればそちらが優先され、ビルドログには値ごとの出どころが書かれます。
- **バックグラウンドワーカー**（キューの処理、チャットボット、取引所への接続維持など、Web リクエストなしで動くサーバー）は `blackwall.json` に `"worker": true` を入れ、実行コマンドを package.json の `start` に書きます。ポートを開く必要はなく、常に動かし、止まれば再起動します。Web リクエストには 404 を返します。
- **GPU ジョブと GPU サーバー**: Pro 以上で GPU を秒単位で借ります。`create_gpu_job` は公開イメージでコマンドを最後まで実行し(学習、一括処理)、終われば GPU を返します。結果はプロジェクトのストレージなど外部に保存しないと残りません。`get_gpu_job` で状態と出力の最後を、`cancel_gpu_job` で停止します。`create_gpu_server` はモデルを動かしておき、`https://<ref>.<zone>/gpu/v1/servers/<名前>/` を secret キーで呼びます。止まっていれば最初のリクエストで起動し(その間は503)、決めた時間リクエストがなければ止まります。`stop_gpu_server`・`delete_gpu_server` で止めるか削除します。`create_gpu_volume` で1つのデータセンターに GPU ストレージを作り、ジョブやサーバーに `volume` として渡すと `/workspace` に付くので、モデルは一度ダウンロードすれば済みます(ある間は1GB・月の料金、`delete_gpu_volume` で削除)。`region`(auto・asia・us・eu)で借りる地域を選び、ストレージを渡すとそのデータセンターで借ります。韓国から近いのは AP-JP-1(日本)です。入力したイメージ・コマンド・環境変数とストレージのファイルは RunPod のデータセンターで処理されます。料金と使用数は `list_gpu` にあります。RTX 4090 は1時間4,500ウォンから、GPU を借りた時点から返すまで、イメージの取得時間も含めて秒単位で請求します。
- **MySQL データベース (WordPress)**: `create_mysql_database` で MariaDB 11.4 のデータベースと専用ログインを作ります(通常1分)。`app` を渡すとそのアプリだけ、渡さなければプロジェクト全体用です(全体用が1つだけならすべてのアプリが受け取ります)。`bind_mysql_database` で受け取るアプリを変えます。受け取るアプリのサーバーは起動時に `MYSQL_URL`・`MYSQL_HOST`・`MYSQL_PORT`・`MYSQL_USER`・`MYSQL_PASSWORD`・`MYSQL_DATABASE` と、公式 WordPress イメージが読む `WORDPRESS_DB_HOST`(ホスト:ポート)・`WORDPRESS_DB_USER`・`WORDPRESS_DB_PASSWORD`・`WORDPRESS_DB_NAME` を受け取ります。ビルドには入らず、同じ名前で保存した変数が優先されます。プレビューも同じデータベースを受け取ります。アドレスにはこのサーバー上のアプリからだけ届きます。`get_mysql_connection` で接続情報を、`list_mysql_databases` で一覧とプランの上限(フリー1個、Pro 10個、Enterprise 50個)を確認します。毎晩自動でバックアップされ、`create_mysql_backup`・`list_mysql_backups`・`restore_mysql_backup` で今すぐバックアップし、戻します(復元の直前の状態を先にバックアップします)。`delete_mysql_database` はデータベース、ログイン、バックアップをすべて削除します。削除と復元は `confirm` にデータベース名をそのまま入れます。REST: `/mysql`、`/mysql/<名前>`、`/mysql/<名前>/connection`、`/mysql/<名前>/backups`、`/mysql/<名前>/restore`。
- **電話と websocket**: サーバーのデプロイは websocket を受け付けます。Twilio 番号の音声 Webhook を `https://<アドレス>/voice` にすると、通話の音声がリアルタイムで届きます(スターター: リポジトリの `examples/phone-voice`)。接続が開いている間、サーバーはアイドル停止と空き作りの対象から外れるため、長い通話も切れません。代表番号は本番デプロイに置いてください。止まっていたサーバーを起こすと最初の電話が数秒遅れます。
- **サーバーメモリ**は既定で 512MB(CPU 1つ)で、`set_server_memory`(コンソールのデプロイ → ビルド設定。今の値と1か月の金額は `get_server_memory`)で 1024・2048・4096MB から選べます。1024MB を超えると CPU は2つです。使ったメモリは時間単位で `runtime_gb_hour` として計量されます。プランごとに選べる上限があります。本番とブランチのアドレスのサーバーはリクエストがなくても常に動いています(最小インスタンス 1。オンにする設定はありません)。そのため `get_server_memory` の1か月の金額がサーバー 1 つの 1 か月の料金です。
- **同時ビルド**: このプロジェクトのビルドを同時にいくつまで動かすかを `set_concurrent_builds` で 1〜20 に決めるか、null で上限をなくします(コンソールのデプロイ → ビルド設定、サーバーメモリのすぐ下。今の値は `get_concurrent_builds`)。超えたビルドはキューで待ち、待っているあいだはビルド時間が請求されません。
- **Dockerfile**: プロジェクトフォルダーに Dockerfile があり package.json がなければ(Python、Go など)、その Dockerfile でイメージをビルドして実行します。package.json もあるリポジトリは、プリセットで `docker` を選ぶか blackwall.json に `"framework": "docker"` を入れるとイメージでビルドします。イメージの CMD で起動し、イメージが EXPOSE したポート(最も小さい TCP ポート、なければ 3000)で待ち受けます。別のポートなら `update_app` の `port` で指定します。イメージの USER にかかわらず権限のないユーザー(uid 10001)、読み取り専用のファイルシステムで動きます。書き込めるのは `/tmp`(64MB)、`/run`・`/var/run/apache2`・`/var/lock/apache2`(各 16MB、再起動すると空になります)、blackwall.json の `"writablePaths"` に書いたパス(最大 8 つ、各 16MB)、そしてボリュームです。残す必要のあるファイルはボリュームに置いてください(下記)。80 のような 1024 未満のポートでも待ち受けられます。公式 WordPress イメージのように root で起動する必要があるイメージは、ビルド設定の「イメージのユーザーで実行」(update_app の `run_as: "image"`)をオンにしてください。gVisor の分離環境の中でイメージの USER(root を含む)で動くため、root でも他のプロジェクトには届きません。このサーバーに gVisor がなければ、オンにできないことをお知らせします。ビルド時の環境変数は `--build-arg` として渡り、イメージの履歴に残るので、秘密の値は実行時の変数にしてください。ビルドは各ステップでメモリ 2GB・CPU 2つ、最長45分、イメージは 4GB までです。
- **`/data`**: Dockerfile ビルドではないサーバー(Node など)は、そのまま `/data` に書き込めます。Railway や Fly 向けの SDK がキャッシュやトークンをそこに置くためです。サーバーのメモリの 1/8(16MB〜256MB)までで、再起動すると空になります。残す必要があれば `/data` にボリュームを付けてください(下記)。ボリュームがその場所に代わります。
- **ボリューム**は、サーバーを再起動しても、新しくデプロイしても残るディスクです。`create_volume` でアプリの本番サーバーに付け(WordPress なら `/var/www/html`)、`list_volumes` で確認し、`resize_volume` で増やし(減らせません)、`delete_volume` で削除します(ファイルとバックアップがすべてなくなり元に戻せないので、confirm にパスを入れます)。`create_volume_backup` はファイルをまとめて 30 日間保管し、`restore_volume_backup` はそのバックアップに戻します(戻す前のファイルは 7 日間バックアップします)。容量は 1〜500GB で上限なので、超えると書き込みが失敗します。プロジェクトのボリュームの合計はプランで決まります(Free 1GB、Pro 50GB)。プレビューと、今の本番ではない以前のデプロイには付きません。付けたり削除したりすると1分以内にサーバーが再起動します。コンソールのデプロイ → ビルド設定にもあります。
- 変更した設定は**次の push から**適用されます。オーナーと管理者だけが変更できます。

## Git 接続：インポート、非公開リポジトリと GitLab

コンソールのデプロイ → **Git 接続**と同じものです。

```
list_git_access               接続したリポジトリ（connected）、GitHub アカウント、保存したトークン（末尾4文字）
list_importable_repositories  GitHub App が見られるリポジトリを探す （query はすべてから、refresh は問い合わせ直し）
import_repository             リポジトリを接続して最初のデプロイを開始 （ビルド設定と dotenv も一緒に）
disconnect_repository         リポジトリひとつの接続を解除：push してもデプロイしない、履歴は残る
set_checks_on_server          チェックを One Server で実行：GitHub リポジトリの Actions ジョブを One Server のマシンで（オン・オフ）
add_repository                最初の push の前にリポジトリを接続 （github: owner/name, gitlab: group/name）
set_repo_token                非公開リポジトリを取得するトークン （セルフホストの GitLab なら gitlab_base）
remove_repo_token             トークンを削除
link_github_app               組織の別プロジェクトで接続済みの GitHub アカウントを接続
unlink_github_app             GitHub アカウント（App のインストール）ひとつ、またはすべての接続を解除
```

GitHub アカウントを**接続する**には GitHub 上で人が直接確認する必要があるため、コンソールのデプロイ → Git 接続でしかできません。接続したあとのインポートは MCP でできます。
非公開リポジトリのビルドが取得の段階で失敗したら、まず `list_git_access` を確認してください。どれもオーナーと管理者だけが変更できます。

## 他のサーバーから取り込む

コンソールの組織 → **他のサーバーから取り込む** と同じです。取り込み元のアカウント（Supabase、Vercel、PostgreSQL）はコンソールで一度接続します（トークンをチャットに貼らないため）。Supabase は [Supabase でログイン] で許可を押すだけでつながります（トークンのコピーは不要）。

```
import_sources                接続した取り込み元のアカウントとそのプロジェクト、これまでの取り込み
start_import                  取り込みを開始 （コンソールで分割した import、または connection+project でまとまりごとに新しいプロジェクト）
get_import                    移す先ごとの段階別の進行、移さないものとその理由
copy_auth_from_import         Supabase プロジェクトのログイン設定（ソーシャルプロバイダー、戻り先アドレス）をこのサーバーのプロジェクトにコピー
set_vault_project_keys       このプロジェクト自身のアドレスと秘密キーを Vault に入れる（サーバー内だけで移ります）
copy_vault_secrets_from_project  別のプロジェクトの Vault シークレットを値ごとコピー（値はサーバー内だけで移ります）
copy_jobs_from_project        別のプロジェクトの定期ジョブをオフのままコピー
copy_auth_from_project        別のプロジェクトのログイン設定をこのプロジェクトにコピー（シークレットはサーバー内だけで移ります）
copy_storage_from_project     別のプロジェクトのバケットとファイルをこのプロジェクトにコピー （同じサイズなら飛ばします）
copy_storage_from_import      Supabase プロジェクトのバケットとファイルをこのサーバーのプロジェクトにコピー （同じサイズなら飛ばします）
```

Supabase の元は start_import の address にセッションプーラーの接続文字列を入れます。今回の実行だけに使って削除します。スケジュールジョブはオフのまま移します。REST では `GET /v1/imports/sources`、`POST /v1/imports {org, import, connection, project, address}`、`GET /v1/imports/<id>` です。

既存のプロジェクトにログイン設定だけを移すときは `copy_auth_from_import` です。シークレットは接続したアカウントで Supabase から直接読んで保存し、答えには入れません。まず `dry_run` で何が移るかを確認し、終わったら答えの `callback_url` を各プロバイダーのコンソールに登録してください。登録するまでログインは失敗します。REST では `POST /v1/projects/<ref>/config/auth/copy-from-import {connection, project, providers, dry_run}` です。

ファイルだけを移すときは `copy_storage_from_import` です。ここにないバケットは Supabase と同じ公開設定と上限で作り、同じサイズのファイルがすでにあれば飛ばします。1 回でファイル 200 個、45 秒までコピーし、残りがあれば答えの `next` を渡して `done` が true になるまで呼び直します。Supabase のキーはサーバーの中だけで使い、答えには入れません。バケットのアクセスルールはコピーしません。REST では `POST /v1/projects/<ref>/storage/copy-from-import {connection, project, buckets, rename, dry_run, next, max_files}` です。

## push せずにデプロイする

```
redeploy             同じコミットを再ビルド （環境変数を後から追加したとき）
deploy_commit        特定のコミットをデプロイ
promote_deployment   ビルドが終わったプレビューを本番へ
rollback_deployment  本番を以前の本番デプロイへ （再ビルドしない、本番を保留）
create_deploy_hook   呼び出すとブランチの最新コミットをビルドするアドレス （CMS の公開など）
list_deploy_hooks    それらのアドレス
remove_deploy_hook   アドレスを削除
```

**環境変数を変更したら redeploy が必要です。** ビルド結果に埋め込まれた値は、再ビルドしないと変わりません。
プレビューを本番に昇格すると、本番の環境変数で**再ビルド**します。プレビューのビルドをそのまま使うことはありません。
本番へのデプロイは、オーナーと管理者だけが行えます。

## リポジトリなしでデプロイする

```
deploy_files    ファイル（パスと内容）を送ってビルドしデプロイ （合計3MBまで、超えたら create_source_upload_url → deploy_source）
deploy_source   アップロード済みのアーカイブ（source）をデプロイ
create_source_upload_url   大きなアーカイブをトークンなしで PUT するアドレス （1時間）
```

- push されたコミットと**同じビルド**を通ります。package.json があればフレームワークを検出してビルドし、`index.html` だけならそのまま配信します。
- `prebuilt: true` ならビルドせず、送ったファイルをそのまま配信します（ビルド済みの `dist/`）。
- `target` は `preview`（既定）または `production` です。プレビューのアドレスは `branch`（既定は `preview`）で決まります。アプリのないプロジェクトには `site` アプリが作られます。
- 大きなサイトは `oneend deploy`（フォルダーを圧縮してアップロード）か `POST /deployments/sources`（本文: .zip、.tar、.tar.gz、50MBまで）を使い、返された `source` をデプロイします。
- ツールだけで行うときは、`create_source_upload_url` でアドレスを受け取ってアーカイブを PUT し（`curl -X PUT --data-binary @site.zip '<url>'`）、答えの `source` で `deploy_source` を呼びます。アドレスは1時間、そのプロジェクトにだけ使え、サイズの上限と検査は `POST /deployments/sources` と同じです。REST では `POST /v1/projects/<ref>/deployments/sources/upload-urls` です。
- `node_modules` と `.git` は除いてアップロードします。フォルダーの外を指すパスやリンク、展開すると大きくなりすぎるアーカイブは拒否します。

## ビルド設定の詳細、システム変数、デプロイのセキュリティ

```
get_build_settings        アプリごとの開発コマンド、Node.js のバージョン、ビルドのスキップ、本番を先に、必須チェック
set_build_dev_settings    開発コマンド（oneend dev）と Node.js のバージョン（18 | 20 | 22 | 24）
set_ignored_build_step    ビルドする push（automatic | every | production | preview | folder | command）
set_production_first      キューで本番のビルドを先に
set_git_checks            必須の GitHub チェック、Git LFS、署名付きコミットのみ
set_expose_system_env     BLACKWALL_ENV、BLACKWALL_URL などのシステム変数を入れる・外す
set_directory_listing     index.html のないフォルダのファイル一覧を表示
get_deployment_security   ビルドログ・出力を見られる人、フォーク保護、OIDC
set_deployment_security   上を変更（省いた項目はそのまま）
```

フレームワーク、ビルド・インストール・出力のコマンド、ビルドマシンは `update_app` です。どれもオーナーと管理者だけが変更できます。

## デプロイの保存期間と復元

```
get_deployment_retention   デプロイの種類ごとの保存期間（いま適用される日数、プロジェクトの値、プランの既定値）
set_deployment_retention   保存期間を変更（null でプランの既定値、プロジェクト管理者）
list_deleted_deployments   3日以内に削除されたデプロイと、復元できる期限
delete_deployment          デプロイを削除（3日間は復元できます）
restore_deployment         削除したデプロイを復元
```

- プランの既定値: Free はすべて30日。Pro・Enterprise はキャンセル30日、失敗90日、プレビュー180日、本番1年（365日）。プロジェクトが決めた値があればそれに従います。
- 期間にかかわらず残すデプロイ: 直近のデプロイ10個、直近の完了した本番デプロイ20個、直近の完了した本番以外のデプロイ20個、本番・ブランチ・ドメインが今配信しているデプロイ（ブランチごとの最新プレビューを含む）。
- 削除したデプロイと期間を過ぎて削除されたデプロイは、3日間 `restore_deployment` で復元できます。その間、そのデプロイの `dpl-…` アドレスは 410 を返し、3日を過ぎるとファイルとビルドログを消去して復元できなくなります。
- REST では `GET·PUT /v1/projects/<ref>/deployment-retention`、`GET /v1/projects/<ref>/deployments/deleted`、`DELETE /v1/projects/<ref>/deployments/<id>`、`POST /v1/projects/<ref>/deployments/<id>/restore` です。CLI では `oneend deployments retention`、`oneend deployments deleted`、`oneend deployments rm`、`oneend deployments restore` です。

## デプロイのアドレス、待機、セキュリティチェック

- デプロイを作るツール（`deploy_files`、`deploy_source`、`deploy_commit`、`redeploy`、`promote_deployment`）と `get_deployment`、`list_deployments`、`rollback_deployment` は、アドレスも返します。`url` はそのデプロイ固有の `dpl-…` アドレス、`production_url` はプロダクションのアドレス、`preview_url` はそのブランチのプレビューのアドレスです。プレビュー保護がオンなら、誰が開けるかを `note` が伝えます。
- `rollback_deployment` のあと、そのアプリのプロダクションは保留されます（`production_held`、コンソールの「本番保留中」）。新しいプロダクションビルドは作られますが、プロダクションのアドレスには出ません。`promote_deployment` で完了したプロダクションデプロイを昇格すると、再ビルドせずにすぐ出て保留が解除されます。いまのデプロイを昇格すると保留だけ解除されます。保留中のアプリは `list_deployments` の `production_held` でわかります。
- `wait`（秒、120まで）を渡すと、ビルドが終わる（`ready`・`error`）まで待って結果をまとめて返します。失敗したら `error` と `build_log` の末尾が、時間内に終わらなければ `still_running: true` と `retry_after_seconds` が返り、そのあと `get_deployment` を `wait` 付きで呼ぶと続けて待ちます。`create_project` の `wait` はデータベースの準備を待ち、`list_projects` の `status` は `ready`・`provisioning`・`failed`・`paused` のいずれかです。
- 応答の `advisors` は、`get_advisors` が見つけた重大なセキュリティ問題（誰でも書き込めるルール、ルールを無視するビューなど）の数と上位3件です。既定では知らせるだけでデプロイします。`block_on_advisors: true` を渡すと、そのような問題がある間はプロダクションへのデプロイを拒否します（プレビューは止めません）。`oneend deploy --block-on-advisors` も同じです。git push で始まったデプロイは止めません。

---

https://end.blackall.ai/docs/deploy?lang=ja
