Files
nobat724_front/Dockerfile
T
hamedandClaude Fable 5 ab1102ec1c chore(docker): update Dockerfile for Next 16, drop duplicate lowercase dockerfile
- update stage comments to Next 16; note Turbopack default build
- npm ci --no-audit --no-fund for faster reproducible install
- add HEALTHCHECK (referenced by docker-compose, previously missing)
- parametrize node version via ARG NODE_VERSION
- remove duplicate case-variant 'dockerfile' (collided with 'Dockerfile'
  on case-insensitive FS, would be two files on Linux/Coolify)

Verified: docker build + run, all routes 200, multi-domain Host routing,
canonical in <head>, container healthcheck reports healthy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:37:54 +03:30

92 lines
3.6 KiB
Docker

# syntax=docker/dockerfile:1
# Multi-stage Dockerfile for Next.js 16 (App Router, output: 'standalone').
# Based on the official Next.js Docker example, tuned for Coolify.
# References:
# https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile
# https://coolify.io/docs/applications/nextjs
# ----------------------------------------------------------------------------
# Base image
# ----------------------------------------------------------------------------
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine AS base
# libc6-compat is recommended by the Next.js image for some native deps (sharp, etc.)
RUN apk add --no-cache libc6-compat
WORKDIR /app
# ----------------------------------------------------------------------------
# 1. Dependencies — installed in a dedicated layer so they are cached as long
# as package.json / lockfile / .npmrc do not change.
# ----------------------------------------------------------------------------
FROM base AS deps
COPY package.json package-lock.json .npmrc ./
# Reproducible install honouring the lockfile (.npmrc provides legacy-peer-deps,
# required because react-google-map-picker declares a React 17 peer).
RUN npm ci --no-audit --no-fund
# ----------------------------------------------------------------------------
# 2. Builder — produces the standalone output.
# NEXT_PUBLIC_* values are inlined into the client bundle at BUILD time,
# so they must be passed as build args. DEV_MODE is read in app/layout.js
# to toggle Google Analytics + robots noindex, so it must also be present
# at build time.
# ----------------------------------------------------------------------------
FROM base AS builder
WORKDIR /app
# Build-time arguments (Coolify: set these as Build Variables)
ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_CLIENT_ID
ARG NEXT_PUBLIC_CLIENT_SECRET
ARG DEV_MODE=FALSE
# Expose them to `next build`
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_CLIENT_ID=$NEXT_PUBLIC_CLIENT_ID
ENV NEXT_PUBLIC_CLIENT_SECRET=$NEXT_PUBLIC_CLIENT_SECRET
ENV DEV_MODE=$DEV_MODE
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Next 16 builds with Turbopack by default; output: 'standalone' emits
# .next/standalone/server.js plus a trimmed node_modules.
RUN npm run build
# ----------------------------------------------------------------------------
# 3. Runner — minimal production image running the standalone server.
# ----------------------------------------------------------------------------
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# The standalone server must bind to all interfaces inside the container.
ENV HOSTNAME=0.0.0.0
ENV PORT=3000
# Run as a non-root user for security.
RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 nextjs
# Public assets (served by the standalone server).
COPY --from=builder /app/public ./public
# Standalone output already contains a minimal node_modules + server.js.
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
# Static assets are NOT included in standalone and must be copied separately.
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
# Container-level health probe (also referenced by docker-compose / Coolify).
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://127.0.0.1:3000/',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))"
# server.js is generated by Next.js at the root of the standalone output.
CMD ["node", "server.js"]