-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathDockerfile
More file actions
92 lines (72 loc) · 3.25 KB
/
Dockerfile
File metadata and controls
92 lines (72 loc) · 3.25 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
# ==================================================
# Claude Code Gateway - Hardened Dockerfile
# ==================================================
# Security features:
# - Multi-stage build (smaller attack surface)
# - Non-root user execution (bun user, UID 1000)
# - Bun runtime (~100MB smaller than node:20-slim)
# ==================================================
# ----- Stage 1: Build -----
# Pin to specific Bun version for reproducible builds
# Bun 1.2+ uses lockfile v1 format; any 1.2+ version can read it
FROM oven/bun:1.3.3-slim AS builder
WORKDIR /app
# Copy package files (root workspace + all workspace packages)
COPY package.json ./
COPY bun.lock* ./
COPY packages/gateway/package.json ./packages/gateway/
COPY packages/sdks/typescript/package.json ./packages/sdks/typescript/
# Install dependencies (including dev deps for build)
# Falls back to non-frozen install if no lockfile exists
RUN bun install --frozen-lockfile || bun install
# Copy source code
COPY packages/gateway/tsconfig.json ./packages/gateway/
COPY packages/gateway/src ./packages/gateway/src
# Build TypeScript using tsc (preserves module structure for Express compatibility)
WORKDIR /app/packages/gateway
RUN bun run build
WORKDIR /app
# Re-install with production deps only
# --ignore-scripts: skip prepare script (husky) since it's a dev dependency
RUN rm -rf node_modules packages/gateway/node_modules && bun install --production --ignore-scripts
# ----- Stage 2: Runtime -----
FROM oven/bun:1.3.3-slim
# Install runtime dependencies (as root, before USER switch)
# - curl: required for healthcheck
# - ca-certificates: required for HTTPS API calls
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Create node symlink pointing to bun (Bun is Node-compatible)
# Required because Claude CLI shebang uses #!/usr/bin/env node
RUN ln -s /usr/local/bin/bun /usr/local/bin/node
# Install Claude Code CLI globally to a shared location accessible by all users
# BUN_INSTALL sets the root for both packages and binaries
ENV BUN_INSTALL="/usr/local/share/bun"
ENV PATH="/usr/local/share/bun/bin:$PATH"
RUN bun install -g @anthropic-ai/claude-code
# Create app directory
WORKDIR /app
# Copy built artifacts with bun user ownership
COPY --from=builder --chown=bun:bun /app/package.json ./
COPY --from=builder --chown=bun:bun /app/node_modules ./node_modules
COPY --from=builder --chown=bun:bun /app/packages/gateway/package.json ./packages/gateway/
COPY --from=builder --chown=bun:bun /app/packages/gateway/dist ./packages/gateway/dist
# Copy OpenAPI spec for /docs endpoint
COPY --chown=bun:bun docs/openapi.yaml ./docs/
# Create Claude CLI data directory for the bun user
RUN mkdir -p /home/bun/.claude && chown -R bun:bun /home/bun/.claude
# Copy Claude skills/commands to the Claude CLI config directory
# These enable Claude Code to use custom tools and slash commands
COPY --chown=bun:bun claude-assets /home/bun/.claude
# Switch to non-root user
USER bun
# Expose the service port
EXPOSE 3100
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3100/health || exit 1
# Start the service
CMD ["bun", "run", "packages/gateway/dist/index.js"]