group conversations with models and local files
1# Multi-stage build: produce a small image with just the runtime.
2#
3# Build args:
4# PORT (default 3001) — server listen port
5# HEZO_DATA (default /data) — where SQLite files + blobs live
6#
7# Volume: /data should be mounted persistently on Railway etc.
8
9FROM node:20-bookworm-slim AS build
10WORKDIR /app
11
12# Install all deps, including dev (needed to build).
13COPY package.json package-lock.json ./
14RUN npm ci
15
16# Source + build.
17COPY tsconfig.json tsconfig.server.json tsconfig.web.json vite.config.ts ./
18COPY index.html ./
19COPY src ./src
20COPY server ./server
21RUN npm run build
22
23# Prune dev deps for the runtime image.
24RUN npm prune --omit=dev
25
26
27FROM node:20-bookworm-slim AS runtime
28WORKDIR /app
29
30# better-sqlite3 has a native module; the build stage's node_modules already
31# contains a Linux-built binary, so copy it as-is.
32COPY --from=build /app/node_modules ./node_modules
33COPY --from=build /app/package.json ./package.json
34COPY --from=build /app/dist-web ./dist-web
35COPY --from=build /app/dist-server ./dist-server
36
37ENV NODE_ENV=production
38ENV PORT=3001
39ENV HOST=0.0.0.0
40ENV HEZO_DATA=/data
41
42EXPOSE 3001
43# On Railway: mount a volume at /data via `railway volume add --mount-path /data`.
44# (Don't use the Dockerfile VOLUME directive — Railway rejects it.)
45
46CMD ["node", "dist-server/server/index.js"]