-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
100 lines (84 loc) · 4.58 KB
/
Dockerfile
File metadata and controls
100 lines (84 loc) · 4.58 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
# ---------- build (toolchain + Yarn v1 pinned) ----------
FROM node:22-alpine3.22 AS build
WORKDIR /usr/src/app
RUN apk add --no-cache python3 make g++ git libc6-compat wget curl
ENV PYTHON=/usr/bin/python3
ENV npm_config_python=/usr/bin/python3
RUN corepack enable && corepack prepare yarn@1.22.22 --activate
# Copy manifests & sources
COPY package.json yarn.lock ./
COPY packages ./packages
# Install with dev deps
RUN yarn install --frozen-lockfile
# Build in dependency order
RUN yarn workspace @jobstash/file-parser build
RUN yarn workspace @jobstash/mcp-server build
RUN yarn workspace @jobstash/mcp-gateway build
# Sanity checks (corrected gateway path)
RUN test -f packages/file-parser/dist/src/index.js || (echo "file-parser build output missing" && ls -R packages/file-parser && exit 1)
RUN test -f packages/mcp-server/dist/src/mcp-runner.js || (echo "mcp-server build output missing" && ls -R packages/mcp-server && exit 1)
# accept either dist/main.js or dist/src/main.js (your build makes dist/src/main.js)
RUN [ -f packages/mcp-gateway/dist/main.js ] || [ -f packages/mcp-gateway/dist/src/main.js ] \
|| (echo "mcp-gateway build output missing" && ls -R packages/mcp-gateway && exit 1)
# Prune to prod deps
RUN rm -rf node_modules && yarn install --frozen-lockfile --production
# ---------- runtime ----------
FROM node:22-alpine3.22 AS runtime
WORKDIR /usr/src/app
RUN apk add --no-cache tini
ENV NODE_ENV=production
ENV GATEWAY_PORT=3000
ENV MCP_SERVER_PORT=3333
ENV MCP_SERVER_URL=http://127.0.0.1:3333
# OPENAI_API_KEY / JOBSTASH_* come from your platform env
# Copy runtime files
COPY --from=build /usr/src/app/package.json ./package.json
COPY --from=build /usr/src/app/yarn.lock ./yarn.lock
COPY --from=build /usr/src/app/node_modules ./node_modules
# Workspace manifests + builds
COPY --from=build /usr/src/app/packages/file-parser/package.json ./packages/file-parser/package.json
COPY --from=build /usr/src/app/packages/mcp-server/package.json ./packages/mcp-server/package.json
COPY --from=build /usr/src/app/packages/mcp-gateway/package.json ./packages/mcp-gateway/package.json
COPY --from=build /usr/src/app/packages/file-parser/dist ./packages/file-parser/dist
COPY --from=build /usr/src/app/packages/mcp-server/dist ./packages/mcp-server/dist
COPY --from=build /usr/src/app/packages/mcp-gateway/dist ./packages/mcp-gateway/dist
# Make gateway’s "../mcp-server/..." relative arg resolve
RUN mkdir -p /usr/src && ln -s /usr/src/app/packages/mcp-server /usr/src/mcp-server || true
# Replace the Node binary with a wrapper that loads runtime env,
# so child spawns (even with wiped env) still see JOBSTASH_* / OPENAI_*.
RUN mv /usr/local/bin/node /usr/local/bin/node-real && \
printf '%s\n' \
'#!/bin/sh' \
'# Load whitelisted runtime env if present' \
'set -a' \
'[ -f /usr/src/app/.env-runtime ] && . /usr/src/app/.env-runtime' \
'set +a' \
'exec /usr/local/bin/node-real "$@"' \
> /usr/local/bin/node && chmod +x /usr/local/bin/node
# Entrypoint writes .env-runtime and starts both services
RUN printf '%s\n' \
'#!/bin/sh' \
'set -e' \
'# Write env file consumed by node wrapper' \
': > /usr/src/app/.env-runtime' \
'for v in JOBSTASH_SITE_URL JOBSTASH_API_URL OPENAI_API_KEY OPENAI_ASSISTANT_ID_PARSER MCP_SERVER_URL MCP_SERVER_PORT GATEWAY_PORT NODE_ENV; do' \
' eval "val=\${$v:-}"' \
' [ -n "$val" ] && printf "%s=%s\n" "$v" "$val" >> /usr/src/app/.env-runtime' \
'done' \
'' \
'SERVER_JS="packages/mcp-server/dist/src/mcp-runner.js"' \
'GATEWAY_JS="packages/mcp-gateway/dist/main.js"' \
'[ -f "$GATEWAY_JS" ] || GATEWAY_JS="packages/mcp-gateway/dist/src/main.js"' \
'[ -f "$SERVER_JS" ] || { echo "[entrypoint] Missing $SERVER_JS"; ls -R packages/mcp-server || true; exit 1; }' \
'[ -f "$GATEWAY_JS" ] || { echo "[entrypoint] Missing $GATEWAY_JS"; ls -R packages/mcp-gateway || true; exit 1; }' \
'echo "[entrypoint] Starting MCP Server on ${MCP_SERVER_PORT}..."' \
'node "$SERVER_JS" --port="${MCP_SERVER_PORT}" & MCP_PID=$!' \
'echo "[entrypoint] Starting Gateway on ${GATEWAY_PORT} (MCP at ${MCP_SERVER_URL})..."' \
'export MCP_SERVER_URL OPENAI_API_KEY JOBSTASH_SITE_URL JOBSTASH_API_URL OPENAI_ASSISTANT_ID_PARSER' \
'node "$GATEWAY_JS" --port="${GATEWAY_PORT}" & GW_PID=$!' \
'trap "echo [entrypoint] Stopping...; kill -TERM $MCP_PID $GW_PID 2>/dev/null || true; wait" TERM INT' \
'wait -n $MCP_PID $GW_PID; EC=$?; echo "[entrypoint] A process exited with code $EC, shutting down..."; kill -TERM $MCP_PID $GW_PID 2>/dev/null || true; wait || true; exit $EC' \
> /usr/local/bin/entrypoint.sh && chmod +x /usr/local/bin/entrypoint.sh
EXPOSE 3000 3333
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/local/bin/entrypoint.sh"]