Repository navigation
Expand file tree
/
Copy pathDockerfile.api
More file actions
100 lines (79 loc) · 4.8 KB
/
Copy pathDockerfile.api
File metadata and controls
100 lines (79 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# ---- MCP bridge build stage ----
# The same bundle the agent images bake in (images/base.Dockerfile): the
# controller MCP (/opt/optio/controller-mcp.js) and the REST bridge
# (/opt/optio/mcp-bridge.js). An Ask Optio turn that runs in this pod
# (OPTIO_ASSISTANT_PLACEMENT=api-pod) gets the same .mcp.json as a turn in an
# agent pod, so the scripts it names have to be here too.
FROM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea AS bridge
RUN corepack enable && corepack prepare pnpm@10 --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig.base.json ./
COPY packages/mcp-bridge/ packages/mcp-bridge/
RUN pnpm install --frozen-lockfile --ignore-scripts --filter @optio/mcp-bridge \
&& pnpm --filter @optio/mcp-bridge build
# ---- Dependencies stage ----
FROM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea AS deps
RUN corepack enable && corepack prepare pnpm@10 --activate
WORKDIR /app
# Copy workspace config
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json tsconfig.base.json ./
# Copy package.json for ALL workspace packages (pnpm needs full workspace graph)
COPY apps/api/package.json apps/api/tsconfig.json apps/api/drizzle.config.ts apps/api/
COPY apps/cli/package.json apps/cli/
COPY apps/web/package.json apps/web/
COPY apps/site/package.json apps/site/
COPY packages/shared/package.json packages/shared/tsconfig.json packages/shared/
COPY packages/container-runtime/package.json packages/container-runtime/tsconfig.json packages/container-runtime/
COPY packages/agent-adapters/package.json packages/agent-adapters/tsconfig.json packages/agent-adapters/
COPY packages/ticket-providers/package.json packages/ticket-providers/tsconfig.json packages/ticket-providers/
# mcp-bridge is built in the bridge stage above; its package.json is here so
# the frozen lockfile still matches the workspace graph.
COPY packages/mcp-bridge/package.json packages/mcp-bridge/
# Install production dependencies (--ignore-scripts avoids husky prepare hook)
RUN pnpm install --frozen-lockfile --ignore-scripts
# ---- Runtime stage ----
FROM node:22-slim@sha256:80fdb3f57c815e1b638d221f30a826823467c4a56c8f6a8d7aa091cd9b1675ea
ARG OPTIO_VERSION=dev
ENV OPTIO_VERSION=${OPTIO_VERSION}
# Verify Node ships OpenSSL >= 3.5 for post-quantum TLS (X25519MLKEM768)
RUN node -e 'const [maj,min] = process.versions.openssl.split(".").map(Number); if (maj < 3 || (maj === 3 && min < 5)) { console.error("OpenSSL " + process.versions.openssl + " too old; need >= 3.5"); process.exit(1); }'
# git + ca-certificates: required by the skill-sync worker for shallow-cloning
# marketplace skills (issue #497, Phase 2). python3 + curl: the run setup
# (WRITE_SETUP_FILES) and the harness commands of the work that runs in this
# pod (below).
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates python3 curl \
&& rm -rf /var/lib/apt/lists/*
# Install tsx globally for TypeScript execution at runtime
# (workspace packages export .ts source, so the API runs via tsx)
RUN npm install -g tsx
# The harnesses the Ask Optio assistant runs with in this pod by default
# (OPTIO_ASSISTANT_PLACEMENT=api-pod, services/assistant-placement.ts): the
# same Claude Code pin as the agent images (images/base.Dockerfile) and Codex.
# An assistant on another harness runs in an agent pod instead.
# TODO(#566): bump back to latest once upstream Bun ships a fix and claude-code adopts it.
# The API launches Codex with `codex exec --dangerously-bypass-approvals-and-
# sandbox` (task-worker.ts, pooled-agent-command.ts; `--full-auto` is gone
# from 0.162+): fail the build if the Codex this image gets no longer takes it.
RUN npm install -g @anthropic-ai/claude-code@2.1.112 @openai/codex \
&& codex exec --help | grep -q -- --dangerously-bypass-approvals-and-sandbox
# The agent home every run writes under (/home/agent, as in the agent
# images): the assistant's run homes, setup files and harness config. The
# chart mounts an emptyDir here (the root filesystem is read-only).
RUN mkdir -p /home/agent && chown node:node /home/agent
# The MCP scripts an agent's .mcp.json names, at the path the agent images use.
RUN mkdir -p /opt/optio
COPY --from=bridge --chmod=0755 /app/packages/mcp-bridge/dist/mcp-bridge.js /opt/optio/mcp-bridge.js
COPY --from=bridge --chmod=0755 /app/packages/mcp-bridge/dist/controller-mcp.js /opt/optio/controller-mcp.js
WORKDIR /app
# Copy production dependencies from deps stage
COPY --from=deps /app/ ./
# Copy source
COPY packages/ packages/
COPY apps/api/ apps/api/
EXPOSE 4000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "fetch('http://localhost:4000/api/health').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"
USER node
WORKDIR /app/apps/api
CMD ["tsx", "src/index.ts"]