Repository navigation
Expand file tree
/
Copy pathDockerfile
More file actions
70 lines (61 loc) · 2.82 KB
/
Copy pathDockerfile
File metadata and controls
70 lines (61 loc) · 2.82 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
# Node 24, not 22: the backend stores board records through `node:sqlite`, which
# 22 gates behind --experimental-sqlite.
FROM node:24-alpine AS base
RUN corepack enable
FROM base AS board-build
WORKDIR /app
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
COPY board/package.json ./board/package.json
COPY admin/package.json ./admin/package.json
COPY backend/package.json ./backend/package.json
RUN pnpm install --frozen-lockfile --filter flipoff-board
# The board inlines its boot grid from the backend's seed module at build time.
COPY backend/src/config/seed.ts ./backend/src/config/seed.ts
COPY board/ ./board/
RUN pnpm -C board build
FROM base AS admin-build
WORKDIR /app
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
COPY board/package.json ./board/package.json
COPY admin/package.json ./admin/package.json
COPY backend/package.json ./backend/package.json
RUN pnpm install --frozen-lockfile --filter flipoff-admin
COPY admin/ ./admin/
RUN pnpm -C admin build
FROM base AS backend-build
WORKDIR /app
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
COPY board/package.json ./board/package.json
COPY admin/package.json ./admin/package.json
COPY backend/package.json ./backend/package.json
RUN pnpm install --frozen-lockfile --filter flipoff-backend
COPY backend/ ./backend/
RUN pnpm -C backend build
FROM base AS production
WORKDIR /app
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
COPY board/package.json ./board/package.json
COPY admin/package.json ./admin/package.json
COPY backend/package.json ./backend/package.json
# No native modules here (bcryptjs is pure JS), so this needs no toolchain. The
# pnpm store is dropped in the same layer that creates it -- a later RUN would
# leave it in the image regardless, since layers only ever add.
RUN pnpm install --frozen-lockfile --filter flipoff-backend --prod \
&& rm -rf /root/.cache /root/.local/share/pnpm/store
COPY --from=backend-build /app/backend/dist ./backend/dist
# The two frontends the server serves, each under its own root. Both Vite
# builds emit an `assets` directory, so they are kept apart here and mounted at
# separate URL prefixes (/assets for the admin at `/`, /b/assets for the board
# at /b/{slug}). The board is a pure client of /api/config; the admin talks
# only to /api/admin.
COPY --from=board-build /app/board/dist ./backend/public/board
COPY --from=admin-build /app/admin/dist ./backend/public/admin
ENV NODE_ENV=production
ENV PORT=8080
EXPOSE 8080
# /api/health rather than /api/config: every other endpoint is scoped to a
# board and answers 400 without one.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "require('http').get('http://127.0.0.1:'+(process.env.PORT||8080)+'/api/health',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))"
WORKDIR /app/backend
CMD ["node", "dist/main.js"]