-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
78 lines (63 loc) · 3.09 KB
/
Copy pathDockerfile
File metadata and controls
78 lines (63 loc) · 3.09 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
# CodeCraft — zwei Abbilder aus einer Datei.
#
# `web` liefert den Editor als statische Dateien über nginx, `server` das
# Backend als Node-Prozess. Beide entstehen aus demselben Build, damit Editor
# und Protokoll nie auseinanderlaufen können: packages/protocol wird von beiden
# Seiten importiert, und ein halber Deploy hätte genau dort die Naht.
#
# docker compose build
# docker compose up -d
# ------------------------------------------------------------- Abhängigkeiten
FROM node:22-alpine AS deps
WORKDIR /app
# Nur die Manifeste zuerst: solange sich keine Abhängigkeit ändert, bleibt
# diese Schicht im Cache, auch wenn sich der Quelltext ändert.
COPY package.json package-lock.json ./
COPY apps/server/package.json apps/server/
COPY apps/web/package.json apps/web/
COPY packages/blocks/package.json packages/blocks/
COPY packages/emoji/package.json packages/emoji/
COPY packages/protocol/package.json packages/protocol/
RUN npm ci
# --------------------------------------------------------------------- Build
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/apps/web/node_modules ./apps/web/node_modules
COPY . .
# Typprüfung und Tests laufen mit. Ein Abbild, das nicht typprüft, soll gar
# nicht erst entstehen — auf dem Server fällt es sonst erst zur Laufzeit auf.
RUN npm run typecheck && npm test
RUN npm run build -w @codecraft/web
# ------------------------------------------------------------------- Editor
FROM nginx:alpine AS web
COPY docker/web/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/apps/web/dist /usr/share/nginx/html
# ------------------------------------------------------------------ Backend
FROM node:22-alpine AS server
WORKDIR /app
ENV NODE_ENV=production
# tsx statt eines Build-Schritts: die Pakete zeigen mit "main" direkt auf ihre
# .ts-Quellen (siehe packages/*/package.json), es gibt also gar kein
# kompiliertes Ergebnis, das man kopieren könnte. tsx liegt als
# devDependency von @codecraft/server in node_modules — `npx tsx` würde es
# sonst bei jedem Containerstart aus dem Netz nachladen.
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/apps/server ./apps/server
COPY --from=build /app/packages ./packages
# Nicht als root. Das Datenverzeichnis gehört diesem Nutzer — die uid steht
# auch in der README, denn beim Bind-Mount muss das Verzeichnis auf dem Host
# ihm gehören.
RUN addgroup -g 10001 codecraft \
&& adduser -u 10001 -G codecraft -S -h /app codecraft \
&& mkdir -p /daten \
&& chown codecraft:codecraft /daten
USER codecraft
ENV CODECRAFT_DATA=/daten/backend.json
ENV PORT=8090
EXPOSE 8090
# Ohne curl im Abbild: Node kann selbst anfragen.
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "fetch('http://127.0.0.1:8090/api/v1/pair',{method:'POST',headers:{'Content-Type':'application/json'},body:'{\"code\":\"AAAAA\"}'}).then(r=>process.exit(r.status===404||r.status===429?0:1)).catch(()=>process.exit(1))"
CMD ["node_modules/.bin/tsx", "apps/server/src/index.ts"]