@molecule/api-code-sandbox-docker 1.0.0 → 1.0.1
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 +229 -0
- package/package.json +8 -7
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
3
|
+
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
|
+
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
|
+
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
+
Generated: 2026-08-04T01:47:54.321Z
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# @molecule/api-code-sandbox-docker
|
|
10
|
+
|
|
11
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
+
|
|
15
|
+
Docker code-sandbox provider for molecule.dev.
|
|
16
|
+
|
|
17
|
+
## Type
|
|
18
|
+
|
|
19
|
+
`provider`
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @molecule/api-code-sandbox-docker @molecule/api-bond @molecule/api-code-sandbox @molecule/api-i18n
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## API
|
|
28
|
+
|
|
29
|
+
### Interfaces
|
|
30
|
+
|
|
31
|
+
#### `ContainerInfo`
|
|
32
|
+
|
|
33
|
+
Container Info interface.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
interface ContainerInfo {
|
|
37
|
+
id: string
|
|
38
|
+
name: string
|
|
39
|
+
status: string
|
|
40
|
+
ports: Array<{ host: number; container: number }>
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### `DockerConfig`
|
|
45
|
+
|
|
46
|
+
Configuration for docker.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
interface DockerConfig {
|
|
50
|
+
/**
|
|
51
|
+
* Docker unix-socket path. Defaults to `/var/run/docker.sock` (or the
|
|
52
|
+
* `DOCKER_SOCKET_PATH` env var). This is the default transport; it is ignored
|
|
53
|
+
* when a TCP endpoint is selected via `host`/`port` or a `tcp://` `DOCKER_HOST`.
|
|
54
|
+
*/
|
|
55
|
+
socketPath?: string
|
|
56
|
+
/**
|
|
57
|
+
* Connect to a remote/TCP Docker daemon at this host instead of the unix
|
|
58
|
+
* socket. When set, the provider issues all Docker Engine API calls over
|
|
59
|
+
* plain TCP to `host:port` (`port` defaults to 2375) and `socketPath` is
|
|
60
|
+
* ignored. Also honored via `DOCKER_HOST` (`tcp://host:port`). Plain
|
|
61
|
+
* (unencrypted) TCP only — for a TLS-protected daemon (2376) front it with a
|
|
62
|
+
* local socket proxy and point `socketPath` at that.
|
|
63
|
+
*/
|
|
64
|
+
host?: string
|
|
65
|
+
/** TCP port for `host` (default 2375). Ignored unless `host` (or a `tcp://` `DOCKER_HOST`) selects a TCP endpoint. */
|
|
66
|
+
port?: number
|
|
67
|
+
/** Base image for sandbox containers. Defaults to node:22-slim. Must already be present on the host — the provider never pulls images. */
|
|
68
|
+
baseImage?: string
|
|
69
|
+
/** Default CPU allocation (cores). */
|
|
70
|
+
defaultCpu?: number
|
|
71
|
+
/** Default memory allocation (MB). */
|
|
72
|
+
defaultMemoryMB?: number
|
|
73
|
+
/**
|
|
74
|
+
* Docker network the sandbox containers attach to (sets each container's
|
|
75
|
+
* `NetworkMode`). Overrides the `SANDBOX_DOCKER_NETWORK` env var. Defaults to
|
|
76
|
+
* the ICC-off isolated `molecule-sandbox` network, auto-created on first use so
|
|
77
|
+
* tenants are L2-isolated by default. Setting it to the shared `bridge` gives NO
|
|
78
|
+
* cross-tenant isolation and is refused in production. [C1-1]
|
|
79
|
+
*/
|
|
80
|
+
network?: string
|
|
81
|
+
/** Container label prefix for identification. */
|
|
82
|
+
labelPrefix?: string
|
|
83
|
+
/** Preview URL template. Use {port} placeholder. */
|
|
84
|
+
previewUrlTemplate?: string
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### `ProcessEnv`
|
|
89
|
+
|
|
90
|
+
Environment variables the Docker sandbox provider reads.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
interface ProcessEnv {
|
|
94
|
+
/** Unix-socket path for the Docker daemon (default `/var/run/docker.sock`). Overridden by `config.socketPath`. */
|
|
95
|
+
DOCKER_SOCKET_PATH?: string
|
|
96
|
+
/** Docker daemon endpoint, docker-client style: `tcp://host:port` or `unix:///path/to/docker.sock`. Overridden by `config.host`/`config.socketPath`. */
|
|
97
|
+
DOCKER_HOST?: string
|
|
98
|
+
/** Docker network sandbox containers attach to (default `molecule-sandbox`, ICC-off). Overridden by `config.network`. [C1-1] */
|
|
99
|
+
SANDBOX_DOCKER_NETWORK?: string
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Functions
|
|
104
|
+
|
|
105
|
+
#### `createProvider(config)`
|
|
106
|
+
|
|
107
|
+
Creates a new `DockerSandboxProvider` instance with the given configuration.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
function createProvider(config?: DockerConfig): SandboxProvider
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- `config` — Optional Docker-specific configuration: daemon endpoint (`socketPath`, or `host`/`port` for a TCP daemon; `DOCKER_HOST` is also honored), `baseImage`, CPU/memory defaults, and the sandbox `network`.
|
|
114
|
+
|
|
115
|
+
**Returns:** A `SandboxProvider` that manages Docker containers as sandboxes.
|
|
116
|
+
|
|
117
|
+
#### `withTransientRetry(op, opts)`
|
|
118
|
+
|
|
119
|
+
Retry a Docker API operation that failed with a TRANSIENT fault — a request
|
|
120
|
+
timeout or a connection-level reset, i.e. the daemon was momentarily overwhelmed,
|
|
121
|
+
not the request malformed. This is the fix for the observed "first cold boot of a
|
|
122
|
+
concurrent batch dies on `Docker API timeout: POST /containers/create`" failure:
|
|
123
|
+
a single 30 s create timeout under daemon load currently kills the whole boot.
|
|
124
|
+
|
|
125
|
+
HTTP error responses (4xx/5xx) are deliberately NOT retried — those are real
|
|
126
|
+
answers (no-such-image, name conflict), not transient network faults. Bounded
|
|
127
|
+
attempts with linear backoff.
|
|
128
|
+
|
|
129
|
+
`onRetry` is the idempotency guard: a create that TIMED OUT client-side may have
|
|
130
|
+
still succeeded server-side, so before re-issuing it the caller can adopt the
|
|
131
|
+
already-created resource (looked up by a unique label) instead of leaking a
|
|
132
|
+
duplicate container. If `onRetry` returns non-null, that value is used and the
|
|
133
|
+
operation is not re-issued.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
function withTransientRetry(
|
|
137
|
+
op: () => Promise<T>,
|
|
138
|
+
opts: {
|
|
139
|
+
label: string
|
|
140
|
+
attempts?: number
|
|
141
|
+
onRetry?: () => Promise<T | null>
|
|
142
|
+
delayMs?: (attempt: number) => number
|
|
143
|
+
log?: { warn: (message: string, meta?: unknown) => void }
|
|
144
|
+
},
|
|
145
|
+
): Promise<T>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
- `op` — the operation to attempt.
|
|
149
|
+
- `opts` — tuning + the optional adopt-on-retry guard.
|
|
150
|
+
- `opts.label` — short operation name for log lines.
|
|
151
|
+
- `opts.attempts` — max attempts (default 3).
|
|
152
|
+
- `opts.onRetry` — adopt-an-existing-resource guard, run before each retry.
|
|
153
|
+
- `opts.delayMs` — backoff for attempt N (default `400 * N` ms).
|
|
154
|
+
- `opts.log` — optional logger for retry warnings.
|
|
155
|
+
|
|
156
|
+
**Returns:** the operation's result, or an adopted result from `onRetry`.
|
|
157
|
+
|
|
158
|
+
### Constants
|
|
159
|
+
|
|
160
|
+
#### `provider`
|
|
161
|
+
|
|
162
|
+
The provider implementation.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const provider: SandboxProvider
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Core Interface
|
|
169
|
+
|
|
170
|
+
Implements `@molecule/api-code-sandbox` interface.
|
|
171
|
+
|
|
172
|
+
## Bond Wiring
|
|
173
|
+
|
|
174
|
+
Setup function to register this provider with the core interface:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { setProvider } from '@molecule/api-code-sandbox'
|
|
178
|
+
import { provider } from '@molecule/api-code-sandbox-docker'
|
|
179
|
+
|
|
180
|
+
export function setupCodeSandboxDocker(): void {
|
|
181
|
+
setProvider(provider)
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Injection Notes
|
|
186
|
+
|
|
187
|
+
### Requirements
|
|
188
|
+
|
|
189
|
+
Peer dependencies:
|
|
190
|
+
|
|
191
|
+
- `@molecule/api-bond` ^1.0.1
|
|
192
|
+
- `@molecule/api-code-sandbox` ^1.0.1
|
|
193
|
+
- `@molecule/api-i18n` ^1.0.1
|
|
194
|
+
|
|
195
|
+
### Runtime Dependencies
|
|
196
|
+
|
|
197
|
+
- `@molecule/api-bond`
|
|
198
|
+
- `@molecule/api-code-sandbox`
|
|
199
|
+
- `@molecule/api-i18n`
|
|
200
|
+
|
|
201
|
+
**Tenant network isolation (secure default).** Each sandbox is placed on a dedicated
|
|
202
|
+
user-defined Docker network created with inter-container communication DISABLED
|
|
203
|
+
(`com.docker.network.bridge.enable_icc=false`), so one tenant's sandbox cannot reach another
|
|
204
|
+
tenant's Vite/API dev-server ports by IP. Do NOT set `SANDBOX_DOCKER_NETWORK="bridge"` — the
|
|
205
|
+
shared docker bridge has ICC enabled (no cross-tenant isolation) and is REFUSED in production.
|
|
206
|
+
Override `SANDBOX_DOCKER_NETWORK` only to point at another dedicated ICC-off network. This is
|
|
207
|
+
an L2 isolation control; pair it with host-layer default-deny egress filtering (operator-
|
|
208
|
+
provisioned) for full isolation. [C1-1]
|
|
209
|
+
|
|
210
|
+
**Prerequisites.** A reachable Docker daemon and the base image already pulled
|
|
211
|
+
on the host. The daemon is reached over a unix socket by default
|
|
212
|
+
(`config.socketPath` ?? `DOCKER_SOCKET_PATH` ?? `/var/run/docker.sock`); a
|
|
213
|
+
remote or rootless daemon can be selected with `config.host`/`config.port` or a
|
|
214
|
+
`DOCKER_HOST` (`tcp://host:port` or `unix:///path`). Only PLAIN (unencrypted)
|
|
215
|
+
TCP is supported — front a TLS-protected daemon (2376) with a local socket
|
|
216
|
+
proxy. The provider never pulls images, so `create()` fails with a no-such-image
|
|
217
|
+
error if the base image (default `node:22-slim`, or `config.baseImage`) is
|
|
218
|
+
absent. The isolated sandbox network is auto-created on first use; it is NOT a
|
|
219
|
+
prerequisite.
|
|
220
|
+
|
|
221
|
+
**No per-sandbox disk quota.** The Docker API cannot portably cap a
|
|
222
|
+
container/volume size (it needs specific storage drivers — e.g. overlay2 on xfs
|
|
223
|
+
with `pquota` — and errors on the common overlay2/ext4 host), so this provider
|
|
224
|
+
enforces none. The core `resources.diskMB` is accepted but not applied here; cap
|
|
225
|
+
disk at the host / volume level instead.
|
|
226
|
+
|
|
227
|
+
## Translations
|
|
228
|
+
|
|
229
|
+
Translation strings are provided by `@molecule/api-locales-code-sandbox-docker`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/api-code-sandbox-docker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Docker-based code sandbox container provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
21
22
|
],
|
|
22
23
|
"keywords": [
|
|
23
24
|
"molecule",
|
|
@@ -28,16 +29,16 @@
|
|
|
28
29
|
],
|
|
29
30
|
"license": "Apache-2.0",
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"@molecule/api-bond": "1.0.
|
|
32
|
-
"@molecule/api-code-sandbox": "1.0.
|
|
32
|
+
"@molecule/api-bond": "1.0.1",
|
|
33
|
+
"@molecule/api-code-sandbox": "1.0.1",
|
|
33
34
|
"@types/node": "26.1.2",
|
|
34
35
|
"typescript": "6.0.3",
|
|
35
36
|
"vitest": "4.1.10"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
38
|
-
"@molecule/api-bond": "^1.0.
|
|
39
|
-
"@molecule/api-code-sandbox": "^1.0.
|
|
40
|
-
"@molecule/api-i18n": "^1.0.
|
|
39
|
+
"@molecule/api-bond": "^1.0.1",
|
|
40
|
+
"@molecule/api-code-sandbox": "^1.0.1",
|
|
41
|
+
"@molecule/api-i18n": "^1.0.1"
|
|
41
42
|
},
|
|
42
43
|
"peerDependenciesMeta": {
|
|
43
44
|
"@molecule/api-code-sandbox": {
|