-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
124 lines (100 loc) · 4.65 KB
/
Copy pathDockerfile
File metadata and controls
124 lines (100 loc) · 4.65 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
122
123
124
# syntax=docker/dockerfile:1.7
# Multi-stage Dockerfile for the Ever Works minimal website template
# (Astro + pnpm monorepo). Produces a small nginx-based image suitable
# for Kubernetes deployment via the `@ever-works/k8s-plugin`.
#
# Layout:
# - `deps` → install workspace dependencies (with build deps).
# - `builder` → run `pnpm --filter @ever-works/web-minimal run build`
# to produce the static `apps/web/dist` output.
# - `runner` → minimal nginx image serving `apps/web/dist` on :80.
#
# The platform's k8s plugin Service maps port 80 → containerPort 3000;
# we override the nginx port to 3000 to match that contract (no need to
# special-case the Astro template in the plugin).
ARG NODE_VERSION=22-alpine
ARG NGINX_VERSION=1.27-alpine
# ---- deps ------------------------------------------------------------------
FROM node:${NODE_VERSION} AS deps
WORKDIR /work
RUN corepack enable
RUN apk add --no-cache libc6-compat
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json turbo.json ./
COPY apps/web/package.json ./apps/web/package.json
COPY packages ./packages
# Configure the npm/pnpm registry: prefer the internal Verdaccio cache
# (VERDACCIO_REGISTRY build-arg, anonymous), else public npm. Empty (e.g. a
# fork build, or the github-hosted platform deploy workflow that can't reach
# the internal VIP) -> public npm, so this is backward-compatible and fork-safe.
# The pnpm-lock.yaml rewrite is best-effort (non-fatal): a host mismatch
# degrades to public downloads rather than breaking the build.
ARG VERDACCIO_REGISTRY=""
RUN if [ -n "$VERDACCIO_REGISTRY" ]; then \
echo "registry=${VERDACCIO_REGISTRY}" >> /work/.npmrc && \
{ sed -i "s|https://registry.npmjs.org|${VERDACCIO_REGISTRY%/}|g" /work/pnpm-lock.yaml 2>/dev/null || true; }; \
fi
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile --filter "@ever-works/web-minimal..."
# ---- builder ---------------------------------------------------------------
FROM node:${NODE_VERSION} AS builder
WORKDIR /work
RUN corepack enable
RUN apk add --no-cache git
COPY --from=deps /work/node_modules ./node_modules
COPY --from=deps /work/apps/web/node_modules ./apps/web/node_modules
# Workspace packages' node_modules carry the per-package symlinks into the pnpm
# virtual store (e.g. packages/adapters/node_modules/isomorphic-git -> ../../../
# node_modules/.pnpm/...). isomorphic-git is a runtime dep of @ever-works/adapters
# and is `ssr.external` in apps/web/astro.config.ts, so the SSR prerender resolves
# it from packages/adapters/node_modules at build time — NOT root node_modules
# (pnpm does not hoist it there, even with shamefully-hoist). Without this copy
# `astro build` fails: "Cannot find module 'isomorphic-git'". `COPY . .` below
# refreshes the source; node_modules are excluded from the context (.dockerignore)
# so these persist.
COPY --from=deps /work/packages ./packages
COPY . .
ARG DATA_REPOSITORY=""
ENV DATA_REPOSITORY=${DATA_REPOSITORY}
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN --mount=type=secret,id=gh_token \
sh -c 'if [ -s /run/secrets/gh_token ]; then export GH_TOKEN=$(cat /run/secrets/gh_token); fi; \
pnpm --filter @ever-works/web-minimal run build'
# ---- runner ----------------------------------------------------------------
FROM nginx:${NGINX_VERSION} AS runner
ARG GITHUB_REPOSITORY=""
ARG GITHUB_SHA=""
LABEL org.opencontainers.image.source="https://github.com/${GITHUB_REPOSITORY}"
LABEL org.opencontainers.image.revision="${GITHUB_SHA}"
LABEL org.opencontainers.image.title="${GITHUB_REPOSITORY}"
# Listen on 3000 so the Service's targetPort: 3000 from the k8s plugin
# matches the Astro static template without special-casing.
RUN sed -i 's|listen\s\+80;|listen 3000;|' /etc/nginx/conf.d/default.conf
# Serve the Astro static output. Default `try_files` falls through to
# /index.html so the SPA-style routes (404.html etc.) work as expected.
RUN cat > /etc/nginx/conf.d/default.conf <<'EOF'
server {
listen 3000;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Long-cache hashed static assets.
location /_astro/ {
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
location / {
try_files $uri $uri.html $uri/index.html /index.html =404;
}
# Health endpoint for the readiness/liveness probes (the k8s plugin
# probes GET /).
location = /healthz {
access_log off;
return 200 "ok\n";
add_header Content-Type text/plain;
}
}
EOF
COPY --from=builder /work/apps/web/dist /usr/share/nginx/html
EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]