forked from InsForge/InsForge
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
125 lines (88 loc) · 4.24 KB
/
Dockerfile
File metadata and controls
125 lines (88 loc) · 4.24 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
# ============================================================
# Stage 1: package-prep — strip version from root package.json
# ============================================================
# Separate stage so that COPY --from uses content-based caching.
# Even if this stage rebuilds on version bump, the OUTPUT is
# identical (version removed), so downstream COPY --from hits cache.
# Pinned deno version — matches docker-compose deno runtime (denoland/deno:alpine-2.0.6)
ARG DENO_VERSION=2.0.6
FROM denoland/deno:alpine-${DENO_VERSION} AS deno-bin
FROM node:20-alpine AS package-prep
RUN apk add --no-cache jq
COPY package.json /tmp/package.json
RUN mkdir -p /out && \
jq 'del(.version) | .workspaces = [.workspaces[] | select(. != "mcp")]' \
/tmp/package.json > /out/package.json
# ============================================================
# Stage 2: deps — ALL dependencies (dev + prod) for building
# ============================================================
FROM node:20-alpine AS deps
WORKDIR /app
# Root package.json comes from package-prep (version stripped).
# COPY --from uses content-based cache: if output is identical,
# this layer and npm install below stay cached across releases.
COPY --from=package-prep /out/package.json ./package.json
COPY package-lock.json ./package-lock.json
COPY backend/package.json ./backend/package.json
COPY frontend/package.json ./frontend/package.json
COPY auth/package.json ./auth/package.json
COPY shared-schemas/package.json ./shared-schemas/package.json
COPY ui/package.json ./ui/package.json
RUN npm ci && npm cache clean --force
# ============================================================
# Stage 3: build — compile all packages
# ============================================================
FROM deps AS build
COPY . .
# Vite bakes these into static bundles at compile time
ARG VITE_API_BASE_URL
ARG VITE_PUBLIC_POSTHOG_KEY
# Build order: ui → backend → frontend → auth
RUN npm run build
# ============================================================
# Stage 4: prod-deps — production dependencies only
# ============================================================
FROM node:20-alpine AS prod-deps
WORKDIR /app
COPY --from=package-prep /out/package.json ./package.json
COPY package-lock.json ./package-lock.json
COPY backend/package.json ./backend/package.json
COPY frontend/package.json ./frontend/package.json
COPY auth/package.json ./auth/package.json
COPY shared-schemas/package.json ./shared-schemas/package.json
COPY ui/package.json ./ui/package.json
RUN npm ci --omit=dev && npm cache clean --force
# ============================================================
# Stage 5: runner — minimal production image
# ============================================================
FROM node:20-alpine AS runner
# tini: proper PID 1 for signal forwarding and zombie reaping
RUN apk add --no-cache tini
WORKDIR /app
# Production node_modules (hoisted by npm workspaces)
COPY --from=prod-deps /app/node_modules ./node_modules
# Compiled output: server.js + frontend/ + auth/ static files
COPY --from=build /app/dist ./dist
# Migration runtime: tsx resolves @/* aliases via tsconfig.json,
# node-pg-migrate reads .sql files from backend/src/
COPY --from=build /app/backend/src ./backend/src
COPY --from=build /app/backend/tsconfig.json ./backend/tsconfig.json
COPY --from=build /app/shared-schemas/src ./shared-schemas/src
# Package manifests for npm scripts
COPY --from=build /app/backend/package.json ./backend/package.json
COPY --from=build /app/package.json ./package.json
# tsx is a devDependency but required at runtime for migrate:bootstrap
RUN npm install -g "tsx@^4.7.1" && npm cache clean --force
# Run as non-root using the built-in node user (uid 1000)
RUN chown -R node:node /app
USER node
EXPOSE 7130 7131
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["sh", "-c", "cd backend && npm run migrate:up && cd .. && exec npm start"]
# ============================================================
# Stage: dev — development image (used by docker-compose)
# ============================================================
# Source code is mounted via volumes, only needs Node.js + Deno.
FROM node:20-alpine AS dev
COPY --from=deno-bin /bin/deno /usr/local/bin/deno
WORKDIR /app