@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.
- package/README.md +62 -219
- package/dist/index.d.mts +548 -0
- package/dist/index.mjs +2452 -0
- package/package.json +17 -118
- package/Dockerfile +0 -368
- package/dist/bridge/index.d.ts +0 -181
- package/dist/bridge/index.d.ts.map +0 -1
- package/dist/bridge/index.js +0 -3053
- package/dist/bridge/index.js.map +0 -1
- package/dist/contexts-1EsLHByO.d.ts +0 -463
- package/dist/contexts-1EsLHByO.d.ts.map +0 -1
- package/dist/dist-Duor5GbS.js +0 -752
- package/dist/dist-Duor5GbS.js.map +0 -1
- package/dist/errors/index.d.ts +0 -4
- package/dist/errors/index.js +0 -4
- package/dist/errors-CXR0xBpw.js +0 -285
- package/dist/errors-CXR0xBpw.js.map +0 -1
- package/dist/errors-QYlSkVGz.js +0 -893
- package/dist/errors-QYlSkVGz.js.map +0 -1
- package/dist/extensions/index.d.ts +0 -4
- package/dist/extensions/index.js +0 -6
- package/dist/extensions-CFB2xHqY.js +0 -1023
- package/dist/extensions-CFB2xHqY.js.map +0 -1
- package/dist/filesystem-BWAZCZER.d.ts +0 -732
- package/dist/filesystem-BWAZCZER.d.ts.map +0 -1
- package/dist/git/index.d.ts +0 -63
- package/dist/git/index.d.ts.map +0 -1
- package/dist/git/index.js +0 -338
- package/dist/git/index.js.map +0 -1
- package/dist/index-Bs4bqXDR.d.ts +0 -438
- package/dist/index-Bs4bqXDR.d.ts.map +0 -1
- package/dist/index-HNYBk-az.d.ts +0 -444
- package/dist/index-HNYBk-az.d.ts.map +0 -1
- package/dist/index.d.ts +0 -576
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -33
- package/dist/index.js.map +0 -1
- package/dist/interpreter/index.d.ts +0 -311
- package/dist/interpreter/index.d.ts.map +0 -1
- package/dist/interpreter/index.js +0 -292
- package/dist/interpreter/index.js.map +0 -1
- package/dist/openai/index.d.ts +0 -68
- package/dist/openai/index.d.ts.map +0 -1
- package/dist/openai/index.js +0 -367
- package/dist/openai/index.js.map +0 -1
- package/dist/opencode/index.d.ts +0 -182
- package/dist/opencode/index.d.ts.map +0 -1
- package/dist/opencode/index.js +0 -454
- package/dist/opencode/index.js.map +0 -1
- package/dist/process-types-GStiZ8f8.d.ts +0 -73
- package/dist/process-types-GStiZ8f8.d.ts.map +0 -1
- package/dist/sandbox-BbAabq93.d.ts +0 -42
- package/dist/sandbox-BbAabq93.d.ts.map +0 -1
- package/dist/sandbox-cmlgGVYX.js +0 -10056
- package/dist/sandbox-cmlgGVYX.js.map +0 -1
- package/dist/sidecar/index.d.ts +0 -77
- package/dist/sidecar/index.d.ts.map +0 -1
- package/dist/sidecar/index.js +0 -201
- package/dist/sidecar/index.js.map +0 -1
- package/dist/xterm/index.d.ts +0 -93
- package/dist/xterm/index.d.ts.map +0 -1
- package/dist/xterm/index.js +0 -220
- 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.
|
|
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
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"codegen",
|
|
48
|
-
"containers",
|
|
49
|
-
"cloudflare",
|
|
50
|
-
"durable objects"
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
51
12
|
],
|
|
52
|
-
"
|
|
53
|
-
|
|
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.
|
|
70
|
-
"import": "./dist/index.
|
|
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
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
|
|
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"]
|