-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathDockerfile.api
More file actions
137 lines (132 loc) · 5.68 KB
/
Dockerfile.api
File metadata and controls
137 lines (132 loc) · 5.68 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
FROM node:22-bookworm-slim AS base
RUN corepack enable
WORKDIR /app
# --- dependency stage ---
# node-pty (used by the in-app CLI OAuth login modal) ships native bindings
# without prebuilt Linux binaries on most channels, so we install build tools
# here so `pnpm install` can compile it from source.
FROM base AS deps
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
python3 \
&& rm -rf /var/lib/apt/lists/*
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json .npmrc ./
COPY packages/db/package.json packages/db/
COPY packages/domain/package.json packages/domain/
COPY packages/agent/package.json packages/agent/
COPY packages/ai/package.json packages/ai/
COPY packages/ingestion/package.json packages/ingestion/
COPY packages/integrations/package.json packages/integrations/
COPY packages/vector/package.json packages/vector/
COPY packages/mcp-server/package.json packages/mcp-server/
COPY packages/vision/package.json packages/vision/
COPY apps/api/package.json apps/api/
COPY apps/worker/package.json apps/worker/
RUN pnpm install --frozen-lockfile
# pnpm 10's approve-builds policy denies node-pty's `install` script
# (the one that runs `node-gyp rebuild`). node-pty ships prebuilds for
# darwin/win32 but NOT linux-x64, so the linux runtime needs that
# rebuild or the api crashes with "Failed to load native module:
# pty.node" at first require.
#
# We bypass pnpm by running node-gyp directly in the node-pty package
# dir. Installing node-gyp globally avoids the `.bin` discovery dance
# that pnpm's symlink layout makes awkward inside a package subdir.
# The trailing `test -f` makes a silent build failure fail the image
# build instead of crashing the api in prod.
RUN npm install -g node-gyp@^11
RUN set -eux \
&& PTY_DIR=$(find /app/node_modules -maxdepth 6 -type d -name "node-pty" 2>/dev/null | head -1) \
&& test -n "$PTY_DIR" \
&& cd "$PTY_DIR" \
&& node-gyp rebuild \
&& test -f build/Release/pty.node
# --- build stage ---
FROM base AS builder
COPY --from=deps /app ./
COPY . .
RUN pnpm --filter @bidwright/db db:generate
# Build workspace packages — their main now points at dist/index.js for
# Node ESM resolution. Without this build, seed scripts (db-migrate
# container) that import @bidwright/domain fail with "Cannot find
# package .../dist/index.js".
RUN pnpm -r --filter "./packages/*" build
RUN pnpm --filter @bidwright/api build
# Runtime images copy dependencies separately from app source so normal
# source edits do not force prod to pull a fresh node_modules-sized layer.
FROM builder AS app
RUN rm -rf node_modules apps/*/node_modules packages/*/node_modules
# --- LibreDWG builder stage ---
FROM debian:bookworm-slim AS libredwg-builder
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
pkg-config \
python3 \
wget \
texinfo \
xz-utils \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN wget -q -O /tmp/libredwg.tar.gz "https://github.com/LibreDWG/libredwg/releases/download/0.13.4/libredwg-0.13.4.tar.gz" \
&& mkdir -p /tmp/libredwg-src \
&& tar xzf /tmp/libredwg.tar.gz -C /tmp/libredwg-src --strip-components=1 \
&& cd /tmp/libredwg-src \
&& ./configure --disable-bindings --disable-shared \
&& make -j"$(nproc)" \
&& make install \
&& rm -rf /tmp/libredwg.tar.gz /tmp/libredwg-src
# --- runtime stage ---
FROM node:22-bookworm-slim AS runner
RUN corepack enable
# bubblewrap is the per-tenant CLI sandbox primitive used by
# BubblewrappedHost when BIDWRIGHT_MODE=server + BIDWRIGHT_MULTITENANT=true.
# The Debian package installs /usr/bin/bwrap setuid-root by default, which
# is the recommended posture: lets unprivileged container processes create
# user/mount/pid namespaces without granting CAP_SYS_ADMIN on the
# container itself. We re-assert the setuid bit defensively in case a
# future Debian build changes the default.
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-venv \
python3-pip \
openjdk-17-jdk-headless \
poppler-utils \
tesseract-ocr \
libgl1 \
libglib2.0-0 \
libgomp1 \
git \
wget \
unzip \
ripgrep \
bubblewrap \
&& rm -rf /var/lib/apt/lists/* \
&& chmod u+s /usr/bin/bwrap \
&& /usr/bin/bwrap --version
COPY --from=libredwg-builder /usr/local/bin/dwg2dxf /usr/local/bin/dwg2dxf
COPY --from=libredwg-builder /usr/local/bin/dwgread /usr/local/bin/dwgread
RUN wget -q -O /tmp/mpxj.zip "https://downloads.sourceforge.net/project/mpxj/mpxj/Version%2016.1.0/mpxj-16.1.0.zip" \
&& mkdir -p /opt/mpxj-dist /opt/mpxj \
&& unzip -q /tmp/mpxj.zip -d /opt/mpxj-dist \
&& find /opt/mpxj-dist -mindepth 1 -maxdepth 1 -type d -exec cp -R {}/. /opt/mpxj/ \; \
&& rm -rf /tmp/mpxj.zip /opt/mpxj-dist
ENV VIRTUAL_ENV=/opt/vision-venv
ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
ENV PYTHON_PATH="${VIRTUAL_ENV}/bin/python"
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
COPY packages/vision/python/requirements.txt /tmp/vision-requirements.txt
RUN python3 -m venv "${VIRTUAL_ENV}" \
&& "${VIRTUAL_ENV}/bin/pip" install --no-cache-dir --upgrade pip setuptools wheel \
&& "${VIRTUAL_ENV}/bin/pip" install --no-cache-dir -r /tmp/vision-requirements.txt
# Install the agent CLIs the production app shells out to.
RUN npm install -g @anthropic-ai/claude-code @openai/codex
RUN npm install -g playwright@1.58.2 \
&& playwright install --with-deps chromium \
&& npm uninstall -g playwright \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=deps /app ./
COPY --from=app /app ./
RUN javac -cp "/opt/mpxj/*:/opt/mpxj/lib/*" apps/api/src/services/schedule-import/mpxj-bridge/BidwrightMpxjJson.java
EXPOSE 3001
CMD ["pnpm", "--filter", "@bidwright/api", "exec", "tsx", "src/index.ts"]