Files
homelab/apps/harness/Dockerfile
Julia McGhee 548b0fde98
All checks were successful
CI / lint-and-test (push) Successful in 38s
Deploy Production / deploy (push) Successful in 1m26s
CI / build (push) Successful in 1m52s
Fix harness crash: load standalone config to skip webpack in production
The standalone next package is trimmed and doesn't include webpack.
The custom server.js was using next() which triggers config loading
that requires webpack. Fix by extracting the standalone config at
build time and setting __NEXT_PRIVATE_STANDALONE_CONFIG before
requiring next, matching what the generated standalone server does.
2026-03-21 21:44:15 +00:00

78 lines
3.0 KiB
Docker

FROM golang:1.26-alpine AS gitea-mcp-builder
ENV GOBIN=/usr/local/bin
RUN go install gitea.com/gitea/gitea-mcp@latest
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@latest --activate
FROM base AS deps
RUN apk add --no-cache libc6-compat python3 make gcc g++ linux-headers
WORKDIR /app
# Use local Node.js headers for node-gyp (avoids flaky unofficial-builds.nodejs.org downloads)
ENV npm_config_nodedir=/usr/local
# Copy workspace root config + relevant package.jsons for install
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
COPY packages/db/package.json ./packages/db/package.json
COPY apps/harness/package.json ./apps/harness/package.json
RUN pnpm install --frozen-lockfile --filter @homelab/harness...
FROM base AS builder
WORKDIR /app
COPY --from=deps /app ./
COPY packages/db ./packages/db
COPY apps/harness ./apps/harness
RUN pnpm --filter @homelab/harness build
# Extract standalone next config so the custom server can skip webpack loading
RUN node -e "\
const s = require('fs').readFileSync('apps/harness/.next/standalone/apps/harness/server.js','utf8');\
const m = s.match(/const nextConfig = (\\{.+\\})\n/);\
require('fs').writeFileSync('apps/harness/.next/standalone/apps/harness/next-config.json', m[1]);"
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
# System tools needed by agent executors
RUN apk add --no-cache git github-cli curl ca-certificates
# Agent CLIs (installed globally before dropping to non-root)
RUN npm install -g @anthropic-ai/claude-code @openai/codex
RUN curl -fsSL https://opencode.ai/install | sh || \
echo "WARN: opencode install failed, skipping"
# MCP servers: Gitea (Go binary from builder stage)
COPY --from=gitea-mcp-builder /usr/local/bin/gitea-mcp /usr/local/bin/gitea-mcp
# MCP servers: Node.js packages (pre-installed to avoid npx cold starts)
RUN npm install -g \
@modelcontextprotocol/server-postgres \
@modelcontextprotocol/server-filesystem \
kubernetes-mcp-server
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Workspace directory for git worktrees (ephemeral)
RUN mkdir -p /data/harness && chown nextjs:nodejs /data/harness
COPY --from=builder /app/apps/harness/public ./apps/harness/public
COPY --from=builder --chown=nextjs:nodejs /app/apps/harness/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/harness/.next/static ./apps/harness/.next/static
# Harness MCP server (self-contained bundle for agent→harness communication)
COPY --from=builder /app/apps/harness/dist/mcp-server.mjs ./apps/harness/dist/mcp-server.mjs
# PTY server dependencies + custom server
COPY --from=builder /app/node_modules/.pnpm/node-pty*/node_modules/node-pty ./node_modules/node-pty
COPY --from=builder /app/node_modules/.pnpm/ws*/node_modules/ws ./node_modules/ws
COPY apps/harness/server.js ./apps/harness/server.js
COPY apps/harness/pty-server.js ./apps/harness/pty-server.js
USER nextjs
EXPOSE 3100
ENV PORT=3100
CMD ["node", "apps/harness/server.js"]