-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathDockerfile
More file actions
73 lines (52 loc) · 2.29 KB
/
Dockerfile
File metadata and controls
73 lines (52 loc) · 2.29 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
# Multi-stage Docker build for freeCodeCamp Curriculum GraphQL API
# Follows freeCodeCamp's main repository build patterns
# Stage 1: Builder - Build TypeScript and fetch curriculum data
FROM node:24-bookworm AS builder
# Install dependencies needed for build
RUN apt-get update && apt-get install -y git
# Install pnpm globally before switching to node user
RUN npm i -g pnpm@10
# Use the existing node user from the base image
USER node
WORKDIR /home/node/build
# Copy package files with correct ownership
COPY --chown=node:node package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
COPY --chown=node:node tsconfig*.json ./
COPY --chown=node:node packages/server/ packages/server/
COPY --chown=node:node scripts/ scripts/
# Install all dependencies (including dev dependencies for build)
RUN pnpm install --frozen-lockfile
# Fetch curriculum data using giget
RUN node scripts/fetch-curriculum-data.mjs
# Build the TypeScript project
RUN pnpm build
# Stage 2: Production Dependencies
FROM node:24-bookworm AS deps
WORKDIR /home/node/build
# Copy package files
COPY --chown=node:node package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY --chown=node:node packages/server/package.json packages/server/
# Install pnpm globally
RUN npm i -g pnpm@10
# Install only production dependencies (skip prepare scripts like husky)
RUN pnpm install --prod --frozen-lockfile --ignore-scripts
# Stage 3: Production Runtime
FROM node:24-bookworm
# Use the node user for production
USER node
WORKDIR /home/node/fcc
# Set production environment
ENV NODE_ENV=production
# Copy built application from builder
COPY --from=builder --chown=node:node /home/node/build/packages/server/dist/ packages/server/dist/
COPY --from=builder --chown=node:node /home/node/build/data/ data/
# Copy production dependencies from deps stage
COPY --from=deps --chown=node:node /home/node/build/node_modules/ node_modules/
COPY --from=deps --chown=node:node /home/node/build/packages/server/node_modules/ packages/server/node_modules/
# Expose port
EXPOSE 4000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD node -e "require('http').get('http://localhost:4000/graphql?query={__typename}', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
# Start server
CMD ["node", "packages/server/dist/index.js"]