Repository navigation
Expand file tree
/
Copy pathDockerfile
More file actions
122 lines (92 loc) · 5.17 KB
/
Copy pathDockerfile
File metadata and controls
122 lines (92 loc) · 5.17 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
# Multi-stage Dockerfile for MOCA Codex monorepo
# Stage 1: Build stage
FROM oven/bun:1.2.0-alpine AS builder
# Accept TURBO_TOKEN as build argument for remote caching
ARG TURBO_TOKEN
ENV TURBO_TOKEN=$TURBO_TOKEN
# Install turbo globally
RUN bun install -g turbo
# Install build dependencies for native modules (e.g., isolated-vm)
# py3-setuptools provides distutils which is required by node-gyp (removed from Python 3.12+)
# nodejs is required for isolated-vm's build scripts which call node directly
RUN apk add --no-cache python3 py3-setuptools g++ make nodejs npm
# Ensure node-gyp and build scripts use the actual Node.js binary (not Bun's node compatibility)
# Bun's node compatibility doesn't fully support process.config which isolated-vm needs
ENV npm_config_node=/usr/bin/node
ENV PATH=/usr/bin:$PATH
# Set working directory
WORKDIR /app
# Copy root package files
COPY package.json bun.lock turbo.json ./
# Copy all workspace package.json files
COPY apps/api/package.json ./apps/api/
COPY apps/api/extensions/directus-extension-codex/package.json ./apps/api/extensions/directus-extension-codex/
COPY apps/documentation/package.json ./apps/documentation/
COPY packages/config/package.json ./packages/config/
COPY packages/eslint-config-custom/package.json ./packages/eslint-config-custom/
COPY packages/types/package.json ./packages/types/
# Copy patches directory (needed for patch-package if it exists)
COPY patches ./patches
# Install dependencies
RUN bun install --frozen-lockfile
# Copy source code
COPY . .
# Build the project using turbo with increased memory limit
RUN NODE_OPTIONS="--max-old-space-size=4096" APP_ENV=production bun run build:api
# Ensure migrations directory exists for copying (even if empty)
RUN mkdir -p /app/apps/api/migrations
# Ensure seed directory exists for copying (even if empty)
RUN mkdir -p /app/apps/api/extensions/directus-extension-codex/seed
# Stage 2: Production stage for API (Directus)
FROM node:20-alpine as third-party-ext
RUN apk add --no-cache python3 g++ make
WORKDIR /extensions
# Install third-party Directus extensions
RUN printf '{\n "name": "directus-extensions",\n "private": true,\n "dependencies": {\n "directus-extension-api-docs": "^2.3.1",\n "directus-extension-sync": "^3.0.5",\n "@pnpm/find-workspace-dir": "^1.0.0",\n "@pnpm/error": "^3.0.0"\n }\n}\n' > package.json
RUN npm install --no-audit --no-fund --legacy-peer-deps
# Move all installed directus extensions into /extensions/directus
RUN mkdir -p ./directus && \
cd node_modules && \
find . -maxdepth 1 -type d -name "directus-extension-*" -exec mv {} ../directus \;
# Install devDependencies and peer dependencies for directus-extension-api-docs
# Includes express (required by swagger-ui-express) and ajv (required by ajv-draft-04)
RUN cd ./directus/directus-extension-api-docs && \
npm install --no-audit --no-fund --legacy-peer-deps --include=dev ajv || true
# Pinned: Directus 12.3+ returns 403 for unauthenticated /server/health (breaks docker healthcheck);
# pin instead of :latest so upstream changes don't break prod deploys unexpectedly
FROM directus/directus:12.3.1 AS api-production
# Switch to root to install dependencies and copy files
USER root
# Install curl, postgresql-client, and npm for health checks and dependency installation (Alpine uses apk)
RUN apk add --no-cache curl postgresql-client npm
# Copy third-party extensions built in separate stage
COPY --from=third-party-ext --chown=node:node /extensions/directus /directus/extensions
# Copy built extensions from builder stage
# This will include the seed folder if it exists in the source
COPY --from=builder --chown=node:node /app/apps/api/extensions /directus/extensions
# Ensure seed directory exists (in case it wasn't in the source or was empty)
RUN mkdir -p /directus/extensions/directus-extension-codex/seed
# Install devDependencies and peer dependencies for directus-extension-api-docs
# Includes express (required by swagger-ui-express) and ajv (required by ajv-draft-04)
RUN cd /directus/extensions/directus-extension-api-docs && \
npm install --no-audit --no-fund --legacy-peer-deps --include=dev ajv && \
test -d node_modules/express && echo "✅ express installed successfully" || echo "❌ express installation failed" && \
test -d node_modules/ajv && echo "✅ ajv installed successfully" || echo "❌ ajv installation failed"
# Verify all extensions are properly installed
RUN ls -la /directus/extensions/ && \
echo "✅ All extensions installed successfully"
RUN ls -la /directus/extensions/directus-extension-codex/ && \
echo "✅ directus-extension-codex installed successfully"
# Copy Directus configuration
COPY --from=builder --chown=node:node /app/apps/api/directus-config /directus/directus-config
# Copy migrations directory from builder stage
COPY --from=builder --chown=node:node /app/apps/api/migrations/ /directus/migrations/
# Switch back to node user
USER node
# Expose port
EXPOSE 8055
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=5 \
CMD curl -f http://localhost:8055/server/health || exit 1
# Run bootstrap (applies pending migrations + ensures admin user) then start
CMD ["sh", "-c", "npx directus bootstrap && npx directus start"]