-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
146 lines (119 loc) · 5.94 KB
/
Dockerfile
File metadata and controls
146 lines (119 loc) · 5.94 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Multi-stage Dockerfile for haotool.org Portfolio
# Includes: haotool (root), ratewise (/ratewise/), nihonname (/nihonname/), quake-school (/quake-school/), park-keeper (/park-keeper/), split-meow (/split-meow/)
# syntax=docker/dockerfile:1
# Build stage
FROM node:24-alpine AS builder
# [fix:2025-12-13] Build arguments for version generation
# 這些參數在建置時從 Git 取得,傳遞到容器內
ARG GIT_COMMIT_COUNT
ARG GIT_COMMIT_HASH
ARG BUILD_TIME
ARG VITE_HAOTOOL_BASE_PATH=/
ARG VITE_RATEWISE_BASE_PATH=/ratewise/
ARG VITE_NIHONNAME_BASE_PATH=/nihonname/
ARG VITE_QUAKE_SCHOOL_BASE_PATH=/quake-school/
ARG VITE_PARK_KEEPER_BASE_PATH=/park-keeper/
ARG VITE_SPLIT_MEOW_BASE_PATH=/split-meow/
# Enable corepack for pnpm
RUN corepack enable && corepack prepare pnpm@9.10.0 --activate
# 安裝 git 供版本計算使用(node:alpine 預設未內建)
RUN apk add --no-cache git
WORKDIR /app
# Set pnpm store directory for cache mount
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
# [fix:2025-11-05] 設定環境變數供 vite.config.ts 使用
ENV GIT_COMMIT_COUNT=${GIT_COMMIT_COUNT}
ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH}
ENV BUILD_TIME=${BUILD_TIME}
ENV CI=true
# Copy package files and pnpm config
COPY .npmrc package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY apps/ratewise/package.json ./apps/ratewise/
COPY apps/nihonname/package.json ./apps/nihonname/
COPY apps/haotool/package.json ./apps/haotool/
COPY apps/quake-school/package.json ./apps/quake-school/
COPY apps/park-keeper/package.json ./apps/park-keeper/
COPY apps/split-meow/package.json ./apps/split-meow/
COPY apps/shared/package.json ./apps/shared/
# [fix:2025-11-06] 安裝依賴時禁用 Husky 並清空 NODE_ENV
# Zeabur 可能自動設置 NODE_ENV=production,導致 devDependencies 被跳過
# Builder 階段需要 devDependencies(TypeScript, Vite 等構建工具)
# 參考: https://typicode.github.io/husky/#/?id=disable-husky-in-cidockerprod
# Reference: https://pnpm.io/docker
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
NODE_ENV= HUSKY=0 pnpm install --frozen-lockfile
# Copy source code
COPY . .
# Build applications(若外部未提供 build args,於此自動回退計算)
# [fix:2025-12-13] 分別為每個專案設置對應的 base 變數,避免相互污染
# [2025 Best Practice] Sitemaps 現在由 vite-ssg-sitemap 在 build 時自動生成
# 新增 haotool 作為根路徑首頁
RUN set -eux; \
if [ -z "${GIT_COMMIT_COUNT:-}" ]; then \
export GIT_COMMIT_COUNT="$(git rev-list --count HEAD)"; \
fi; \
if [ -z "${GIT_COMMIT_HASH:-}" ]; then \
export GIT_COMMIT_HASH="$(git rev-parse --short HEAD)"; \
fi; \
if [ -z "${BUILD_TIME:-}" ]; then \
export BUILD_TIME="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"; \
fi; \
VITE_HAOTOOL_BASE_PATH=/ pnpm build:haotool && \
VITE_RATEWISE_BASE_PATH=/ratewise/ pnpm build:ratewise && \
VITE_NIHONNAME_BASE_PATH=/nihonname/ pnpm build:nihonname && \
VITE_QUAKE_SCHOOL_BASE_PATH=/quake-school/ pnpm build:quake-school && \
VITE_PARK_KEEPER_BASE_PATH=/park-keeper/ pnpm build:park-keeper && \
VITE_SPLIT_MEOW_BASE_PATH=/split-meow/ pnpm build:split-meow
# [fix:2025-12-30] 驗證 sitemaps 已生成並包含在構建中
# Sitemaps 應該在 dist/ 目錄(構建輸出)而非 public/
RUN test -f /app/apps/ratewise/dist/sitemap.xml && \
test -f /app/apps/nihonname/dist/sitemap.xml && \
test -f /app/apps/haotool/dist/sitemap.xml && \
test -f /app/apps/quake-school/dist/sitemap.xml && \
test -f /app/apps/park-keeper/dist/sitemap.xml || \
{ echo "ERROR: Sitemaps not generated in Docker build"; exit 1; }
# Production stage
# [fix:2026-03-07] 改用官方 nginx:stable(Debian trixie)以避開 Alpine zlib 供應鏈告警,
# 並只安裝 healthcheck 所需的 wget,避免額外擴大攻擊面。
FROM nginx:stable
# [fix:2026-04-10] 安裝安全更新以修復 CVE-2026-4775 (libtiff) 等漏洞
# 參考: https://security-tracker.debian.org/tracker/CVE-2026-4775
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends wget && \
rm -rf /var/lib/apt/lists/*
# [fix:2025-12-13] 新架構:haotool 作為根路徑首頁
# 複製 haotool 作為根目錄(首頁)
COPY --from=builder /app/apps/haotool/dist /usr/share/nginx/html
# Copy built assets for ratewise 到子目錄
COPY --from=builder /app/apps/ratewise/dist /usr/share/nginx/html/ratewise-app
# Copy built assets for nihonname 到子目錄
COPY --from=builder /app/apps/nihonname/dist /usr/share/nginx/html/nihonname-app
# [fix:2025-12-29] Copy built assets for quake-school 到子目錄
COPY --from=builder /app/apps/quake-school/dist /usr/share/nginx/html/quake-school-app
# Copy park-keeper static assets
COPY --from=builder /app/apps/park-keeper/dist /usr/share/nginx/html/park-keeper-app
# Copy split-meow static assets
COPY --from=builder /app/apps/split-meow/dist /usr/share/nginx/html/split-meow-app
# 創建符號連結以支援路由
RUN ln -s /usr/share/nginx/html/ratewise-app /usr/share/nginx/html/ratewise && \
ln -s /usr/share/nginx/html/nihonname-app /usr/share/nginx/html/nihonname && \
ln -s /usr/share/nginx/html/quake-school-app /usr/share/nginx/html/quake-school && \
ln -s /usr/share/nginx/html/park-keeper-app /usr/share/nginx/html/park-keeper && \
ln -s /usr/share/nginx/html/split-meow-app /usr/share/nginx/html/split-meow
# Copy nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf
# Create non-root user for security
RUN groupadd --system --gid 1001 nodejs && useradd --system --uid 1001 --gid 1001 nodejs
RUN chown -R nodejs:nodejs /usr/share/nginx/html /var/cache/nginx /var/run /var/log/nginx
# Expose port
EXPOSE 8080
# Health check - 測試 nginx 是否正常回應 HTTP 請求
# 檔案存在不代表 nginx 運作正常,必須測試實際 HTTP 回應
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1
# Use non-root user
USER nodejs
# Start nginx
CMD ["nginx", "-g", "daemon off;"]