พอร์ต taskpane ของ Word add-in "e-Court Documents Versioning" จาก D:\word-addin-poc มาเป็น sibling app ที่ route /docedit/wordaddin: - wordaddin/ (client-only zone): services พอร์ตดิบทั้งชุด (authService/versioningService เป็น mock รอ backend จริง) + models + config - components/wordaddin/: WordAddinGate ฉีด office.js self-host (singleton กัน StrictMode double-inject + fallback timer ครอบเคส onReady เงียบ) และ TaskpaneApp state machine แปลง JSX เป็น Genesis design system - scripts/fetch-office-js.mjs (postinstall ตัวที่สาม): ดาวน์โหลด Office.js runtime ล่าสุดจาก CDN Microsoft ไป public/wordaddin/office-js/ (gitignore สร้างใหม่ได้ — npm @microsoft/office-js ตกรุ่นไม่มี Document.close) - middleware/basePath/root page: เปิด /wordaddin เป็น public (auth แยกจาก แอป note), root /docedit redirect ไป taskpane ยกเว้นลิงก์ e-Court N8 (?fileUrl=&fileId=&typeId=) ที่ยังส่งต่อ /note ตามเดิม - docker/web.Dockerfile รัน fetch-office-js ตอน build + npm scripts dev:https สำหรับ sideload ตาม docs/WORDADDIN-DEV.md Co-Authored-By: Claude Code <noreply@anthropic.com>
55 lines
4.6 KiB
Docker
55 lines
4.6 KiB
Docker
# ─── Stage 1: ติดตั้ง dependencies (npm ci รวม postinstall คัดลอก pdf.worker) ───
|
|
FROM node:24-alpine AS deps
|
|
WORKDIR /app
|
|
COPY package.json package-lock.json ./
|
|
# postinstall รัน scripts/patch-pdf-worker.mjs + copy-swagger-ui.mjs + fetch-office-js.mjs ตอน npm ci — คัดลอกเข้ามาก่อน ไม่งั้นหาไฟล์ไม่เจอ
|
|
# (fetch-office-js ดาวน์โหลด Office.js runtime จาก appsforoffice.microsoft.com — build stage ต้องออกอินเทอร์เน็ตถึง CDN นี้ได้)
|
|
COPY scripts/patch-pdf-worker.mjs scripts/copy-swagger-ui.mjs scripts/fetch-office-js.mjs scripts/
|
|
# postinstall เขียน public/note/pdf.worker.min.mjs (script สร้าง dir ปลายทางเอง)
|
|
RUN npm ci
|
|
|
|
# ─── Stage 2: build Next.js (output: standalone) ───
|
|
FROM node:24-alpine AS builder
|
|
WORKDIR /app
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY . .
|
|
# ประกันว่า pdf.worker.min.mjs ตรงกับเวอร์ชัน pdfjs-dist ใน node_modules เสมอ
|
|
# (postinstall รันใน stage deps ซึ่งยังไม่มี public/ ของ repo) — ต้องใช้ตัว patch ด้วย
|
|
# ไม่ใช่ copyFileSync เปล่า ๆ ไม่งั้น worker ที่ patch fake-space ไทยถูกเขียนทับด้วยตัวดิบ
|
|
# + คัดลอก asset Swagger UI (public/note/swagger-ui/) ให้ตรงเวอร์ชันเช่นกัน
|
|
# + ดาวน์โหลด Office.js runtime ล่าสุด (public/wordaddin/office-js/) ของ taskpane wordaddin
|
|
RUN node scripts/patch-pdf-worker.mjs && node scripts/copy-swagger-ui.mjs && node scripts/fetch-office-js.mjs
|
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
# db/index.ts throw ถ้าไม่มี DATABASE_URL ตอน next build เก็บ page data —
|
|
# ใส่ค่า dummy (postgres.js เชื่อมแบบ lazy ไม่มี query ตอน build) ตัวจริงฉีดตอน docker run
|
|
ENV DATABASE_URL=postgresql://placeholder:placeholder@127.0.0.1:5432/placeholder
|
|
RUN npm run build
|
|
|
|
# ─── Stage 3: runtime ตัวเบา (แค่ standalone + public/) ───
|
|
FROM node:24-alpine AS runner
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production \
|
|
NEXT_TELEMETRY_DISABLED=1 \
|
|
PORT=3000 \
|
|
HOSTNAME=0.0.0.0
|
|
RUN addgroup -S nodejs && adduser -S nextjs -G nodejs
|
|
# Next 14.2 รวม public/ (pdf.worker, ฟอนต์ Sarabun, samples PDF) ไว้ใน standalone แล้ว
|
|
# แต่ไม่รวม .next/static (JS chunks) — ต้องคัดลอกเพิ่ม ไม่งั้นหน้าเว็บไม่มี JS
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
# migration: ไฟล์ SQL (drizzle-kit generate) + runner — รันตอน container start
|
|
COPY --from=builder --chown=nextjs:nodejs /app/drizzle ./drizzle
|
|
COPY --from=builder --chown=nextjs:nodejs /app/scripts ./scripts
|
|
# postgres.js โดน Next บีบ bundle เข้า server chunks — standalone node_modules ไม่มี package นี้
|
|
# แต่ migrate.mjs import มันตรง ๆ → คัดลอกจาก stage deps (v3 ไม่มี dependency ย่อย โฟลเดอร์เดียวพอ)
|
|
COPY --from=deps --chown=nextjs:nodejs /app/node_modules/postgres ./node_modules/postgres
|
|
# สร้างโฟลเดอร์ uploads ให้ user nextjs เป็นเจ้าของ — named volume ที่ compose mount ทับ
|
|
# (เก็บไฟล์อัปโหลดข้าม redeploy) จะได้ ownership จาก image ตอน init:
|
|
# ไม่มี dir นี้ใน image = volume ถูกสร้างโดย root แล้ว action เขียนไฟล์ไม่ได้ (EACCES)
|
|
RUN mkdir -p public/note/uploads && chown nextjs:nodejs public/note/uploads
|
|
USER nextjs
|
|
EXPOSE 3000
|
|
# DATABASE_URL ฉีดตอนรันผ่าน env ของ container (อย่าฝังใน image)
|
|
# migrate สร้าง database ถ้ายังไม่มี + apply ไฟล์ที่ยังไม่ได้ apply (idempotent)
|
|
# seed-samples sync ตาราง files กับ public/note/samples/ ที่ bake อยู่ใน image (idempotent)
|
|
CMD ["sh", "-c", "node scripts/migrate.mjs && node scripts/seed-samples.mjs && exec node server.js"]
|