-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
71 lines (59 loc) · 3.26 KB
/
Copy pathDockerfile
File metadata and controls
71 lines (59 loc) · 3.26 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
# Arkyc API image — mirrors the production build in .github/workflows/deploy.yml:
# build the whole workspace once, then ship a slim, standalone, prod-only artifact
# with a flat node_modules that runs the compiled server (and, from the same image,
# `ark migrate` / `ark queue:work`).
# ---- Builder: full monorepo + dev deps -------------------------------------
FROM node:22-bookworm-slim AS builder
# `prepare` / `ark build` silence tsdown by default; surface real errors on failure.
ENV VERBOSITY=1
# corepack resolves the pnpm version pinned in package.json#packageManager.
RUN corepack enable
WORKDIR /repo
# The whole workspace (source only — see .dockerignore).
COPY . .
# The same ordered build the deploy uses:
# 1. install WITHOUT lifecycle scripts — the API's `postinstall` (which builds
# the app via tsdown) must NOT run mid-install, before the workspace libs
# exist. Native deps ship prebuilt (sharp) and pnpm gates dep build scripts,
# so skipping scripts is safe here.
# 2. build the workspace libs (tsdown),
# 3. run the API `prepare` (regenerate .arkstack + compile) then `ark build`
# (emit dist/server.js).
RUN pnpm install --frozen-lockfile --ignore-scripts \
&& pnpm run build:libs \
&& pnpm --filter @arkyc/api run postinstall \
&& pnpm --filter @arkyc/api build
# Assemble a standalone, prod-only artifact (flat node_modules, independent of the
# workspace) into /app — exactly how the server runs in production.
# --legacy: pnpm v10's default deploy needs inject-workspace-packages; legacy
# mode resolves the @arkyc/* workspace deps without that global flag.
# `--prod` requires @h3ravel/musket >= 2.2.8: before that the `ark` CLI statically
# imported `tsdown` (a devDependency), so a prod-only artifact could not run `ark`
# at all. It is a dynamic, optional import now, so `ark migrate` (startup) and
# `ark queue:work` (workers) run fine without the dev deps.
# `dist` and `.arkstack` are gitignored, so `pnpm deploy` skips them — copy both
# in (.arkormx is DB-derived and regenerated by `ark migrate` at startup).
RUN pnpm --filter=@arkyc/api deploy --prod --legacy /app \
&& rm -rf /app/dist /app/.arkstack \
&& cp -r apps/api/dist /app/dist \
&& cp -r apps/api/.arkstack /app/.arkstack
# ---- Runtime: slim image running the compiled server -----------------------
FROM node:22-bookworm-slim AS runtime
ENV NODE_ENV=production
# `ark` (migrate / queue:work) resolves from the artifact's flat node_modules.
ENV PATH=/app/node_modules/.bin:$PATH
WORKDIR /app
# tini reaps zombies and forwards signals for a clean shutdown (no PM2 here).
RUN apt-get update \
&& apt-get install -y --no-install-recommends tini \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /app /app
COPY docker/api-entrypoint.sh /usr/local/bin/api-entrypoint
RUN chmod +x /usr/local/bin/api-entrypoint
EXPOSE 3100
# Node 22 ships a global fetch, so the healthcheck needs no curl in the image.
HEALTHCHECK --interval=15s --timeout=5s --start-period=45s --retries=5 \
CMD node -e "fetch('http://127.0.0.1:'+(process.env.APP_PORT||3100)+'/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
ENTRYPOINT ["/usr/bin/tini", "--", "api-entrypoint"]
# Overridden by the worker service (see docker-compose.yml) to `ark queue:work`.
CMD ["node", "dist/server.js"]