Repository navigation
Expand file tree
/
Copy pathDockerfile
More file actions
101 lines (80 loc) · 4.45 KB
/
Copy pathDockerfile
File metadata and controls
101 lines (80 loc) · 4.45 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
# Build stage
FROM node:26-slim@sha256:c0753125a3789977aefe869cbebccf70e3cfd7ea84ca48547458f02e4f1d7146 AS base
WORKDIR /app
# Set NODE_ENV to development to ensure devDependencies are installed for the build
ENV NODE_ENV=development
# Accept build argument for analytics feature flag
# - 'true': Enable Google Analytics tracking
# - 'false' or unset: Disable analytics (default for security/privacy)
ARG VITE_APP_CFG_FEATURE_FLAG_ANALYTICS_ENABLED=false
ENV VITE_APP_CFG_FEATURE_FLAG_ANALYTICS_ENABLED=$VITE_APP_CFG_FEATURE_FLAG_ANALYTICS_ENABLED
# Disable mainnet network selection on hosted Role Manager deployments
ARG VITE_APP_CFG_FEATURE_FLAG_MAINNET_NETWORKS_DISABLED=false
ENV VITE_APP_CFG_FEATURE_FLAG_MAINNET_NETWORKS_DISABLED=$VITE_APP_CFG_FEATURE_FLAG_MAINNET_NETWORKS_DISABLED
# Accept build argument for Google Analytics tag ID
ARG VITE_GA_TAG_ID
ENV VITE_GA_TAG_ID=$VITE_GA_TAG_ID
# Install build dependencies required for native Node.js modules
# node-gyp (used by some dependencies) requires python and build-essential
# 'python-is-python3' is used in newer Debian-based images instead of 'python'
RUN apt-get update && apt-get install -y python-is-python3 build-essential && rm -rf /var/lib/apt/lists/*
# Clear any potential corrupted Node.js cache that might cause gyp issues
RUN rm -rf /root/.cache/node-gyp /root/.npm /root/.node-gyp || true
# Install pnpm
RUN npm install -g pnpm
# Copy workspace configuration files
# Note: .pnpmfile.cjs is included because pnpm-lock.yaml has a checksum for it.
# The local-dev rewrite hook is a no-op in Docker (LOCAL_* env vars are not set),
# but the prerelease-widening hook (allowAdapterPrereleases) always runs.
COPY ./package.json ./pnpm-lock.yaml ./pnpm-workspace.yaml ./.npmrc ./.pnpmfile.cjs ./
COPY ./tsconfig.json ./tsconfig.base.json ./tsconfig.node.json ./
# Copy all workspace packages, apps, and scripts
COPY ./packages ./packages/
COPY ./apps ./apps/
COPY ./scripts ./scripts/
# Step 1: Install dependencies from frozen lockfile (exact production dependency tree)
# Retry once on failure after clearing possible corrupted caches to avoid node-gyp issues
RUN pnpm install --frozen-lockfile || (echo "Install failed, clearing caches and retrying..." && rm -rf /root/.cache/node-gyp /root/.npm /root/.node-gyp && pnpm install --frozen-lockfile)
# Step 2: Surgically override adapter packages for staging builds.
# When ADAPTER_DIST_TAG is set (e.g. "rc"), the resolution script queries npm for
# both the requested dist-tag and "latest", picks the newer version per adapter, and
# runs `pnpm add --save-exact` for only those packages. All non-adapter dependencies
# remain byte-for-byte identical to the frozen lockfile from Step 1.
# When ADAPTER_DIST_TAG is unset (production), this step is a no-op.
ARG ADAPTER_DIST_TAG
RUN if [ -n "$ADAPTER_DIST_TAG" ]; then \
node scripts/resolve-staging-adapters.cjs "$ADAPTER_DIST_TAG"; \
fi
# Set Node.js memory limit to prevent OOM during build
# This is especially important for TypeScript compilation in CI environments
ENV NODE_OPTIONS="--max-old-space-size=4096"
# Build all packages and the application with optimizations
# This step uses Docker BuildKit secrets to securely pass API keys
# The secrets are only available during this RUN command and won't be stored in the image
RUN --mount=type=secret,id=etherscan_api_key \
--mount=type=secret,id=routescan_api_key \
sh -c '\
if [ -f /run/secrets/etherscan_api_key ]; then \
export VITE_APP_CFG_SERVICE_ETHERSCANV2_API_KEY=$(cat /run/secrets/etherscan_api_key); \
else \
echo "Warning: Building without Etherscan API key"; \
fi && \
if [ -f /run/secrets/routescan_api_key ]; then \
export VITE_APP_CFG_SERVICE_ROUTESCAN_API_KEY=$(cat /run/secrets/routescan_api_key); \
else \
echo "Warning: Building without Routescan API key"; \
fi && \
pnpm build:app'
# Runtime stage - using a slim image for a smaller footprint
FROM node:26-slim@sha256:c0753125a3789977aefe869cbebccf70e3cfd7ea84ca48547458f02e4f1d7146 AS runner
# Set NODE_ENV to production for the final runtime image
ENV NODE_ENV=production
WORKDIR /app
# Install 'serve' to run the static application
RUN npm install -g serve
# Copy the built application from the base stage
COPY --from=base /app/apps/role-manager/dist ./dist
# Expose the port the app will run on
EXPOSE 3000
# Start the server to serve the static files from the 'dist' folder
CMD ["serve", "-s", "dist", "-l", "3000"]