サンドボックスの作成
POST /v1/sandboxes でサンドボックスを作成します。どのフィールドも省略できます。
| フィールド | 説明 |
|---|---|
image |
公開・非公開を問わず任意の OCI イメージ(python:3.12、ghcr.io/acme/api:1.4)。指定しなければプラットフォームのデフォルトイメージ(後述) |
image_pull_secret |
プライベートイメージの場合:値がレジストリの username:password であるシークレットの名前。イメージのプルに使われ、サンドボックスの中には一切置かれない |
snapshot または template |
イメージの代わりにスナップショットかテンプレートから始める。3 つのうち指定できるのは 1 つまで |
name |
英小文字、数字、ハイフンで 1〜63 文字。ID を受け付けるところでは、名前も受け付ける |
env, metadata |
環境変数(合計 256 KiB まで)。最大 64 個のラベル(使用量をラベルでグループ化できる)。ラベル product はプラットフォームが使うため、設定する作成や変更は拒否される(400 reserved_metadata) |
limits |
サイズ:{vcpus, memory_bytes}。メモリは偶数の MiB(マシンのメモリを読み込む単位である 2 MiB ページの整数倍)で最小 128 MiB、プランで許される量を超えることはできない。それ以外のメモリは拒否される(400 invalid_field) |
sleep_after_seconds |
アイドル時に稼働したままでいる時間:指定しなければ 30 秒、最小 1 秒、null ならスリープしない。スリープと復帰を参照 |
sleep_notice_ms, sleep_hold_max_ms |
スリープのどれだけ前にプログラムに通知するか、そしてプログラムが自ら稼働させ続けられる時間:内部から稼働させ続けるを参照 |
expires_at, delete_after_idle_ms |
削除される時刻、またはスリープしたまま削除されるまでの時間 |
volumes, drives, public_ports, egress |
パスにマウントするドライブとボリューム、誰でも開けるポート、ネットワークルール。copy: true の新しいボリュームには、Docker が新しい名前付きボリュームに行うのと同じく、最初にマウントされたときに、イメージのそのパスにあるものが入る |
start_command, start, ready |
マシンの起動時に始めるサービスと、それが立ち上がったことを示すチェック(後述) |
init |
"systemd":システム全体。イメージ自身の systemd が PID 1 になる(後述)。指定しなければプラットフォームの init |
runtime |
プロセスの制限、カーネル設定、メモリ上のファイルシステム、リゾルバー、/dev/shm のサイズ。アプリのバージョンのランタイム設定と同じ。指定しなければ、Docker と同じく、開けるファイル数は 1,024 で、最大 524,288 まで引き上げられる |
awake_ports, connection_idle_seconds |
リンク経由でアップグレードされた接続(WebSocket)が開いている間サンドボックスを稼働させ続けるポートと、何も流れない状態で接続を閉じるまでの時間:クライアントの接続中は稼働を参照 |
hostname, stop |
ID の代わりにマシンが持つ名前(変更不可)。再起動や削除の前のサービスの止め方:{signal, grace_ms}(イメージの STOPSIGNAL、なければ SIGTERM。強制終了まで 10 秒、最大 10 分) |
project_network |
true:何かを実行する前から、project_address でプロジェクトのプライベートネットワーク上に置く |
checkpoint |
{every_seconds}:稼働中に取るチェックポイント。マシンが失われてもプロセスごと再開できる。指定しなければなし |
region |
na、eu、ap のいずれか:作成する場所。指定しなければコントロールプレーンのリージョン。リージョンを参照 |
イメージから作る最初のサンドボックスは、プラットフォームがイメージをプルしてそのテンプレートを保存する間 starting で、送られた呼び出しは準備ができるまで待ちます。同じイメージから作る以降のサンドボックスはすべてテンプレートのコピーで、すでに実行中のコピーのプールから取り出されます。
limits を指定しなければ、サンドボックスのサイズはマシンの基本テンプレートのサイズで、プランの最大サイズ(無料プランでは 2 vCPU と 4 GiB、有料プランでは 8 vCPU と 16 GiB)を超えることはありません。プランで許されるより大きい limits は拒否されます(403 plan_size_exceeded)。サンドボックスのルートディスクは 8 GiB です。
デフォルトイメージ
Node 24、Python 3.11(pip、venv、uv)、Go、Rust、Maven 付きの Java 25 と、日常的なツール(ripgrep、jq、sqlite3、rsync、dig、sudo)を備えた Debian 12 です。コマンドは /root から root として実行されます。2 つ目のアカウント user は、パスワードなしで sudo を使えます。起動時に始まるものはなく、待ち受けているポートもありません。
マシンとともに始まるサービス
start_command(またはイメージ自身の ENTRYPOINT と CMD を実行する start: true)と ready のチェックを指定すると、プラットフォームはサービスを一度起動し、準備ができるまで待ってから、それをテンプレートとして保存します。同じ設定で作るサンドボックスはすべてそのコピーで、サービスはすでに動いており、メモリはサンドボックスが変更するまで共有されます。
テンプレートの保存前にプログラムが行ったことは、そこから作るすべてのサンドボックスで同じです。生成したキー、トークン、Cookie、ID、乱数生成器の状態などです。起動コマンドは、準備ができる前に、ユーザーやセッションを識別するものを作ってはいけません。そうしたものは、最初に使うときか、サンドボックスの作成後に実行するコマンドで作ってください。
システム全体:systemd
init: "systemd" を指定すると、サンドボックスはマシン全体になります。イメージ自身の systemd が PID 1 になり、プラットフォームのエージェントはそのサービスの 1 つになります。サーバーと同じように、パッケージをインストールし、systemctl でサービスを起動し、cron とジャーナルを使い、SSH でログインできます。
glac sandboxes create --name box --init systemd
glac sandboxes exec box -- systemctl status- イメージを指定しなければ、プラットフォームの Ubuntu 24.04(後述)になります。systemd を含むイメージならどれでも使え、含まないイメージはビルドに失敗します(
invalid_image)。 - 何が動くかはユニットで決まります。
initをstart、start_command、readyと一緒に指定した作成は拒否され(400invalid_start)、スナップショットやテンプレートから作るサンドボックスへのinitの指定も拒否されます(それらは元のとおりになるため)。ほかの値は 400invalid_fieldです。POST /v1/runもinitを受け付け、サンドボックスは自身の設定を示します(init:systemd、またはプラットフォームの init ならnull)。 - 専用のマシン ID。
/etc/machine-id(と D-Bus のコピー)はサンドボックス専用のもので、マシンの作成時に与えられ、スリープ、復帰、移動を経ても保たれます。そのスナップショットから作ったサンドボックスや各フォークは、それぞれ別の ID を持ちます。ジャーナルはその ID の下で、ディスク上に保持されます。 - プラットフォームが管理するものは、ネットワーク、リゾルバー、時計、シリアルコンソールです。それらを変更するユニット(systemd-networkd、NetworkManager、systemd-resolved、timesyncd、chrony、シリアルコンソールの getty、systemd-firstboot)は、起動のたびにマスクされます。イメージの
/etc/systemd/systemに同じ名前のユニットがあれば、ほかのユニットに対してと同じく、マスクより優先されます。 - **スリープ。**ほかのサンドボックスと同じく、アイドル時にスリープします。systemd 自身のタイマーではサンドボックスは稼働し続けず、
Persistent=trueのタイマーユニットは、サンドボックスが復帰したときに逃したものを実行します。cron はサンドボックスの稼働中にしか動かず、毎分の実行によってスリープが最大 1 分遅れることがあります。スケジュールどおりに実行しなければならないものは、タイマーユニットにしてください。 - プラットフォーム経由で実行するコマンド(
exec、run、ターミナル)は、ログインセッションではなく、エージェントのサービスのプロセスです。systemctl --userは、マシン自身のサーバーへの SSH ログインでは使えますが、それらのコマンドでは使えません。サンドボックスのenvとsecret_envはそれらのコマンドの環境で、systemd のサービスはユニットが与えるもの(Environment=)を持ちます。 rebootとpoweroffは、ほかのサンドボックスと同じく、マシンを終了させます。
プラットフォームの Ubuntu イメージは、systemd、D-Bus、OpenSSH サーバー、cron と、人やエージェントが最初に手を伸ばすツール(curl、git、jq、venv 付きの python3、rsync、sudo、htop、dig、zip など)を備えた Ubuntu 24.04 です。ほかのツールは apt で入れられます。コマンドは root として実行され、アカウント user はパスワードなしで sudo を使えます。SSH サーバーはキーだけを受け付け、各マシンはサーバーの初回起動時に自身のホストキーを作ります。外部からはプラットフォームの SSH ゲートウェイでサンドボックスにアクセスし、マシン自身のサーバーは隣にあるもの(転送されたポート、プロジェクトのネットワーク上の別のサンドボックス)のためのものです。お客様には関係のない処理のために毎日サンドボックスを復帰させてしまうタイマー(apt、motd-news、fstrim、dpkg のバックアップ)はマスクされ、ジャーナルはディスク上に保持されます。
コマンドの実行
| 呼び出し | 内容 |
|---|---|
POST /v1/sandboxes/{id}/run |
コマンドを実行して待つ。終了コード、stdout、stderr を返す |
POST /v1/sandboxes/{id}/exec |
コマンドを開始し、すぐにその ID(exe-…)を返す。出力は GET …/exec/{exec}/output で読み、追跡もできる |
POST /v1/run |
サンドボックスを作成し、コマンドを 1 つ実行して削除する。サンドボックスはそのリクエストの間だけ存在する |
文字列で指定したコマンドは sh -c で実行されます。リストで指定するとシェルを介さずにそのまま実行され、プログラムは sh -c と同じく、コマンド自身の環境(イメージのものに呼び出しが追加したもの)の PATH から探されるため、イメージだけが追加するディレクトリ(/usr/local/cargo/bin、/opt/conda/bin)にあるプログラムも見つかります。user を指定しなければ root として、cwd で、サンドボックスの環境変数に env を加えて実行されます。
glac sandboxes exec web 'ls /srv | wc -l' # one argument: a line for sh -c
glac sandboxes exec web -- ls -la /srv # several: a program and its arguments
tar c . | glac sandboxes exec web tar x -C /srv # standard input goes to the command
cmd=$(glac sandboxes exec web --detach -- sh -c 'while true; do date; sleep 1; done')
glac sandboxes logs web "$cmd" # what it printed so far (--follow: until it ends)
glac sandboxes kill web "$cmd" --signal INT- 出力は、各コマンドの最後の 16 MiB が、すべてのバイトに位置を付けて保持されるため、途中で切れた読み手は中断したところから続きを読めます。コマンドが遅い読み手を待つことはありません。大きな出力はファイルに書き出してコピーしてください。
- コマンドは接続ではなくサンドボックスに属します。
glac sandboxes execは接続が切れても中断したところから再開し、最初の Ctrl-C はコマンドに送られます(2 回目でコマンドを動かしたまま抜けます)。 - 終了コード。
glac run、glac sandboxes exec、glac sandboxes shellはコマンドの終了コードで終了し、失敗したのがコマンドでない場合は 125 で終了します。SDK は終了コードをエラーではなく結果として返します。
ファイル
/v1/sandboxes/{id}/files は、コマンドを実行するユーザー(または user で指定した別のユーザー)として、ファイルの読み取り、書き込み、一覧表示、移動、削除を行い、ファイルのモード、長さ、最終更新時刻を設定します(mode、size_bytes、modified_at を付けた PATCH。SDK では set_attributes)。書き込みは、offset を指定しない限り、ファイル全体を一度に置き換えます。読み手に見えるのは古い内容か新しい内容のどちらかで、内容が途中で途切れた書き込みでは、ファイルは元のままです。どんな長さのファイルも 1 回の呼び出しで読み書きできます。バイトは届くそばから通過し、途中でファイル全体を保持するものはなく、読み取りでは最初に長さが示されます。SDK の upload、download、read_stream(readStream)は、ローカルファイルとの間でこれを行います。
glac sandboxes cp -r ./src web:/srv/src # in
glac sandboxes cp web:/var/log/app.log . # out
glac sandboxes cp web:/etc/os-release - # to standard outputsbx.files.write("/srv/config.json", '{"debug": true}') # makes the directories above it
print(sbx.files.list("/srv"))
data = sbx.files.read("/srv/config.json")ターミナル
glac sandboxes shell web でターミナルを開きます。シェル、または指定したコマンド(glac sandboxes shell web htop)です。Enter の後に ~. で、動かしたまま抜けます。--join exe-… で戻ります。開いているターミナルではサンドボックスは稼働し続けず、スリープした後は、次のキー入力で復帰します。
API では、ターミナルは tty: {cols, rows} を付けて開始したコマンド(POST …/exec)と、その入力、出力、サイズを運ぶ …/exec/{exec}/tty への WebSocket です。ブラウザは WebSocket にヘッダーを設定できないため、tty スコープを持つトークンを ?sandbox_token= で渡します。コンソールのターミナルはこの方法で動いています。SDK には sbx.terminal() があります。
コードインタープリター、エージェント、デスクトップ
プラットフォームには、状態を保つコード実行用、コーディングエージェント用、そしてプログラムが画面を見て操作できるデスクトップ用のイメージがあります。SDK にはそれらの呼び出しがあり、Python では sbx.run_code(…)、sbx.agent("claude")、Desktop(sbx) です。Python SDK のページを参照してください。