# syntax=docker/dockerfile:1.6 ############ Base ############ FROM node:20-alpine AS base WORKDIR /app RUN apk add --no-cache bash curl tzdata \ && ln -snf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime \ && echo "Asia/Bangkok" > /etc/timezone ARG NEXT_PUBLIC_API_BASE ENV TZ=Asia/Bangkok \ NEXT_TELEMETRY_DISABLED=1 \ CHOKIDAR_USEPOLLING=true \ WATCHPACK_POLLING=true \ NEXT_PUBLIC_API_BASE=${NEXT_PUBLIC_API_BASE} \ npm_config_yes=true # (ค่าพวกนี้ซ้ำกับ compose ได้ ไม่เป็นปัญหา) ############ Deps (install) ############ FROM base AS deps ## COPY package.json package-lock.json* ./ # ถ้ามี lock ใช้ npm ci; ถ้าไม่มีก็ npm i ## RUN if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi COPY package.json ./ # ไม่ copy lock เพื่อบังคับให้ใช้ npm install RUN npm install --no-audit --no-fund # เพิ่ม shadcn/ui + tailwind deps # RUN npm install -D tailwindcss postcss autoprefixer shadcn@latest \ # && npm install class-variance-authority clsx framer-motion lucide-react tailwind-merge tailwindcss-animate # init tailwind config (กัน No Tailwind CSS configuration found) # RUN npx tailwindcss init -p # bake components ของ shadcn แบบ non-interactive # RUN npx shadcn add -y button badge card input tabs progress dropdown-menu tooltip switch ############ Dev (hot-reload) ############ # ใช้ร่วมกับ compose: bind ทั้งโปรเจ็กต์ → /app # และใช้ named volume แยกสำหรับ /app/node_modules และ /app/.next FROM base AS dev RUN apk add --no-cache git openssh-client ca-certificates # สำคัญ: สร้างโฟลเดอร์ที่ Next ใช้งาน (เวลายังไม่ bind อะไรเข้ามา) RUN install -d -o node -g node /app/public /app/app /app/.logs /app/.next /app/.next/cache # นำ node_modules จากชั้น deps มาไว้ (ลดเวลาตอน start ครั้งแรก) COPY --from=deps /app/node_modules /app/node_modules # ไม่กำหนด USER ที่นี่ ปล่อยให้ compose คุม (ตอนนี้คุณใช้ user: "1000:1000") ENV NODE_ENV=development EXPOSE 3000 CMD ["npm", "run", "dev"] ############ Build (production) ############ FROM deps AS builder COPY . . RUN npm run build ############ Prod runtime (optimized) ############ FROM node:20-alpine AS prod WORKDIR /app ENV NODE_ENV=production RUN apk add --no-cache libc6-compat # RUN apk add --no-cache libc6-compat \ # && addgroup -g 1000 node && adduser -D -u 1000 -G node node # คัดเฉพาะของจำเป็น COPY --from=builder /app/package.json /app/package-lock.json* ./ # ติดตั้งเฉพาะ prod deps RUN if [ -f package-lock.json ]; then npm ci --omit=dev --no-audit --no-fund; else npm i --omit=dev --no-audit --no-fund; fi COPY --from=builder --chown=node:node /app/.next ./.next COPY --from=builder --chown=node:node /app/public ./public USER node EXPOSE 3000 CMD ["npm", "start"] # docker compose -f docker-frontend-build.yml build --no-cache