forked from spliit-app/spliit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
99 lines (83 loc) · 3.56 KB
/
Copy pathDockerfile
File metadata and controls
99 lines (83 loc) · 3.56 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
FROM node:24-alpine AS base
WORKDIR /usr/app
COPY ./package.json \
./package-lock.json \
./next.config.mjs \
./prisma.config.ts \
./tsconfig.json \
./reset.d.ts \
./tailwind.config.js \
./postcss.config.js ./
COPY ./scripts ./scripts
COPY ./prisma ./prisma
# The registry occasionally resets a connection mid-install, which fails the
# whole image build for a reason that has nothing to do with the code. Retry a
# few times before giving up.
RUN apk add --no-cache openssl && \
for i in 1 2 3 4 5; do \
npm ci --ignore-scripts --fetch-retries=5 --fetch-timeout=600000 && exit 0; \
echo "npm ci failed (attempt $i of 5), retrying in 10s..."; \
sleep 10; \
done; \
exit 1
COPY ./src ./src
COPY ./messages ./messages
# Prisma 7 generates the client into ./src/generated/prisma instead of
# node_modules, so this has to run after the source tree is in place.
RUN npx prisma generate
ENV NEXT_TELEMETRY_DISABLED=1
COPY scripts/build.env .env
RUN npm run build
# Next.js copies .env into the standalone output, which would ship the mocked
# build values (a database URL pointing at `db`, placeholder S3 and OpenAI
# credentials) inside the image. Real configuration comes from the container
# environment and would win, but a variable the operator *forgot* to set would
# silently resolve to a build placeholder instead of failing. Drop it.
RUN rm -f .next/standalone/.env
# The standalone output traces its own dependencies, so the runtime stage no
# longer installs a production node_modules. What it does still need is the
# Prisma CLI, to run `migrate deploy` at container start — and the CLI is not
# part of the app's module graph, so nothing traces it.
#
# It gets its own isolated install rather than being copied out of the base
# stage: that stage installs with --ignore-scripts (the repo's postinstall runs
# migrate deploy, which cannot run at build time), so @prisma/engines never
# downloads the schema engine that `migrate deploy` needs. Installing the same
# version here, with scripts, produces a complete self-contained CLI.
FROM node:24-alpine AS prisma-cli
WORKDIR /opt/prisma-cli
ENV CHECKPOINT_DISABLE=1
RUN apk add --no-cache openssl
COPY --from=base /usr/app/node_modules/prisma/package.json ./_prisma.json
RUN PRISMA_VERSION="$(node -p "require('./_prisma.json').version")" && \
rm -f ./_prisma.json && \
npm init -y > /dev/null && \
for i in 1 2 3 4 5; do \
npm install --no-audit --no-fund --fetch-retries=5 \
--fetch-timeout=600000 "prisma@${PRISMA_VERSION}" && exit 0; \
echo "prisma install failed (attempt $i of 5), retrying in 10s..."; \
sleep 10; \
done; \
exit 1
FROM node:24-alpine AS runner
EXPOSE 3000/tcp
WORKDIR /usr/app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# The standalone server binds to localhost by default, which is unreachable
# from outside the container.
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
RUN apk add --no-cache openssl
# The traced server, plus the two things tracing cannot know about: the static
# assets it serves and the public/ directory.
COPY --from=base /usr/app/.next/standalone ./
COPY --from=base /usr/app/.next/static ./.next/static
COPY ./public ./public
# prisma.config.ts carries the connection URLs that used to live in
# schema.prisma; `prisma migrate deploy` reads it at container start.
COPY --from=base /usr/app/prisma ./prisma
COPY --from=base /usr/app/prisma.config.ts ./
COPY --from=prisma-cli /opt/prisma-cli/node_modules ./node_modules
COPY ./scripts ./scripts
ENTRYPOINT ["/bin/sh", "/usr/app/scripts/container-entrypoint.sh"]