diff --git a/deploy/core/Dockerfile b/deploy/core/Dockerfile index 9be91f94..df5d0aa6 100644 --- a/deploy/core/Dockerfile +++ b/deploy/core/Dockerfile @@ -1,6 +1,6 @@ FROM node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd -RUN apk add --no-cache ca-certificates curl git git-daemon +RUN apk add --no-cache ca-certificates curl git git-daemon docker-cli WORKDIR /app diff --git a/src/sandbox/local-sandbox.ts b/src/sandbox/local-sandbox.ts index ce8c97b4..bae13196 100644 --- a/src/sandbox/local-sandbox.ts +++ b/src/sandbox/local-sandbox.ts @@ -165,14 +165,28 @@ export function createLocalSandbox(workspace: WorkspaceStore, opts: LocalSandbox timeoutMs?: number, signal?: AbortSignal, ): Promise<{ status: number; text: string }> { - const port = await resolvePort(name); - const signals = [AbortSignal.timeout(timeoutMs ?? 30_000), ...(signal ? [signal] : [])]; - const res = await fetchImpl(`http://127.0.0.1:${port}${path}`, { - method: body === undefined ? "GET" : "POST", - ...(body === undefined ? {} : { body: JSON.stringify(body), headers: { "content-type": "application/json" } }), - signal: AbortSignal.any(signals), - }); - return { status: res.status, text: await res.text() }; + const port = await resolvePort(name).catch(() => null); + const targets: string[] = []; + if (port) { + targets.push(`http://127.0.0.1:${port}`); + targets.push(`http://host.docker.internal:${port}`); + } + targets.push(`http://${name}:${AGENT_PORT}`); + let lastErr: unknown; + for (const base of targets) { + try { + const signals = [AbortSignal.timeout(timeoutMs ?? 5000), ...(signal ? [signal] : [])]; + const res = await fetchImpl(`${base}${path}`, { + method: body === undefined ? "GET" : "POST", + ...(body === undefined ? {} : { body: JSON.stringify(body), headers: { "content-type": "application/json" } }), + signal: AbortSignal.any(signals), + }); + return { status: res.status, text: await res.text() }; + } catch (e) { + lastErr = e; + } + } + throw lastErr ?? new Error(`local sandbox ${name}: unreachable`); } async function waitDaemon(name: string): Promise {