Repository navigation
Expand file tree
/
Copy pathDockerfile.server
More file actions
117 lines (100 loc) · 5.25 KB
/
Copy pathDockerfile.server
File metadata and controls
117 lines (100 loc) · 5.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# =============================================================================
# Craft Agents Server — multi-platform Docker image
#
# Build:
# docker buildx build -f Dockerfile.server -t craft-agent-server .
#
# Run (use --user to match host UID/GID for volume permissions):
# docker run --rm -p 9100:9100 \
# --user $(id -u):$(id -g) \
# -e HOME=/home/craftagents \
# -e CRAFT_SERVER_TOKEN=<secret> \
# craft-agent-server
#
# Run with TLS + mounted config:
# docker run --rm -p 9100:9100 \
# --user $(id -u):$(id -g) \
# -e HOME=/home/craftagents \
# -e CRAFT_SERVER_TOKEN=<secret> \
# -e CRAFT_RPC_TLS_CERT=/certs/cert.pem \
# -e CRAFT_RPC_TLS_KEY=/certs/key.pem \
# -v /path/to/certs:/certs:ro \
# -v ~/.craft-agent:/home/craftagents/.craft-agent \
# craft-agent-server
# =============================================================================
FROM oven/bun:1.3-slim
LABEL org.opencontainers.image.source="https://github.com/craft-ai-agents/craft-agents-oss"
LABEL org.opencontainers.image.description="Craft Agents Server — headless AI workflow server"
LABEL org.opencontainers.image.licenses="Apache-2.0"
# Install system deps + Node.js (required by the WhatsApp worker subprocess;
# Bun cannot run Baileys' crypto deps). Pin Node to a major via NodeSource so
# upgrades are explicit — must match the --target in scripts/build-wa-worker.ts.
ARG NODE_MAJOR=20
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates git ripgrep curl gnupg && \
curl -fsSL https://deb.nodesource.com/setup_${NODE_MAJOR}.x | bash - && \
apt-get install -y --no-install-recommends nodejs && \
rm -rf /var/lib/apt/lists/*
# Create non-root user (Claude Code SDK refuses to run as root).
# At runtime, override with --user $(id -u):$(id -g) to match host permissions.
RUN groupadd -r craftagents && \
useradd -r -g craftagents -m -d /home/craftagents -s /bin/bash craftagents
WORKDIR /app
# Copy dependency manifests first for layer caching.
# `bunfig.toml` MUST be in the WORKDIR before `bun install` runs — it sets
# `linker = "hoisted"`, which is required for the WebUI / renderer build
# (transitive deps like i18next, @tiptap/*, pdfjs-dist resolve at top-level
# node_modules). Without it Bun defaults to isolated installs and the Vite
# build fails on the first transitive bare-package import.
COPY package.json bun.lock bunfig.toml ./
COPY packages/server/package.json packages/server/
COPY packages/server-core/package.json packages/server-core/
COPY packages/shared/package.json packages/shared/
COPY packages/core/package.json packages/core/
COPY packages/session-tools-core/package.json packages/session-tools-core/
COPY packages/pi-agent-server/package.json packages/pi-agent-server/
COPY packages/craft-agents-commands/package.json packages/craft-agents-commands/
COPY packages/craft-cli/package.json packages/craft-cli/
COPY packages/ui/package.json packages/ui/
COPY packages/messaging-gateway/package.json packages/messaging-gateway/
COPY packages/messaging-whatsapp-worker/package.json packages/messaging-whatsapp-worker/
COPY apps/electron/package.json apps/electron/
COPY apps/cli/package.json apps/cli/
COPY apps/marketing/package.json apps/marketing/
COPY apps/viewer/package.json apps/viewer/
COPY apps/webui/package.json apps/webui/
COPY apps/docs-site/package.json apps/docs-site/
RUN bun install --frozen-lockfile
# Copy source
COPY . .
# Build the Pi agent server subprocess (required by runtime-resolver.ts)
RUN bun build packages/pi-agent-server/src/index.ts \
--outfile packages/pi-agent-server/dist/index.js --target node --format cjs
# Build the WhatsApp worker bundle (CJS, Node target — Bun cannot run it).
RUN bun run scripts/build-wa-worker.ts
# Build web UI assets (served by the server on the RPC port).
# vite's bundler runs under Node (via shebang in vite's bin) and hits V8's
# default ~2GB heap cap on the rendering phase (>5k modules). Raise to 4GB
# so low-RAM build hosts (e.g. 4GB VPS) can complete the build.
RUN NODE_OPTIONS="--max-old-space-size=4096" bunx vite build --config apps/webui/vite.config.ts
# Pre-create .craft-agent so Docker named volumes inherit the correct permissions.
RUN mkdir -p /home/craftagents/.craft-agent
# Make app world-readable so any --user can run it. Home dir is writable for .craft-agent.
# Use find to only touch files/dirs missing the read bit — much faster than chmod -R on the
# entire tree (node_modules alone has hundreds of thousands of entries).
RUN find /app -not -perm -o=r -exec chmod o+r {} + && \
find /app -type d -not -perm -o=x -exec chmod o+x {} + && \
chmod -R 777 /home/craftagents
USER craftagents
ENV CRAFT_RPC_HOST=0.0.0.0
ENV CRAFT_RPC_PORT=9100
ENV CRAFT_WEBUI_DIR=/app/apps/webui/dist
ENV CRAFT_BUNDLED_ASSETS_ROOT=/app/apps/electron
# WhatsApp worker — Bun cannot run the CJS worker, so we point the adapter at
# system `node` (installed above). If CRAFT_BUNDLED_ASSETS_ROOT changes, update
# CRAFT_MESSAGING_WA_WORKER to match; the default in packages/server resolves
# against CRAFT_BUNDLED_ASSETS_ROOT, but the layout above flattens to /app.
ENV CRAFT_MESSAGING_WA_WORKER=/app/packages/messaging-whatsapp-worker/dist/worker.cjs
ENV CRAFT_MESSAGING_NODE_BIN=node
EXPOSE 9100
ENTRYPOINT ["bun", "run", "packages/server/src/index.ts"]