@axiom-lattice/opensandbox-gateway 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,9 @@
1
+ # Copy to .env and fill in. docker compose auto-reads .env in the packages/opensandbox-gateway directory.
2
+ # Shared auth key for the whole sandbox system (server + gateway; Core must set MICROSANDBOX_API_KEY to the same value).
3
+ SANDBOX_API_KEY=change-me-sandbox-key
4
+ # The published gateway image (see README "Docker Compose Deployment").
5
+ GATEWAY_IMAGE=kioko12520/opensandbox-gateway:0.1.5
6
+ # Host directory for named-volume data. Must match allowed_host_paths in sandbox.toml.
7
+ VOLUME_DIR=/data/opensandbox/volumes
8
+ # Optional: separate key for the gateway's own auth; defaults to SANDBOX_API_KEY.
9
+ # GATEWAY_API_KEY=change-me-gateway-key
@@ -1,5 +1,5 @@
1
1
 
2
- > @axiom-lattice/opensandbox-gateway@0.2.0 build /home/runner/work/agentic/agentic/packages/opensandbox-gateway
2
+ > @axiom-lattice/opensandbox-gateway@0.2.2 build /home/runner/work/agentic/agentic/packages/opensandbox-gateway
3
3
  > tsup src/index.ts src/cli.ts --format esm --dts --clean --sourcemap
4
4
 
5
5
  CLI Building entry: src/cli.ts, src/index.ts
@@ -14,8 +14,8 @@
14
14
  ESM dist/cli.mjs.map 387.00 B
15
15
  ESM dist/index.mjs.map 71.00 B
16
16
  ESM dist/chunk-DXSDNFP5.mjs.map 78.82 KB
17
- ESM ⚡️ Build success in 92ms
17
+ ESM ⚡️ Build success in 178ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 23671ms
19
+ DTS ⚡️ Build success in 29393ms
20
20
  DTS dist/cli.d.mts 20.00 B
21
21
  DTS dist/index.d.mts 10.55 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @axiom-lattice/opensandbox-gateway
2
2
 
3
+ ## 0.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 08bf26a: update metric builder
8
+
9
+ ## 0.2.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 8db9937: huge enhance
14
+
3
15
  ## 0.2.0
4
16
 
5
17
  ### Minor Changes
package/Dockerfile ADDED
@@ -0,0 +1,14 @@
1
+ FROM node:20-slim AS builder
2
+ RUN corepack enable && corepack prepare pnpm@10.4.0 --activate
3
+ WORKDIR /repo
4
+ COPY . .
5
+ RUN pnpm install --frozen-lockfile \
6
+ && pnpm --filter @axiom-lattice/opensandbox-gateway build \
7
+ && pnpm --filter @axiom-lattice/opensandbox-gateway deploy --legacy --prod /out
8
+
9
+ FROM node:20-slim
10
+ ENV NODE_ENV=production
11
+ WORKDIR /app
12
+ COPY --from=builder /out .
13
+ EXPOSE 4002
14
+ CMD ["node", "dist/cli.mjs"]
package/README.md CHANGED
@@ -241,6 +241,85 @@ CMD ["lattice-opensandbox-gateway", "--host", "0.0.0.0", "--port", "4002"]
241
241
  pnpm --filter @axiom-lattice/opensandbox-gateway dev
242
242
  ```
243
243
 
244
+ ## Docker Compose Deployment
245
+
246
+ Deploys the full sandbox stack (`opensandbox-server` + `opensandbox-gateway`) with a single command. Files live in this package:
247
+
248
+ - `docker-compose.yml` — both services, network, and volume wiring
249
+ - `sandbox.toml` — OpenSandbox Server config (mounted into the server container)
250
+ - `Dockerfile` — gateway image build (pnpm install → build → `pnpm deploy --prod`)
251
+ - `.env.example` — secret template; copy to `.env` and fill in
252
+
253
+ ### Architecture
254
+
255
+ ```
256
+ Core (agent) Docker host
257
+ │ MICROSANDBOX_SERVICE_URL │
258
+ ▼ │
259
+ opensandbox-gateway ──HTTP──▶ opensandbox-server ──docker.sock──▶ sandbox containers
260
+ (Node Fastify, :4002) (Python FastAPI, :8080)
261
+ ```
262
+
263
+ ### Prerequisites
264
+
265
+ - Docker Engine with compose support (Docker Desktop on macOS)
266
+ - On macOS, `VOLUME_DIR` must be under a Docker Desktop shared path (e.g. a dir under `/Users`)
267
+
268
+ ### Configure
269
+
270
+ 1. Publish the gateway image once (it has no official image), then set `.env`:
271
+ ```bash
272
+ cp .env.example .env
273
+ # edit .env → SANDBOX_API_KEY, GATEWAY_IMAGE, VOLUME_DIR
274
+ ```
275
+ The `GATEWAY_IMAGE` must point to an image built from this package's `Dockerfile` (see the deploy package README for the build/push commands).
276
+ 2. (Optional) Override defaults via the compose `environment` or `sandbox.toml`:
277
+ - Business sandbox image — set on the **Core** side via `MICROSANDBOX_IMAGE` (default `kioko12520/sandbox:0.1.0`). The gateway fallback is `OPEN_SANDBOX_DEFAULT_IMAGE` (default `ubuntu:22.04`).
278
+ - `execd_image` / `egress.image` in `sandbox.toml` must be pullable on the host.
279
+
280
+ > **Linux hosts:** `sandbox.toml` ships with `[proxy] resolve_internal = false` + `[docker] host_ip = "172.17.0.1"` (host-mapped routing). Keep them — with the default `resolve_internal = true`, the Linux server container cannot route to sandbox bridge IPs and sandbox operations hang (OrbStack/macOS tolerates it; Linux does not). See `deploy/OFFLINE_DEPLOYMENT.md`.
281
+
282
+ ### Start
283
+
284
+ ```bash
285
+ cd packages/opensandbox-gateway
286
+ docker compose up -d
287
+ ```
288
+
289
+ Verify:
290
+
291
+ ```bash
292
+ curl http://localhost:8080/health # OpenSandbox Server → {"status":"healthy"}
293
+ curl http://localhost:4002/health # gateway
294
+ curl -H "Authorization: Bearer $SANDBOX_API_KEY" http://localhost:4002/api/sandboxes
295
+ ```
296
+
297
+ ### Connect from Core
298
+
299
+ On the agent process, set:
300
+
301
+ ```bash
302
+ MICROSANDBOX_SERVICE_URL=http://localhost:4002
303
+ MICROSANDBOX_API_KEY=<same as SANDBOX_API_KEY>
304
+ MICROSANDBOX_IMAGE=kioko12520/sandbox:0.1.0 # optional, dynamic sandbox image
305
+ ```
306
+
307
+ ### Path alignment (important)
308
+
309
+ `VOLUME_DIR` (host) is bind-mounted into the gateway at `/data/opensandbox/volumes`, and the server only allows bind mounts under `allowed_host_paths` in `sandbox.toml`. All three must agree:
310
+
311
+ | Place | Value |
312
+ |-------|-------|
313
+ | `.env` → `VOLUME_DIR` (host, Docker daemon view) | `/data/opensandbox/volumes` (default) |
314
+ | Gateway `VOLUME_BASE_PATH` (inside container, fixed) | `/data/opensandbox/volumes` |
315
+ | `sandbox.toml` → `allowed_host_paths` | `/data/opensandbox/volumes` (default) |
316
+
317
+ If you change `VOLUME_DIR`, update `allowed_host_paths` in `sandbox.toml` to the **same** value. A mismatch produces `Host path is not under any allowed prefix` on volume mounts.
318
+
319
+ ### Auth
320
+
321
+ `SANDBOX_API_KEY` is shared by both services (server `api_key` + gateway's server-auth key). The gateway's own auth defaults to the same key and can be overridden with `GATEWAY_API_KEY`. The Core side must set `MICROSANDBOX_API_KEY` to the gateway's auth key.
322
+
244
323
  ## Operational Notes
245
324
 
246
325
  - Requires a running OpenSandbox Server. Start it before starting the gateway.
@@ -249,6 +328,7 @@ pnpm --filter @axiom-lattice/opensandbox-gateway dev
249
328
  - Image management endpoints (`GET /api/images`, `POST /api/images/pull`) are stubs and return empty results.
250
329
  - Sandbox logs and runtime metrics are not yet implemented (stub returns).
251
330
  - Volume FS operations (`/api/volumes/:name/fs/*`) read/write files on the host at `$VOLUME_BASE_PATH`. Works with Docker runtime where the gateway has filesystem access to the host.
331
+ - **Sandbox TTL:** sandboxes expire after `OPEN_SANDBOX_DEFAULT_TIMEOUT` seconds (default `600`) of inactivity. The server destroys the container on expiry. `PUT /api/sandboxes/:name` (ensure) recreates an expired sandbox, but file operations do **not** auto-recreate — they fail against a dead container. This is transparent to the Core agent (it ensures before every operation), but note that **container filesystem state is lost on rebuild** unless data lives in named volumes. For long-running workloads, raise `OPEN_SANDBOX_DEFAULT_TIMEOUT` or use named volumes for persistence.
252
332
 
253
333
  ## API Compatibility
254
334
 
@@ -0,0 +1,9 @@
1
+ # Copy to .env and fill in. docker compose auto-reads .env in the deploy directory.
2
+ # Shared auth key for the whole sandbox system (server + gateway; Core must set MICROSANDBOX_API_KEY to the same value).
3
+ SANDBOX_API_KEY=change-me-sandbox-key
4
+ # The published gateway image (see README "Packaging for distribution").
5
+ GATEWAY_IMAGE=kioko12520/opensandbox-gateway:0.1.5
6
+ # Host directory for named-volume data. Must match allowed_host_paths in sandbox.toml.
7
+ VOLUME_DIR=/data/opensandbox/volumes
8
+ # Optional: separate key for the gateway's own auth; defaults to SANDBOX_API_KEY.
9
+ # GATEWAY_API_KEY=change-me-gateway-key
@@ -0,0 +1,126 @@
1
+ # OpenSandbox Offline Deployment Guide
2
+
3
+ Deploy the OpenSandbox sandbox stack on an air-gapped / offline machine using a pre-packaged image bundle. **This procedure has been verified end-to-end on a Linux x86_64 server** (2 CPUs, Docker 29).
4
+
5
+ ## What you need to carry over
6
+
7
+ | Item | Source | Content |
8
+ |------|--------|---------|
9
+ | `sandbox-stack-amd64.tar.gz` (1.5 GB) | offline packager | 5 Docker images: `opensandbox/server`, `kioko12520/opensandbox-gateway:0.1.5`, `opensandbox/execd:v1.1.0`, `opensandbox/egress:v1.1.7`, `kioko12520/sandbox:0.1.0` |
10
+ | `deploy/` folder | this repo | `docker-compose.yml`, `sandbox.toml`, `.env.example`, `README.md` |
11
+
12
+ > Only the gateway image is self-built. The rest are official images and the business sandbox image. All are amd64 in this bundle; for arm64 targets build an arm64 bundle (see "Preparing the bundle").
13
+
14
+ ## Target machine prerequisites
15
+
16
+ - Docker Engine with Compose
17
+ - ~5 GB free disk (bundle extraction + runtime overhead)
18
+ - `docker0` bridge gateway reachable from containers (default `172.17.0.1`; verify below)
19
+
20
+ ## Install
21
+
22
+ ```bash
23
+ # 1. Load all images (no network needed)
24
+ gunzip -c sandbox-stack-amd64.tar.gz | docker load
25
+ docker images | grep -E "opensandbox|kioko12520/sandbox" # confirm 5 images
26
+
27
+ # 2. Prepare the deploy folder
28
+ mkdir -p /opt/opensandbox && cp -r deploy/ /opt/opensandbox/
29
+ cd /opt/opensandbox
30
+ cp .env.example .env
31
+ # edit .env: SANDBOX_API_KEY=<your-secret>, GATEWAY_IMAGE=kioko12520/opensandbox-gateway:0.1.5
32
+
33
+ # 3. (Only if needed) verify/adjust [docker] host_ip in sandbox.toml
34
+ docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
35
+ # If the gateway is NOT 172.17.0.1, update host_ip in sandbox.toml to match.
36
+
37
+ # 4. Start
38
+ docker compose up -d
39
+
40
+ # 5. Verify
41
+ curl http://localhost:8080/health # {"status":"healthy"}
42
+ curl http://localhost:4002/health # {"success":true,"data":{"status":"ok"}}
43
+ curl -H "Authorization: Bearer $SANDBOX_API_KEY" http://localhost:4002/api/sandboxes
44
+ ```
45
+
46
+ ## Smoke test (sandbox lifecycle)
47
+
48
+ ```bash
49
+ KEY=<your SANDBOX_API_KEY>
50
+ # Create (first create pulls nothing - images already loaded; large images take 1-3 min, keep client timeout ≥ 300s)
51
+ curl -m 300 -X PUT "http://localhost:4002/api/sandboxes/test1" \
52
+ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
53
+ -d '{"image":"kioko12520/sandbox:0.1.0","cpus":1,"memoryMib":512}'
54
+
55
+ # Exec a command
56
+ curl -X POST "http://localhost:4002/api/shell/exec" \
57
+ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
58
+ -d '{"sandboxName":"test1","command":"uname -m && python3 --version"}'
59
+
60
+ # File write/read
61
+ curl -X POST "http://localhost:4002/api/files/write" \
62
+ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
63
+ -d '{"sandboxName":"test1","path":"/tmp/offline.txt","content":"ok"}'
64
+ curl -X POST "http://localhost:4002/api/files/read" \
65
+ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
66
+ -d '{"sandboxName":"test1","path":"/tmp/offline.txt"}'
67
+ ```
68
+
69
+ ## Connect the agent (Core)
70
+
71
+ ```bash
72
+ MICROSANDBOX_SERVICE_URL=http://localhost:4002
73
+ MICROSANDBOX_API_KEY=<same as SANDBOX_API_KEY>
74
+ MICROSANDBOX_IMAGE=kioko12520/sandbox:0.1.0
75
+ ```
76
+
77
+ ## Critical configuration (verified)
78
+
79
+ `sandbox.toml` must use **host-mapped port routing**, not internal bridge IPs:
80
+
81
+ ```toml
82
+ [proxy]
83
+ resolve_internal = false
84
+
85
+ [docker]
86
+ network_mode = "bridge"
87
+ host_ip = "172.17.0.1" # docker0 gateway; must match `docker network inspect bridge`
88
+ ```
89
+
90
+ **Why:** on a Linux host, the server container runs on the Compose bridge (e.g. `172.21.0.x`) and **cannot route to sandbox containers on the default bridge** (`172.17.0.x`). With the default `resolve_internal = true`, the server's execd proxy silently hangs (sandbox creation appears stuck, and commands/file ops fail with `SANDBOX_NOT_FOUND`). `resolve_internal = false` + `host_ip` targets the sandbox's host-mapped port via the docker0 gateway, which works from any container. (OrbStack on macOS happens to allow cross-bridge routing, so the default also worked there — Linux servers will not.)
91
+
92
+ ## Known behaviors / caveats
93
+
94
+ - **Large-image first provisioning is slow** (1-3 min for `kioko12520/sandbox:0.1.0`). If the client disconnects mid-create, the gateway can leave the sandbox in a stuck in-memory state; `docker compose restart opensandbox-gateway` clears it, and a re-`PUT` recovers the existing container.
95
+ - **TTL**: sandboxes expire after `OPEN_SANDBOX_DEFAULT_TIMEOUT` (default 600 s) and the server destroys the container. File ops do not auto-recreate; the agent re-`ensure`s before each op. Rebuilds lose container filesystem state unless data lives in named volumes.
96
+ - **Architecture matters**: an amd64 bundle only runs on x86_64 targets. Build a separate arm64 bundle for arm64 machines, or use `skopeo` to package a multi-arch bundle (`:all`).
97
+ - `VOLUME_DIR` (host) must match `allowed_host_paths` in `sandbox.toml`, else volume mounts fail with `Host path is not under any allowed prefix`.
98
+
99
+ ## Preparing the bundle (on a networked machine)
100
+
101
+ ```bash
102
+ # Same-arch source machine
103
+ docker pull opensandbox/server:latest
104
+ docker pull kioko12520/opensandbox-gateway:0.1.5
105
+ docker pull opensandbox/execd:v1.1.0
106
+ docker pull opensandbox/egress:v1.1.7
107
+ docker pull kioko12520/sandbox:0.1.0
108
+ docker save opensandbox/server:latest kioko12520/opensandbox-gateway:0.1.5 \
109
+ opensandbox/execd:v1.1.0 opensandbox/egress:v1.1.7 kioko12520/sandbox:0.1.0 \
110
+ | gzip > sandbox-stack-amd64.tar.gz
111
+
112
+ # Pin the architecture on a cross-arch source (e.g. amd64 bundle from an arm64 machine)
113
+ docker pull --platform linux/amd64 <each image above>
114
+ # The --platform flag is required here too; otherwise an ARM host can export its ARM64 variant.
115
+ docker image save --platform linux/amd64 \
116
+ opensandbox/server:latest kioko12520/opensandbox-gateway:0.1.5 \
117
+ opensandbox/execd:v1.1.0 opensandbox/egress:v1.1.7 kioko12520/sandbox:0.1.0 \
118
+ | gzip > sandbox-stack-amd64.tar.gz
119
+
120
+ # Multi-arch bundle (all platforms, needs skopeo)
121
+ skopeo copy docker://docker.io/kioko12520/opensandbox-gateway:0.1.5 \
122
+ docker-archive:gateway-multiarch.tar:kioko12520/opensandbox-gateway:0.1.5:all
123
+ # repeat for each image
124
+ ```
125
+
126
+ If Docker Hub is unreachable from the packager, pull via a mirror first (e.g. `hub.rat.dev/<image>`) then `docker tag` back to the canonical name before saving.
@@ -0,0 +1,95 @@
1
+ # OpenSandbox Deploy Package
2
+
3
+ Self-contained Docker Compose deployment for the Axiom Lattice OpenSandbox sandbox stack. Hand this folder to anyone who needs the service; they do **not** need the Axiom Lattice monorepo.
4
+
5
+ ## Contents
6
+
7
+ | File | Purpose |
8
+ |------|---------|
9
+ | `docker-compose.yml` | Two services: `opensandbox-server` (Python, creates/runs sandbox containers via the host Docker daemon) + `opensandbox-gateway` (Node HTTP gateway, the API your agent connects to) |
10
+ | `sandbox.toml` | OpenSandbox Server runtime config (mounted into the server container) |
11
+ | `.env.example` | Secret/image/path template — copy to `.env` |
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ Core (agent) Docker host
17
+ │ MICROSANDBOX_SERVICE_URL │
18
+ ▼ ▼
19
+ opensandbox-gateway ──HTTP──▶ opensandbox-server ──docker.sock──▶ sandbox containers
20
+ (Node Fastify, :4002) (Python FastAPI, :8080)
21
+ ```
22
+
23
+ ## Requirements (on the target host)
24
+
25
+ - Docker Engine with Compose
26
+ - Ability to pull: `opensandbox/server`, `opensandbox/execd:v1.1.0`, `opensandbox/egress:v1.1.7`, the gateway image, and the business sandbox images
27
+ - For offline / air-gapped targets, see **[`OFFLINE_DEPLOYMENT.md`](OFFLINE_DEPLOYMENT.md)** (verified end-to-end on Linux x86_64)
28
+
29
+ > **Important (Linux hosts):** `sandbox.toml` ships with `[proxy] resolve_internal = false` and `[docker] host_ip = "172.17.0.1"`. Do not revert `resolve_internal` to `true` — on Linux the server container cannot route to sandbox bridge IPs, and sandbox operations hang (see OFFLINE_DEPLOYMENT.md for details).
30
+
31
+ ## Quick Start (consumer)
32
+
33
+ ```bash
34
+ cp .env.example .env # fill SANDBOX_API_KEY, GATEWAY_IMAGE, VOLUME_DIR
35
+ docker compose up -d
36
+ curl http://localhost:8080/health # OpenSandbox Server
37
+ curl http://localhost:4002/health # gateway
38
+ ```
39
+
40
+ Then on the agent process:
41
+
42
+ ```bash
43
+ MICROSANDBOX_SERVICE_URL=http://localhost:4002
44
+ MICROSANDBOX_API_KEY=<same as SANDBOX_API_KEY>
45
+ MICROSANDBOX_IMAGE=kioko12520/sandbox:0.1.0 # optional; dynamic business sandbox image
46
+ ```
47
+
48
+ ## Packaging for distribution (publisher)
49
+
50
+ The gateway has **no official image**, so publish it once, then ship this folder:
51
+
52
+ ```bash
53
+ # 1. Build + push the gateway image (from the monorepo root)
54
+ docker build -t <registry>/opensandbox-gateway:<tag> -f packages/opensandbox-gateway/Dockerfile .
55
+ docker push <registry>/opensandbox-gateway:<tag>
56
+
57
+ # 2. Set GATEWAY_IMAGE in the deploy/.env.example to that image
58
+ # 3. Ship the deploy/ folder
59
+ ```
60
+
61
+ Offline / air-gapped alternative — hand over the image as a tar instead of a registry:
62
+
63
+ ```bash
64
+ docker save <registry>/opensandbox-gateway:<tag> | gzip > opensandbox-gateway.tar.gz
65
+ # recipient:
66
+ gunzip -c opensandbox-gateway.tar.gz | docker load
67
+ ```
68
+
69
+ The `opensandbox/server` image is pulled automatically from Docker Hub.
70
+
71
+ ## Key configuration
72
+
73
+ | Variable | Meaning |
74
+ |----------|---------|
75
+ | `SANDBOX_API_KEY` | Shared auth key (server + gateway). Core must set `MICROSANDBOX_API_KEY` to the same value |
76
+ | `GATEWAY_IMAGE` | The published gateway image |
77
+ | `VOLUME_DIR` | Host directory for named-volume data. **Must match `allowed_host_paths` in `sandbox.toml`** |
78
+
79
+ ### Path alignment (important)
80
+
81
+ `VOLUME_DIR` (host) is bind-mounted into the gateway at `/data/opensandbox/volumes`, and the server only allows bind mounts under `allowed_host_paths` in `sandbox.toml`. All three must agree:
82
+
83
+ | Place | Value |
84
+ |-------|-------|
85
+ | `.env` → `VOLUME_DIR` (host, Docker daemon view) | `/data/opensandbox/volumes` (default) |
86
+ | Gateway `VOLUME_BASE_PATH` (inside container, fixed) | `/data/opensandbox/volumes` |
87
+ | `sandbox.toml` → `allowed_host_paths` | `/data/opensandbox/volumes` (default) |
88
+
89
+ If you change `VOLUME_DIR`, update `allowed_host_paths` in `sandbox.toml` to the **same** value. A mismatch produces `Host path is not under any allowed prefix` on volume mounts.
90
+
91
+ ### Sandbox behavior notes
92
+
93
+ - Default image: `OPEN_SANDBOX_DEFAULT_IMAGE` fallback `ubuntu:22.04`; the effective image comes from the client (`MICROSANDBOX_IMAGE`).
94
+ - **TTL:** sandboxes expire after 600s idle (`OPEN_SANDBOX_DEFAULT_TIMEOUT`) and the server destroys the container. `PUT /api/sandboxes/:name` (ensure) recreates them; file operations do not. Container filesystem state is lost on rebuild unless using named volumes. Raise the TTL for long-running workloads.
95
+ - Image management endpoints are stubs (return empty / 501).
@@ -0,0 +1,35 @@
1
+ services:
2
+ opensandbox-server:
3
+ image: opensandbox/server:latest
4
+ restart: unless-stopped
5
+ environment:
6
+ SANDBOX_CONFIG_PATH: /etc/opensandbox/config.toml
7
+ OPENSANDBOX_SERVER_API_KEY: ${SANDBOX_API_KEY:?set SANDBOX_API_KEY in .env}
8
+ volumes:
9
+ - /var/run/docker.sock:/var/run/docker.sock
10
+ - ./sandbox.toml:/etc/opensandbox/config.toml:ro
11
+ - opensandbox-store:/data/opensandbox
12
+ ports:
13
+ - "8080:8080"
14
+
15
+ opensandbox-gateway:
16
+ image: ${GATEWAY_IMAGE:?set GATEWAY_IMAGE to the published gateway image}
17
+ restart: unless-stopped
18
+ environment:
19
+ HOST: 0.0.0.0
20
+ PORT: 4002
21
+ OPEN_SANDBOX_DOMAIN: opensandbox-server:8080
22
+ OPEN_SANDBOX_PROTOCOL: http
23
+ OPEN_SANDBOX_API_KEY: ${SANDBOX_API_KEY:?set SANDBOX_API_KEY in .env}
24
+ OPEN_SANDBOX_USE_SERVER_PROXY: "true"
25
+ GATEWAY_API_KEY: ${GATEWAY_API_KEY:-${SANDBOX_API_KEY}}
26
+ VOLUME_BASE_PATH: /data/opensandbox/volumes
27
+ volumes:
28
+ - ${VOLUME_DIR:-/data/opensandbox/volumes}:/data/opensandbox/volumes
29
+ ports:
30
+ - "4002:4002"
31
+ depends_on:
32
+ - opensandbox-server
33
+
34
+ volumes:
35
+ opensandbox-store:
@@ -0,0 +1,46 @@
1
+ [server]
2
+ host = "0.0.0.0"
3
+ port = 8080
4
+ # api_key is injected via the OPENSANDBOX_SERVER_API_KEY env var (see docker-compose.yml), not hardcoded here
5
+
6
+ [proxy]
7
+ # Docker Compose: the server container cannot route to sandbox bridge IPs on Linux hosts,
8
+ # so target host-mapped ports instead of internal bridge IPs (see [docker] host_ip).
9
+ resolve_internal = false
10
+
11
+ [log]
12
+ level = "INFO"
13
+
14
+ [runtime]
15
+ type = "docker"
16
+ execd_image = "opensandbox/execd:v1.1.0"
17
+
18
+ [storage]
19
+ # Must equal VOLUME_DIR on the host (Docker daemon view). Default: /data/opensandbox/volumes
20
+ # If you change VOLUME_DIR in .env, update this to match.
21
+ allowed_host_paths = ["/data/opensandbox/volumes"]
22
+
23
+ [store]
24
+ type = "sqlite"
25
+ path = "/data/opensandbox/opensandbox.db"
26
+
27
+ [docker]
28
+ network_mode = "bridge"
29
+ # Host address the server uses to reach sandbox host-mapped ports (resolve_internal=false).
30
+ # docker0 gateway is reachable from any container; change it if the host bridge subnet differs.
31
+ host_ip = "172.17.0.1"
32
+ port_range_min = 40000
33
+ port_range_max = 60000
34
+ drop_capabilities = ["AUDIT_WRITE", "MKNOD", "NET_ADMIN", "NET_RAW", "SYS_ADMIN", "SYS_MODULE", "SYS_PTRACE", "SYS_TIME", "SYS_TTY_CONFIG"]
35
+ no_new_privileges = true
36
+ pids_limit = 4096
37
+ apparmor_profile = ""
38
+ seccomp_profile = ""
39
+
40
+ [ingress]
41
+ mode = "direct"
42
+
43
+ [egress]
44
+ image = "opensandbox/egress:v1.1.7"
45
+ mode = "dns"
46
+ readiness_timeout_seconds = 30.0
@@ -0,0 +1,35 @@
1
+ services:
2
+ opensandbox-server:
3
+ image: opensandbox/server:latest
4
+ restart: unless-stopped
5
+ environment:
6
+ SANDBOX_CONFIG_PATH: /etc/opensandbox/config.toml
7
+ OPENSANDBOX_SERVER_API_KEY: ${SANDBOX_API_KEY:?set SANDBOX_API_KEY in .env}
8
+ volumes:
9
+ - /var/run/docker.sock:/var/run/docker.sock
10
+ - ./sandbox.toml:/etc/opensandbox/config.toml:ro
11
+ - opensandbox-store:/data/opensandbox
12
+ ports:
13
+ - "8080:8080"
14
+
15
+ opensandbox-gateway:
16
+ image: ${GATEWAY_IMAGE:?set GATEWAY_IMAGE to the published gateway image}
17
+ restart: unless-stopped
18
+ environment:
19
+ HOST: 0.0.0.0
20
+ PORT: 4002
21
+ OPEN_SANDBOX_DOMAIN: opensandbox-server:8080
22
+ OPEN_SANDBOX_PROTOCOL: http
23
+ OPEN_SANDBOX_API_KEY: ${SANDBOX_API_KEY:?set SANDBOX_API_KEY in .env}
24
+ OPEN_SANDBOX_USE_SERVER_PROXY: "true"
25
+ GATEWAY_API_KEY: ${GATEWAY_API_KEY:-${SANDBOX_API_KEY}}
26
+ VOLUME_BASE_PATH: /data/opensandbox/volumes
27
+ volumes:
28
+ - ${VOLUME_DIR:-/data/opensandbox/volumes}:/data/opensandbox/volumes
29
+ ports:
30
+ - "4002:4002"
31
+ depends_on:
32
+ - opensandbox-server
33
+
34
+ volumes:
35
+ opensandbox-store:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/opensandbox-gateway",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "main": "dist/index.mjs",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
package/sandbox.toml ADDED
@@ -0,0 +1,46 @@
1
+ [server]
2
+ host = "0.0.0.0"
3
+ port = 8080
4
+ # api_key is injected via the OPENSANDBOX_SERVER_API_KEY env var (see docker-compose.yml), not hardcoded here
5
+
6
+ [proxy]
7
+ # Docker Compose: the server container cannot route to sandbox bridge IPs on Linux hosts,
8
+ # so target host-mapped ports instead of internal bridge IPs (see [docker] host_ip).
9
+ resolve_internal = false
10
+
11
+ [log]
12
+ level = "INFO"
13
+
14
+ [runtime]
15
+ type = "docker"
16
+ execd_image = "opensandbox/execd:v1.1.0"
17
+
18
+ [storage]
19
+ # Must equal VOLUME_DIR on the host (Docker daemon view). Default: /data/opensandbox/volumes
20
+ # If you change VOLUME_DIR in .env, update this to match.
21
+ allowed_host_paths = ["/data/opensandbox/volumes"]
22
+
23
+ [store]
24
+ type = "sqlite"
25
+ path = "/data/opensandbox/opensandbox.db"
26
+
27
+ [docker]
28
+ network_mode = "bridge"
29
+ # Host address the server uses to reach sandbox host-mapped ports (resolve_internal=false).
30
+ # docker0 gateway is reachable from any container; change it if the host bridge subnet differs.
31
+ host_ip = "172.17.0.1"
32
+ port_range_min = 40000
33
+ port_range_max = 60000
34
+ drop_capabilities = ["AUDIT_WRITE", "MKNOD", "NET_ADMIN", "NET_RAW", "SYS_ADMIN", "SYS_MODULE", "SYS_PTRACE", "SYS_TIME", "SYS_TTY_CONFIG"]
35
+ no_new_privileges = true
36
+ pids_limit = 4096
37
+ apparmor_profile = ""
38
+ seccomp_profile = ""
39
+
40
+ [ingress]
41
+ mode = "direct"
42
+
43
+ [egress]
44
+ image = "opensandbox/egress:v1.1.7"
45
+ mode = "dns"
46
+ readiness_timeout_seconds = 30.0