@cloudflare/sandbox 0.13.0-next.776.1 → 1.0.0-rc.0

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.
Files changed (63) hide show
  1. package/README.md +62 -219
  2. package/dist/index.d.mts +548 -0
  3. package/dist/index.mjs +2452 -0
  4. package/package.json +17 -118
  5. package/Dockerfile +0 -368
  6. package/dist/bridge/index.d.ts +0 -181
  7. package/dist/bridge/index.d.ts.map +0 -1
  8. package/dist/bridge/index.js +0 -3053
  9. package/dist/bridge/index.js.map +0 -1
  10. package/dist/contexts-1EsLHByO.d.ts +0 -463
  11. package/dist/contexts-1EsLHByO.d.ts.map +0 -1
  12. package/dist/dist-Duor5GbS.js +0 -752
  13. package/dist/dist-Duor5GbS.js.map +0 -1
  14. package/dist/errors/index.d.ts +0 -4
  15. package/dist/errors/index.js +0 -4
  16. package/dist/errors-CXR0xBpw.js +0 -285
  17. package/dist/errors-CXR0xBpw.js.map +0 -1
  18. package/dist/errors-QYlSkVGz.js +0 -893
  19. package/dist/errors-QYlSkVGz.js.map +0 -1
  20. package/dist/extensions/index.d.ts +0 -4
  21. package/dist/extensions/index.js +0 -6
  22. package/dist/extensions-CFB2xHqY.js +0 -1023
  23. package/dist/extensions-CFB2xHqY.js.map +0 -1
  24. package/dist/filesystem-BWAZCZER.d.ts +0 -732
  25. package/dist/filesystem-BWAZCZER.d.ts.map +0 -1
  26. package/dist/git/index.d.ts +0 -63
  27. package/dist/git/index.d.ts.map +0 -1
  28. package/dist/git/index.js +0 -338
  29. package/dist/git/index.js.map +0 -1
  30. package/dist/index-Bs4bqXDR.d.ts +0 -438
  31. package/dist/index-Bs4bqXDR.d.ts.map +0 -1
  32. package/dist/index-HNYBk-az.d.ts +0 -444
  33. package/dist/index-HNYBk-az.d.ts.map +0 -1
  34. package/dist/index.d.ts +0 -576
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/index.js +0 -33
  37. package/dist/index.js.map +0 -1
  38. package/dist/interpreter/index.d.ts +0 -311
  39. package/dist/interpreter/index.d.ts.map +0 -1
  40. package/dist/interpreter/index.js +0 -292
  41. package/dist/interpreter/index.js.map +0 -1
  42. package/dist/openai/index.d.ts +0 -68
  43. package/dist/openai/index.d.ts.map +0 -1
  44. package/dist/openai/index.js +0 -367
  45. package/dist/openai/index.js.map +0 -1
  46. package/dist/opencode/index.d.ts +0 -182
  47. package/dist/opencode/index.d.ts.map +0 -1
  48. package/dist/opencode/index.js +0 -454
  49. package/dist/opencode/index.js.map +0 -1
  50. package/dist/process-types-GStiZ8f8.d.ts +0 -73
  51. package/dist/process-types-GStiZ8f8.d.ts.map +0 -1
  52. package/dist/sandbox-BbAabq93.d.ts +0 -42
  53. package/dist/sandbox-BbAabq93.d.ts.map +0 -1
  54. package/dist/sandbox-cmlgGVYX.js +0 -10056
  55. package/dist/sandbox-cmlgGVYX.js.map +0 -1
  56. package/dist/sidecar/index.d.ts +0 -77
  57. package/dist/sidecar/index.d.ts.map +0 -1
  58. package/dist/sidecar/index.js +0 -201
  59. package/dist/sidecar/index.js.map +0 -1
  60. package/dist/xterm/index.d.ts +0 -93
  61. package/dist/xterm/index.d.ts.map +0 -1
  62. package/dist/xterm/index.js +0 -220
  63. package/dist/xterm/index.js.map +0 -1
package/package.json CHANGED
@@ -1,129 +1,28 @@
1
1
  {
2
2
  "name": "@cloudflare/sandbox",
3
- "version": "0.13.0-next.776.1",
3
+ "version": "1.0.0-rc.0",
4
+ "description": "Structured workspace file operations for Cloudflare sandboxes",
5
+ "license": "Apache-2.0",
4
6
  "repository": {
5
7
  "type": "git",
6
- "url": "https://github.com/cloudflare/sandbox-sdk"
7
- },
8
- "description": "A sandboxed environment for running commands",
9
- "type": "module",
10
- "dependencies": {
11
- "@cloudflare/containers": "^0.3.7",
12
- "aws4fetch": "^1.0.20",
13
- "capnweb": "^0.8.0",
14
- "hono": "^4.12.26"
15
- },
16
- "devDependencies": {
17
- "@openai/agents": "^0.3.3",
18
- "@opencode-ai/sdk": "^1.1.40",
19
- "@repo/shared": "^0.0.0",
20
- "@types/acorn": "^4.0.6",
21
- "@types/bun": "^1.3.14",
22
- "@types/tar-stream": "^3.1.4",
23
- "@xterm/xterm": "^6.0.0",
24
- "acorn": "^8.14.0",
25
- "async-mutex": "^0.5.0",
26
- "tar-stream": "^3.2.0",
27
- "wrangler": "^4.102.0"
28
- },
29
- "peerDependencies": {
30
- "@openai/agents": "^0.3.3",
31
- "@opencode-ai/sdk": "^1.1.40",
32
- "@xterm/xterm": ">=5.0.0"
33
- },
34
- "peerDependenciesMeta": {
35
- "@openai/agents": {
36
- "optional": true
37
- },
38
- "@opencode-ai/sdk": {
39
- "optional": true
40
- },
41
- "@xterm/xterm": {
42
- "optional": true
43
- }
8
+ "url": "git+https://github.com/cloudflare/sandbox-sdk.git"
44
9
  },
45
- "tags": [
46
- "sandbox",
47
- "codegen",
48
- "containers",
49
- "cloudflare",
50
- "durable objects"
10
+ "files": [
11
+ "dist"
51
12
  ],
52
- "scripts": {
53
- "build": "rm -rf dist && npm run build:sidecar && tsdown --config tsdown.config.ts",
54
- "build:sidecar": "bun run ../../extensions/interpreter/build.ts",
55
- "check": "biome check && npm run typecheck",
56
- "fix": "biome check --fix && npm run typecheck",
57
- "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.sidecar.json",
58
- "docker:local": "scripts/docker-local.sh",
59
- "test": "vitest run --config vitest.config.ts \"$@\"",
60
- "test:harness": "vitest run --config vitest.harness.config.ts \"$@\"",
61
- "test:sidecar": "bun test ../../extensions/interpreter/src/sidecar",
62
- "test:e2e": "npm run test:e2e:vitest && npm run test:e2e:browser",
63
- "test:e2e:vitest": "cd ../../tests/e2e/test-worker && ./generate-config.sh && cd ../../.. && vitest run --config vitest.e2e.config.ts \"$@\"",
64
- "test:e2e:browser": "cd ../../tests/e2e/test-worker && ./generate-config.sh && cd ../../.. && npx playwright install chromium && playwright test --config tests/e2e/browser/playwright.config.ts",
65
- "test:perf": "cd ../.. && vitest run --config vitest.perf.config.ts \"$@\""
66
- },
13
+ "type": "module",
14
+ "sideEffects": false,
67
15
  "exports": {
68
16
  ".": {
69
- "types": "./dist/index.d.ts",
70
- "import": "./dist/index.js",
71
- "require": "./dist/index.js"
72
- },
73
- "./extensions": {
74
- "types": "./dist/extensions/index.d.ts",
75
- "import": "./dist/extensions/index.js",
76
- "require": "./dist/extensions/index.js"
77
- },
78
- "./errors": {
79
- "types": "./dist/errors/index.d.ts",
80
- "import": "./dist/errors/index.js",
81
- "require": "./dist/errors/index.js"
82
- },
83
- "./sidecar": {
84
- "types": "./dist/sidecar/index.d.ts",
85
- "import": "./dist/sidecar/index.js",
86
- "require": "./dist/sidecar/index.js"
87
- },
88
- "./interpreter": {
89
- "types": "./dist/interpreter/index.d.ts",
90
- "import": "./dist/interpreter/index.js",
91
- "require": "./dist/interpreter/index.js"
92
- },
93
- "./git": {
94
- "types": "./dist/git/index.d.ts",
95
- "import": "./dist/git/index.js",
96
- "require": "./dist/git/index.js"
97
- },
98
- "./openai": {
99
- "types": "./dist/openai/index.d.ts",
100
- "import": "./dist/openai/index.js",
101
- "require": "./dist/openai/index.js"
102
- },
103
- "./opencode": {
104
- "types": "./dist/opencode/index.d.ts",
105
- "import": "./dist/opencode/index.js",
106
- "require": "./dist/opencode/index.js"
107
- },
108
- "./xterm": {
109
- "types": "./dist/xterm/index.d.ts",
110
- "import": "./dist/xterm/index.js",
111
- "require": "./dist/xterm/index.js"
112
- },
113
- "./bridge": {
114
- "types": "./dist/bridge/index.d.ts",
115
- "import": "./dist/bridge/index.js",
116
- "require": "./dist/bridge/index.js"
17
+ "types": "./dist/index.d.mts",
18
+ "import": "./dist/index.mjs"
117
19
  }
118
20
  },
119
- "keywords": [],
120
- "author": "",
121
- "license": "Apache-2.0",
122
- "files": [
123
- "dist",
124
- "Dockerfile",
125
- "startup.sh",
126
- "README.md",
127
- "LICENSE"
128
- ]
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "dependencies": {
25
+ "aws4fetch": "1.0.20",
26
+ "zod": "4.5.4"
27
+ }
129
28
  }
package/Dockerfile DELETED
@@ -1,368 +0,0 @@
1
- # Bun version — override via --build-arg BUN_VERSION=$(cat .bun-version)
2
- ARG BUN_VERSION=1.3.14
3
- # Node version — override via --build-arg NODE_VERSION=24
4
- ARG NODE_VERSION=24
5
- # cloudflared release — shared across glibc and musl image variants.
6
- # Bump this together with the architecture-specific checksums below.
7
- ARG CLOUDFLARED_VERSION=2026.3.0
8
- # fuse-overlayfs release — backs the copy-on-write layer of restored backups.
9
- # Pinned upstream because Ubuntu 22.04 ships 1.7.1, which returns EEXIST when
10
- # a restored directory is deleted, recreated and listed before files are
11
- # created in it (fixed in 1.15). Switch back to the distro package once the
12
- # base image ships 1.15 or newer.
13
- # Bump this together with the architecture-specific checksums below.
14
- ARG FUSE_OVERLAYFS_VERSION=1.18
15
- FROM oven/bun:${BUN_VERSION} AS bun-binary
16
- FROM node:${NODE_VERSION}-slim AS node-runtime
17
-
18
- # ============================================================================
19
- # Release downloader — shared base for fetching pinned upstream binaries
20
- # ============================================================================
21
- FROM alpine:3.21 AS release-downloader
22
-
23
- # Inject the host's extra CA bundle when downloading behind a TLS-intercepting
24
- # proxy (e.g. Cloudflare WARP / Zero Trust). No-op when the secret isn't passed.
25
- RUN --mount=type=secret,id=wrangler_ca \
26
- if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
27
- cat /run/secrets/wrangler_ca >> /etc/ssl/certs/ca-certificates.crt; \
28
- mkdir -p /usr/local/share/ca-certificates && \
29
- cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt; \
30
- fi && \
31
- apk add --no-cache ca-certificates curl && \
32
- if [ -f /usr/local/share/ca-certificates/wrangler-dev-ca.crt ]; then \
33
- update-ca-certificates; \
34
- fi
35
-
36
- # ============================================================================
37
- # cloudflared (Cloudflare Tunnel daemon) — enables sandbox.tunnels.*
38
- # Version pin lives at the top of this Dockerfile as a global ARG, shared
39
- # by every image variant so they ship the same release.
40
- # ============================================================================
41
- FROM release-downloader AS cloudflared-binary
42
-
43
- ARG TARGETARCH
44
- ARG CLOUDFLARED_VERSION
45
- ARG CLOUDFLARED_SHA256_AMD64=4a9e50e6d6d798e90fcd01933151a90bf7edd99a0a55c28ad18f2e16263a5c30
46
- ARG CLOUDFLARED_SHA256_ARM64=0755ba4cbab59980e6148367fcf53a8f3ec85a97deefd63c2420cf7850769bee
47
-
48
- RUN set -eux; \
49
- arch="${TARGETARCH:-}"; \
50
- if [ -z "$arch" ]; then \
51
- arch="$(apk --print-arch)"; \
52
- fi; \
53
- case "$arch" in \
54
- amd64|x86_64) suffix=amd64; sha="${CLOUDFLARED_SHA256_AMD64}" ;; \
55
- arm64|aarch64) suffix=arm64; sha="${CLOUDFLARED_SHA256_ARM64}" ;; \
56
- *) echo "Unsupported arch for cloudflared: $arch" >&2; exit 1 ;; \
57
- esac; \
58
- url="https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-${suffix}"; \
59
- curl -fsSL -o /cloudflared "$url"; \
60
- echo "$sha /cloudflared" | sha256sum -c -; \
61
- chmod +x /cloudflared; \
62
- /cloudflared --version
63
-
64
- # ============================================================================
65
- # fuse-overlayfs — statically linked upstream release for the glibc images
66
- # ============================================================================
67
- FROM release-downloader AS fuse-overlayfs-binary
68
-
69
- ARG TARGETARCH
70
- ARG FUSE_OVERLAYFS_VERSION
71
- ARG FUSE_OVERLAYFS_SHA256_AMD64=56b0ae0aeb8abb308b068af2f137ed8d1bd239f4f27e21672ff0def861eea1e8
72
- ARG FUSE_OVERLAYFS_SHA256_ARM64=82fed736197b2a881a822e5357b488796f654e8371ce8573a1592331510a0133
73
-
74
- RUN set -eux; \
75
- arch="${TARGETARCH:-}"; \
76
- if [ -z "$arch" ]; then \
77
- arch="$(apk --print-arch)"; \
78
- fi; \
79
- case "$arch" in \
80
- amd64|x86_64) suffix=x86_64; sha="${FUSE_OVERLAYFS_SHA256_AMD64}" ;; \
81
- arm64|aarch64) suffix=aarch64; sha="${FUSE_OVERLAYFS_SHA256_ARM64}" ;; \
82
- *) echo "Unsupported arch for fuse-overlayfs: $arch" >&2; exit 1 ;; \
83
- esac; \
84
- url="https://github.com/containers/fuse-overlayfs/releases/download/v${FUSE_OVERLAYFS_VERSION}/fuse-overlayfs-${suffix}"; \
85
- curl -fsSL -o /fuse-overlayfs "$url"; \
86
- echo "$sha /fuse-overlayfs" | sha256sum -c -; \
87
- chmod +x /fuse-overlayfs; \
88
- /fuse-overlayfs --version
89
-
90
- # Sandbox container images (default and python variants)
91
- # Multi-stage build optimized for Turborepo monorepo
92
-
93
- # ============================================================================
94
- # Stage 1: Prune monorepo to only include necessary packages
95
- # ============================================================================
96
- FROM node-runtime AS pruner
97
-
98
- WORKDIR /app
99
-
100
- RUN npm install -g turbo
101
-
102
- COPY . .
103
-
104
- # Prune to only @repo/sandbox-container and its dependencies (@repo/shared)
105
- # The --docker flag generates out/json and out/full directories
106
- RUN turbo prune @repo/sandbox-container --docker
107
-
108
- # ============================================================================
109
- # Stage 2: Install dependencies and build packages
110
- # Using glibc-based images (not Alpine) so the standalone binary works on
111
- # standard Linux distributions (Debian, Ubuntu, RHEL, etc.)
112
- # ============================================================================
113
- FROM node-runtime AS builder
114
-
115
- WORKDIR /app
116
-
117
- # Install Bun runtime (glibc version for glibc-compatible standalone binary)
118
- COPY --from=bun-binary /usr/local/bin/bun /usr/local/bin/bun
119
-
120
- # Copy pruned lockfile and package.json files (for Docker layer caching)
121
- COPY --from=pruner /app/out/json/ .
122
- COPY --from=pruner /app/out/package-lock.json ./package-lock.json
123
-
124
- # Install ALL dependencies with cache mount for npm packages
125
- RUN --mount=type=cache,target=/root/.npm \
126
- CI=true npm ci
127
-
128
- COPY --from=pruner /app/out/full/ .
129
-
130
- # Build all packages (Turborepo handles dependency order automatically)
131
- # This builds @repo/shared first, then @repo/sandbox-container (including standalone binary)
132
- RUN npx turbo run build
133
-
134
- # ============================================================================
135
- # Stage 3: Download pre-built Python 3.11.14
136
- # ============================================================================
137
- FROM ubuntu:22.04 AS python-builder
138
-
139
- # Prevent interactive prompts during package installation
140
- ENV DEBIAN_FRONTEND=noninteractive
141
-
142
- # Accept architecture from Docker BuildKit (for multi-arch builds)
143
- ARG TARGETARCH
144
-
145
- # Install minimal dependencies for downloading
146
- RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
147
- --mount=type=cache,target=/var/lib/apt,sharing=locked \
148
- rm -f /etc/apt/apt.conf.d/docker-clean && \
149
- echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
150
- apt-get update && apt-get install -y --no-install-recommends \
151
- wget ca-certificates
152
-
153
- # Download and extract pre-built Python 3.11.14 from python-build-standalone
154
- # Using PGO+LTO optimized builds for better performance
155
- # Supports multi-arch: amd64 (x86_64) and arm64 (aarch64)
156
- RUN --mount=type=cache,target=/tmp/python-cache \
157
- # Map Docker TARGETARCH to python-build-standalone arch naming
158
- if [ "$TARGETARCH" = "amd64" ]; then \
159
- PYTHON_ARCH="x86_64-unknown-linux-gnu"; \
160
- EXPECTED_SHA256="edd8d11aa538953d12822fab418359a692fd1ee4ca2675579fbf0fa31e3688f1"; \
161
- elif [ "$TARGETARCH" = "arm64" ]; then \
162
- PYTHON_ARCH="aarch64-unknown-linux-gnu"; \
163
- EXPECTED_SHA256="08141d31f95d86a23f23e4c741b726de0055f12f83200d1d4867b4e8e6e967c5"; \
164
- else \
165
- echo "Unsupported architecture: $TARGETARCH" && exit 1; \
166
- fi && \
167
- cd /tmp/python-cache && \
168
- wget -nc https://github.com/indygreg/python-build-standalone/releases/download/20251028/cpython-3.11.14+20251028-${PYTHON_ARCH}-install_only.tar.gz && \
169
- # Verify SHA256 checksum for security
170
- echo "${EXPECTED_SHA256} cpython-3.11.14+20251028-${PYTHON_ARCH}-install_only.tar.gz" | sha256sum -c - && \
171
- cd /tmp && \
172
- tar -xzf /tmp/python-cache/cpython-3.11.14+20251028-${PYTHON_ARCH}-install_only.tar.gz && \
173
- mv python /usr/local/ && \
174
- rm -rf /tmp/cpython-*
175
-
176
- # ============================================================================
177
- # Stage 4: Runtime base - Ubuntu 22.04 with Node.js and Bun (no Python)
178
- # ============================================================================
179
- FROM ubuntu:22.04 AS runtime-base
180
-
181
- # Accept version as build argument (passed from npm_package_version)
182
- ARG SANDBOX_VERSION=unknown
183
-
184
- # Prevent interactive prompts during package installation
185
- ENV DEBIAN_FRONTEND=noninteractive
186
-
187
- ENV SANDBOX_VERSION=${SANDBOX_VERSION}
188
-
189
- # Install runtime packages, S3FS-FUSE for bucket mounting, and snapshot tools
190
- # - fuse3: FUSE filesystem support (replaces legacy fuse, needed by s3fs/squashfuse/fuse-overlayfs)
191
- # - squashfs-tools: create squashfs archives (mksquashfs)
192
- # - squashfuse: mount squashfs in userspace (FUSE)
193
- # Cache-bust: 2 - Clear apt cache to force fresh package list
194
- RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
195
- --mount=type=cache,target=/var/lib/apt,sharing=locked \
196
- rm -f /etc/apt/apt.conf.d/docker-clean && \
197
- echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \
198
- rm -rf /var/cache/apt/* /var/lib/apt/lists/* && \
199
- apt-get update && apt-get install -y --no-install-recommends \
200
- s3fs fuse3 squashfs-tools squashfuse \
201
- ca-certificates curl wget procps git unzip zip jq file tini \
202
- inotify-tools \
203
- libssl3 zlib1g libbz2-1.0 libreadline8 libsqlite3-0 \
204
- libncursesw6 libtinfo6 libxml2 libxmlsec1 libffi8 liblzma5 libtk8.6 && \
205
- update-ca-certificates
206
-
207
- # Enable FUSE in container - allow non-root users to use FUSE
208
- RUN sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
209
-
210
- # fusermount requires /etc/mtab to locate active mounts
211
- RUN ln -sf /proc/mounts /etc/mtab
212
-
213
- # Userspace overlayfs for copy-on-write backup restores
214
- COPY --from=fuse-overlayfs-binary /fuse-overlayfs /usr/bin/fuse-overlayfs
215
- RUN fuse-overlayfs --version
216
-
217
- # Install Node.js from official Node image (defaults to 24 LTS,
218
- # override via --build-arg NODE_VERSION=<version>)
219
- COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node
220
- COPY --from=node-runtime /usr/local/lib/node_modules /usr/local/lib/node_modules
221
- RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
222
- ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
223
-
224
- # Install Bun runtime from official image
225
- COPY --from=bun-binary /usr/local/bin/bun /usr/local/bin/bun
226
-
227
- # Copy standalone binary
228
- COPY --from=builder /app/packages/sandbox-container/dist/sandbox /container-server/sandbox
229
-
230
- # Set up container server directory
231
- WORKDIR /container-server
232
-
233
- # Copy legacy JS bundle for backwards compatibility
234
- # Users with custom startup scripts that call `bun /container-server/dist/index.js` need this
235
- COPY --from=builder /app/packages/sandbox-container/dist/index.js ./dist/
236
-
237
- COPY --from=cloudflared-binary /cloudflared /usr/local/bin/cloudflared
238
- RUN cloudflared --version
239
-
240
- # Inject the host's extra CA bundle when running locally behind a TLS-
241
- # intercepting proxy (e.g. Cloudflare WARP / Zero Trust). See
242
- # DOCKER_README.md for the local-dev setup. No-op when the secret
243
- # isn't passed.
244
- RUN --mount=type=secret,id=wrangler_ca \
245
- if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
246
- cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
247
- cat /run/secrets/wrangler_ca >> /etc/ssl/certs/ca-certificates.crt && \
248
- update-ca-certificates; \
249
- fi
250
-
251
- RUN mkdir -p /workspace
252
-
253
- # Expose the application port (3000 for control)
254
- EXPOSE 3000
255
-
256
- # ============================================================================
257
- # Stage 5a: Default image - lean, no Python
258
- # ============================================================================
259
- FROM runtime-base AS default
260
-
261
- # Disable Python pool (Python not available in this image)
262
- ENV PYTHON_POOL_MIN_SIZE=0
263
- ENV JAVASCRIPT_POOL_MIN_SIZE=3
264
- ENV TYPESCRIPT_POOL_MIN_SIZE=3
265
-
266
- ENTRYPOINT ["/usr/bin/tini", "--", "/container-server/sandbox"]
267
-
268
- # ============================================================================
269
- # Stage 5b: Python image - full, with Python + data science packages
270
- # ============================================================================
271
- FROM runtime-base AS python
272
-
273
- # Copy pre-built Python from python-builder stage
274
- COPY --from=python-builder /usr/local/python /usr/local/python
275
-
276
- # Create symlinks and update shared library cache
277
- RUN ln -s /usr/local/python/bin/python3.11 /usr/local/bin/python3.11 && \
278
- ln -s /usr/local/python/bin/python3 /usr/local/bin/python3 && \
279
- ln -s /usr/local/python/bin/pip3 /usr/local/bin/pip3 && \
280
- echo "/usr/local/python/lib" > /etc/ld.so.conf.d/python.conf && \
281
- ldconfig
282
-
283
- # Set Python 3.11 as default python3
284
- RUN update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.11 1
285
-
286
- # Install Python packages for data science and the code interpreter extension.
287
- # The interpreter runtime itself is provisioned by the @cloudflare/sandbox/interpreter
288
- # extension; this image only provides the Python toolchain it relies on.
289
- RUN --mount=type=cache,target=/root/.cache/pip \
290
- pip3 install --no-cache-dir matplotlib numpy pandas ipython
291
-
292
- # Pre-warm pool sizes consumed by the interpreter extension sidecar
293
- ENV PYTHON_POOL_MIN_SIZE=3
294
- ENV JAVASCRIPT_POOL_MIN_SIZE=3
295
- ENV TYPESCRIPT_POOL_MIN_SIZE=3
296
-
297
- ENTRYPOINT ["/usr/bin/tini", "--", "/container-server/sandbox"]
298
-
299
- # ============================================================================
300
- # Stage 5c: OpenCode image - with OpenCode CLI for AI coding agent
301
- # ============================================================================
302
- FROM runtime-base AS opencode
303
-
304
- RUN --mount=type=secret,id=wrangler_ca \
305
- if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
306
- cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
307
- update-ca-certificates; \
308
- fi
309
-
310
- # Install OpenCode CLI via npm (avoids GitHub API rate limits)
311
- RUN npm i -g opencode-ai \
312
- && opencode --version
313
-
314
- # Disable Python pool (Python not available in this image)
315
- ENV PYTHON_POOL_MIN_SIZE=0
316
- ENV JAVASCRIPT_POOL_MIN_SIZE=3
317
- ENV TYPESCRIPT_POOL_MIN_SIZE=3
318
-
319
- # Expose OpenCode server port (in addition to 3000 from runtime-base)
320
- EXPOSE 4096
321
-
322
- ENTRYPOINT ["/usr/bin/tini", "--", "/container-server/sandbox"]
323
-
324
- # ============================================================================
325
- # Stage 5d: Musl image - Alpine-based with musl-linked binary
326
- # ============================================================================
327
- FROM alpine:3.21 AS musl
328
-
329
- ARG SANDBOX_VERSION=unknown
330
-
331
- ENV SANDBOX_VERSION=${SANDBOX_VERSION}
332
-
333
- # CA certificate installation
334
- RUN mkdir -p /usr/local/share/ca-certificates
335
- RUN --mount=type=secret,id=wrangler_ca \
336
- if [ -f /run/secrets/wrangler_ca ] && [ -s /run/secrets/wrangler_ca ]; then \
337
- cp /run/secrets/wrangler_ca /usr/local/share/ca-certificates/wrangler-dev-ca.crt && \
338
- cat /run/secrets/wrangler_ca >> /etc/ssl/certs/ca-certificates.crt && \
339
- apk add --no-cache ca-certificates && \
340
- update-ca-certificates; \
341
- else \
342
- apk add --no-cache ca-certificates; \
343
- fi
344
-
345
- RUN apk add --no-cache bash file git curl libstdc++ libgcc s3fs-fuse fuse tini
346
-
347
- RUN sed -i 's/#user_allow_other/user_allow_other/' /etc/fuse.conf
348
-
349
- # The Alpine variant uses the same cloudflared release asset as the glibc
350
- # variants. It is a static binary that runs on musl without gcompat.
351
- COPY --from=cloudflared-binary /cloudflared /usr/local/bin/cloudflared
352
- RUN cloudflared --version
353
-
354
- COPY --from=builder /app/packages/sandbox-container/dist/sandbox-musl /container-server/sandbox
355
-
356
- WORKDIR /container-server
357
-
358
- COPY --from=builder /app/packages/sandbox-container/dist/index.js ./dist/
359
-
360
- RUN mkdir -p /workspace
361
-
362
- EXPOSE 3000
363
-
364
- ENV PYTHON_POOL_MIN_SIZE=0
365
- ENV JAVASCRIPT_POOL_MIN_SIZE=0
366
- ENV TYPESCRIPT_POOL_MIN_SIZE=0
367
-
368
- ENTRYPOINT ["/sbin/tini", "--", "/container-server/sandbox"]