forked from forbole/big-dipper-2.0-cosmos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDockerfile
163 lines (139 loc) · 5.28 KB
/
Dockerfile
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
ARG BASE_IMAGE=node:18
ARG PROJECT_NAME=web
# This is a multiple stage Dockerfile.
# - Stage 1: starter (base image with Node.js 18 and the turbo package installed globally)
# - Stage 2: pruner (copies all necessary files and sets up yarn configurations, runs turbo prune)
# - Stage 3: builder (adds dependencies, environment variables, and builds the project using yarn)
# - Stage 4: runner (final image for the web project, sets environment variables, starts the server)
# Stage: starter
FROM ${BASE_IMAGE} AS starter
WORKDIR /app
RUN npm i -g turbo
# Stage: pruner
FROM starter AS pruner
COPY ./ ./
ARG PROJECT_NAME
RUN yarn config set nodeLinker node-modules \
&& yarn config set supportedArchitectures --json '{}' \
&& turbo prune --scope=${PROJECT_NAME} --docker
################################################################################
# Stage: builder
FROM starter AS builder
### First install the dependencies (as they change less often)
COPY .yarnrc.yml ./
COPY .yarn/ ./.yarn/
COPY --from=pruner /app/out/json/ /app/out/yarn.lock ./
## Setting up the environment variables for the docker container.
ARG PROJECT_NAME
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ARG NEXT_PUBLIC_SENTRY_DSN
ENV NEXT_PUBLIC_SENTRY_DSN=${NEXT_PUBLIC_SENTRY_DSN}
ARG SENTRY_AUTH_TOKEN
ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}
ENV SENTRY_URL=https://sentry.io/
ENV SENTRY_ORG=forbole
ENV SENTRY_PROJECT=big-dipper
ENV SENTRY_ENVIRONMENT=production
ARG BASE_PATH
ENV BASE_PATH=${BASE_PATH}
ENV CI=1
ENV HUSKY=0
ARG TURBO_TEAM
ENV TURBO_TEAM=${TURBO_TEAM}
ARG TURBO_TOKEN
ENV TURBO_TOKEN=${TURBO_TOKEN}
ENV BUILD_STANDALONE=1
# add placeholder for env variables to be injected in runner stage
ENV NEXT_PUBLIC_CHAIN_TYPE={{NEXT_PUBLIC_CHAIN_TYPE}}
ENV NEXT_PUBLIC_BANNERS_JSON={{NEXT_PUBLIC_BANNERS_JSON}}
ENV NEXT_PUBLIC_GRAPHQL_URL={{NEXT_PUBLIC_GRAPHQL_URL}}
ENV NEXT_PUBLIC_GRAPHQL_WS={{NEXT_PUBLIC_GRAPHQL_WS}}
ENV NEXT_PUBLIC_MATOMO_URL={{NEXT_PUBLIC_MATOMO_URL}}
ENV NEXT_PUBLIC_MATOMO_SITE_ID={{NEXT_PUBLIC_MATOMO_SITE_ID}}
ENV NEXT_PUBLIC_RPC_WEBSOCKET={{NEXT_PUBLIC_RPC_WEBSOCKET}}
RUN export SENTRYCLI_SKIP_DOWNLOAD=$([ -z "${NEXT_PUBLIC_SENTRY_DSN}" ] && echo 1) \
&& corepack enable && yarn -v \
&& yarn config set supportedArchitectures --json '{}' \
&& YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install --inline-builds
## Build the project
COPY --from=pruner /app/out/full/ ./
RUN ([ -z "${NEXT_PUBLIC_SENTRY_DSN}" ] || yarn node packages/shared-utils/configs/sentry/install.js) \
&& yarn workspace ${PROJECT_NAME} add sharp \
&& yarn workspace ${PROJECT_NAME} run build
################################################################################
# Stage: runner
FROM ${BASE_IMAGE} AS runner
# Copying the files from the builder stage to the runner stage.
ARG PROJECT_NAME
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ARG NEXT_PUBLIC_CHAIN_TYPE
ENV NEXT_PUBLIC_CHAIN_TYPE=${NEXT_PUBLIC_CHAIN_TYPE}
ARG NEXT_PUBLIC_BANNERS_JSON
ENV NEXT_PUBLIC_BANNERS_JSON=${NEXT_PUBLIC_BANNERS_JSON}
ARG NEXT_PUBLIC_GRAPHQL_URL
ENV NEXT_PUBLIC_GRAPHQL_URL=${NEXT_PUBLIC_GRAPHQL_URL}
ARG NEXT_PUBLIC_GRAPHQL_WS
ENV NEXT_PUBLIC_GRAPHQL_WS=${NEXT_PUBLIC_GRAPHQL_WS}
ARG NEXT_PUBLIC_MATOMO_URL
ENV NEXT_PUBLIC_MATOMO_URL=${NEXT_PUBLIC_MATOMO_URL}
ARG NEXT_PUBLIC_MATOMO_SITE_ID
ENV NEXT_PUBLIC_MATOMO_SITE_ID=${NEXT_PUBLIC_MATOMO_SITE_ID}
ARG NEXT_PUBLIC_RPC_WEBSOCKET
ENV NEXT_PUBLIC_RPC_WEBSOCKET=${NEXT_PUBLIC_RPC_WEBSOCKET}
ARG PORT
ENV PORT=${PORT:-3000}
WORKDIR /app/apps/${PROJECT_NAME}
RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 nextjs \
&& chown -R nextjs:nodejs /home/nextjs /app
COPY --chown=nextjs:nodejs --from=builder \
/app/package.json /app/.pnp.* /app/.yarnrc.yml /app/yarn.lock \
../../
COPY --chown=nextjs:nodejs --from=builder \
/app/.yarn/ \
../../.yarn/
COPY --chown=nextjs:nodejs --from=builder \
/app/apps/${PROJECT_NAME}/.next/apps/${PROJECT_NAME}/server.js /app/apps/${PROJECT_NAME}/package.json \
./
COPY --chown=nextjs:nodejs --from=builder \
/app/apps/${PROJECT_NAME}/public/ \
./public/
COPY --chown=nextjs:nodejs --from=builder \
/app/apps/${PROJECT_NAME}/.next/apps/${PROJECT_NAME}/.next/ \
./.next/
COPY --chown=nextjs:nodejs --from=builder \
/app/apps/${PROJECT_NAME}/.next/static/ \
./.next/static/
# reference: https://github.com/vercel/next.js/discussions/34894
RUN printf 'const { readFileSync, writeFileSync } = require("fs");\n\
function inject(file) {\n\
const code = readFileSync(file, "utf8").replace(/(['\
"'"\
'"`])[{][{](\
NEXT_PUBLIC_CHAIN_TYPE|\
NEXT_PUBLIC_BANNERS_JSON|\
NEXT_PUBLIC_GRAPHQL_URL|\
NEXT_PUBLIC_GRAPHQL_WS|\
NEXT_PUBLIC_MATOMO_URL|\
NEXT_PUBLIC_MATOMO_SITE_ID|\
NEXT_PUBLIC_RPC_WEBSOCKET\
)[}][}]\\1/gi, (match, quote, name) => {\n\
console.log(`inject ${match} with ${JSON.stringify(process.env[name.toUpperCase()])} in ${file}`);\n\
return JSON.stringify(process.env[name] ?? "")\n\
});\n\
writeFileSync(file, code, "utf8");\n\
}\n' > ./inject.js \
&& egrep -ilr '[{][{](\
NEXT_PUBLIC_CHAIN_TYPE|\
NEXT_PUBLIC_BANNERS_JSON|\
NEXT_PUBLIC_GRAPHQL_URL|\
NEXT_PUBLIC_GRAPHQL_WS|\
NEXT_PUBLIC_MATOMO_URL|\
NEXT_PUBLIC_MATOMO_SITE_ID|\
NEXT_PUBLIC_RPC_WEBSOCKET\
)[}][}]' ./.next | xargs -I{} printf 'inject("'{}'");\n' | tee -a ./inject.js;
# Don't run production as root
USER nextjs
CMD node ./inject.js && yarn node ./server.js