-
Notifications
You must be signed in to change notification settings - Fork 340
Expand file tree
/
Copy pathDockerfile.dev
More file actions
111 lines (96 loc) · 5.72 KB
/
Copy pathDockerfile.dev
File metadata and controls
111 lines (96 loc) · 5.72 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
# syntax=docker/dockerfile:1
#
# From-source multi-stage build for local smoke / floating-main / SHA-tagged
# dev images. Production/OSS Helm images use the root Dockerfile (npm install).
#
# Lives at the repository root because the build needs the whole pnpm workspace
# as its context: the server depends on the workspace package @truefoundry/trueforge-core.
#
# Dependency install uses pnpm fetch (lockfile-only) then install --offline so
# the download layer stays cached when only package.json / scripts change.
# See https://pnpm.io/cli/fetch. BuildKit cache mounts are avoided so the same
# file builds on Railway Metal (which requires a hardcoded service id in mount ids).
FROM node:24-slim AS base
ENV PNPM_HOME=/pnpm
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && pnpm config set store-dir /pnpm/store
WORKDIR /app
# ---------------------------------------------------------------------------
# store: the pnpm store, from the lockfile only (stable when manifests churn).
# BuildKit cache mounts are omitted: Railway's Metal builder requires
# `id=s/<service-id>-…` (hardcoded per deploy), which cannot live in a shared
# OSS Dockerfile. Layer cache on this stage still hits when the lockfile is
# unchanged.
# ---------------------------------------------------------------------------
FROM base AS store
COPY pnpm-lock.yaml pnpm-workspace.yaml ./
RUN pnpm fetch
# ---------------------------------------------------------------------------
# workspace: install inputs shared by every stage below — the manifests plus the
# sources the root postinstall hook (build:gen) inlines.
# ---------------------------------------------------------------------------
FROM store AS workspace
COPY package.json .npmrc tsconfig.base.json ./
COPY packages/trueforge-core/package.json packages/trueforge-core/package.json
COPY packages/trueforge/package.json packages/trueforge/package.json
COPY packages/trueforge-sdk/package.json packages/trueforge-sdk/package.json
COPY packages/frontend/package.json packages/frontend/package.json
COPY packages/trueforge-ui/package.json packages/trueforge-ui/package.json
COPY packages/trueforge-core/scripts packages/trueforge-core/scripts
COPY packages/trueforge-core/src/core/sandbox/scripts packages/trueforge-core/src/core/sandbox/scripts
# ---------------------------------------------------------------------------
# builder: install all deps (incl. dev) and build trueforge-core + server.
# The server imports @truefoundry/trueforge-sdk (schedule dispatch), so the SDK
# must be built before `pnpm --filter @truefoundry/trueforge build` (tsc).
# ---------------------------------------------------------------------------
FROM workspace AS builder
RUN pnpm install --frozen-lockfile --offline --filter @truefoundry/trueforge...
COPY packages/trueforge-core packages/trueforge-core
COPY packages/trueforge-sdk packages/trueforge-sdk
RUN pnpm --filter @truefoundry/trueforge-sdk build
COPY packages/trueforge packages/trueforge
RUN pnpm --filter @truefoundry/trueforge-core build && pnpm --filter @truefoundry/trueforge build
# ---------------------------------------------------------------------------
# frontend-builder: build the UI the server serves (parallel to builder above).
# ---------------------------------------------------------------------------
FROM workspace AS frontend-builder
RUN pnpm install --frozen-lockfile --offline --filter frontend...
COPY packages/trueforge-sdk packages/trueforge-sdk
RUN pnpm --filter @truefoundry/trueforge-sdk build
COPY packages/trueforge-ui packages/trueforge-ui
RUN pnpm --filter @truefoundry/trueforge-ui build
COPY packages/frontend packages/frontend
RUN pnpm --filter frontend build
# ---------------------------------------------------------------------------
# prod-deps: production dependency tree (no dev tooling), resolved offline.
# ---------------------------------------------------------------------------
FROM workspace AS prod-deps
RUN pnpm install --frozen-lockfile --offline --prod --filter @truefoundry/trueforge...
# ---------------------------------------------------------------------------
# runner: minimal image with prod node_modules + built artifacts.
# ---------------------------------------------------------------------------
FROM base AS runner
ENV NODE_ENV=production \
HOST=0.0.0.0
# Production dependency tree (pnpm workspace symlinks preserved).
COPY --from=prod-deps /app/node_modules ./node_modules
COPY --from=prod-deps /app/packages/trueforge-core/node_modules ./packages/trueforge-core/node_modules
COPY --from=prod-deps /app/packages/trueforge/node_modules ./packages/trueforge/node_modules
# Built workspace dependencies (@truefoundry/trueforge-core + SDK).
COPY --from=builder /app/packages/trueforge-core/package.json ./packages/trueforge-core/package.json
COPY --from=builder /app/packages/trueforge-core/dist ./packages/trueforge-core/dist
COPY --from=builder /app/packages/trueforge-sdk/package.json ./packages/trueforge-sdk/package.json
COPY --from=builder /app/packages/trueforge-sdk/dist ./packages/trueforge-sdk/dist
# Built server (JS). UI is copied below from the parallel frontend stage into
# dist/_frontend — same path as the npm tarball / `pnpm build` copy step.
COPY --from=builder /app/packages/trueforge/package.json ./packages/trueforge/package.json
COPY --from=builder /app/packages/trueforge/dist ./packages/trueforge/dist
# Frontend builds in a parallel stage; place it at the same path as the npm tarball.
COPY --from=frontend-builder /app/packages/frontend/dist ./packages/trueforge/dist/_frontend
WORKDIR /app/packages/trueforge
RUN groupadd --gid 10001 trueforge \
&& useradd --uid 10001 --gid trueforge trueforge
EXPOSE 8790
# Launch-only (matches root `pnpm start` / `standalone:start`). Image already contains dist.
USER 10001:10001
CMD ["node", "dist/main.js"]