feat(docker): finalise le déploiement compose (sqlite + postgres)
- Compose nettoyé en deux profils isolés (sqlite, postgres) avec healthcheck HTTP et network_mode host pour la découverte LAN. - Override docker-compose.bridge.yml pour les environnements où host mode n'est pas disponible (macOS/Windows). - Entrypoint tolérant : fallback prisma db push quand aucune migration n'existe encore. - Dockerfile robuste sans package-lock.json (npm install fallback). - .env.docker.example et docker/README.md pour un démarrage en une commande. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,44 +1,95 @@
|
||||
# syntax=docker/dockerfile:1.6
|
||||
# ---------------------------------------------------------------
|
||||
# IPAM — Dockerfile multi-stage
|
||||
# ---------------------------------------------------------------
|
||||
# Build arg :
|
||||
# DATABASE_PROVIDER = sqlite (défaut) | postgresql
|
||||
# Rappel : le provider Prisma est statique dans schema.prisma, on
|
||||
# le bascule via scripts/switch-db-provider.mjs avant `prisma generate`.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
ARG DATABASE_PROVIDER=sqlite
|
||||
|
||||
# ---------- Stage 1 : deps ----------
|
||||
FROM node:20-alpine AS deps
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm ci
|
||||
# `npm ci` exige un package-lock.json ; sinon on retombe sur `npm install`
|
||||
# qui en générera un. Cela permet un build « out of the box » même sans lock.
|
||||
RUN if [ -f package-lock.json ]; then \
|
||||
npm ci; \
|
||||
else \
|
||||
echo "package-lock.json absent -> npm install" && \
|
||||
npm install --no-audit --no-fund; \
|
||||
fi
|
||||
|
||||
# ---------- Stage 2 : build ----------
|
||||
FROM node:20-alpine AS builder
|
||||
ARG DATABASE_PROVIDER
|
||||
ENV DATABASE_PROVIDER=${DATABASE_PROVIDER}
|
||||
|
||||
# Valeur factice pour que Zod ne rejette pas la config à la génération
|
||||
ENV DATABASE_URL="file:./data/build-placeholder.db"
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
RUN npx prisma generate
|
||||
RUN npm run build
|
||||
|
||||
# Bascule le provider Prisma si nécessaire, puis génère le client et build
|
||||
RUN node scripts/switch-db-provider.mjs "$DATABASE_PROVIDER" \
|
||||
&& npx prisma generate \
|
||||
&& npm run build
|
||||
|
||||
# ---------- Stage 3 : runner ----------
|
||||
FROM node:20-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ARG DATABASE_PROVIDER
|
||||
ENV DATABASE_PROVIDER=${DATABASE_PROVIDER}
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
|
||||
# Outils système utiles à la découverte réseau
|
||||
# - iputils : ping ICMP (privileged / cap_net_raw)
|
||||
# - iproute2 : ip neigh (ARP)
|
||||
# - nmap : fallback scan ports (optionnel, décommente si besoin)
|
||||
RUN apk add --no-cache iputils iproute2
|
||||
WORKDIR /app
|
||||
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
# Outils système utiles à la découverte et à l'entrypoint :
|
||||
# - iputils : ping ICMP (cap_net_raw requis côté compose)
|
||||
# - iproute2 : `ip neigh` pour le scanner ARP
|
||||
# - netcat-openbsd : attente de PostgreSQL (entrypoint)
|
||||
# - openssl, tini, dumb-init : init + signaux propres
|
||||
RUN apk add --no-cache iputils iproute2 netcat-openbsd tini openssl
|
||||
|
||||
COPY --from=builder /app/public ./public
|
||||
# User non-root pour la sécurité
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 nextjs
|
||||
|
||||
# Binaires app (mode standalone Next)
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
# Prisma : schema + client généré + migrations (pour `migrate deploy` au boot)
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.prisma ./node_modules/.prisma
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/prisma ./node_modules/prisma
|
||||
# tsx + dépendances pour pouvoir exécuter prisma/seed.ts si RUN_SEED=true
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/tsx ./node_modules/tsx
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/esbuild ./node_modules/esbuild
|
||||
|
||||
# Entrypoint
|
||||
COPY --chown=nextjs:nodejs docker/entrypoint.sh /app/entrypoint.sh
|
||||
RUN chmod +x /app/entrypoint.sh
|
||||
|
||||
# Volume SQLite (inutile en PG mais inoffensif)
|
||||
RUN mkdir -p /app/data && chown -R nextjs:nodejs /app/data
|
||||
VOLUME ["/app/data"]
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
# Healthcheck simple — retourne 200 dès que Next répond
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
|
||||
|
||||
# tini pour gérer SIGTERM proprement
|
||||
ENTRYPOINT ["/sbin/tini", "--", "/app/entrypoint.sh"]
|
||||
|
||||
Reference in New Issue
Block a user