From 99c3380d00f35d827f4f5832af7f2c554a29caac Mon Sep 17 00:00:00 2001 From: Mathieu Date: Sun, 7 Jun 2026 00:27:16 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20dockerfile=20+=20docker-compose=20+=20d?= =?UTF-8?q?=C3=A9ploiement=20VPS=20gestion.materiaux-destock.fr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 18 +++++++++++++++++ .gitignore | 1 + Dockerfile | 48 ++++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 15 +++++++++++++++ next.config.mjs | 4 +++- prisma/seed.mjs | 23 ++++++++++++++++++++++ scripts/start.sh | 6 ++++++ 7 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 prisma/seed.mjs create mode 100755 scripts/start.sh diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..38032c7 --- /dev/null +++ b/.env.example @@ -0,0 +1,18 @@ +# Auth +NEXTAUTH_URL=https://gestion.materiaux-destock.fr +NEXTAUTH_SECRET= + +# Shopify (remplir lors du Plan 2) +SHOPIFY_STORE_DOMAIN=materiaux-destock.myshopify.com +SHOPIFY_ADMIN_API_TOKEN=shpat_... + +# Google Sheets (remplir lors du Plan 3) +GOOGLE_SERVICE_ACCOUNT_EMAIL=...@....iam.gserviceaccount.com +GOOGLE_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n..." +GOOGLE_SHEETS_ID= + +# Base de données +DATABASE_URL="file:./data/app.db" + +# Seed (premier déploiement uniquement) +SEED_ADMIN_PASSWORD= diff --git a/.gitignore b/.gitignore index 2fbc9e5..63cbc82 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ yarn-error.log* next-env.d.ts /src/generated/prisma +.env.production diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3e2a881 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +# Étape 1 : dépendances +FROM node:20-alpine AS deps +WORKDIR /app +RUN apk add --no-cache python3 make g++ +COPY package*.json ./ +RUN npm ci + +# Étape 2 : build +FROM node:20-alpine AS builder +WORKDIR /app +RUN apk add --no-cache python3 make g++ +COPY --from=deps /app/node_modules ./node_modules +COPY . . +ENV DATABASE_URL="file:./data/app.db" +RUN npx prisma generate +RUN npm run build + +# Étape 3 : image de production +FROM node:20-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production + +RUN apk add --no-cache python3 make g++ + +RUN addgroup --system --gid 1001 nodejs \ + && adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static +COPY --from=builder /app/prisma ./prisma +COPY --from=builder /app/prisma.config.ts ./prisma.config.ts +COPY --from=builder /app/node_modules/.bin/prisma ./node_modules/.bin/prisma +COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma +COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma +COPY --from=builder /app/node_modules/better-sqlite3 ./node_modules/better-sqlite3 +COPY --from=builder /app/node_modules/@prisma/adapter-better-sqlite3 ./node_modules/@prisma/adapter-better-sqlite3 +COPY --from=builder /app/node_modules/dotenv ./node_modules/dotenv +COPY scripts/start.sh ./start.sh + +RUN mkdir -p data && chown -R nextjs:nodejs data . + +USER nextjs +EXPOSE 3000 +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["sh", "start.sh"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3c18cf2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + app: + build: . + image: gestion-materiaux-destock:latest + restart: unless-stopped + env_file: + - .env + volumes: + - ./data:/app/data + networks: + - web + +networks: + web: + external: true diff --git a/next.config.mjs b/next.config.mjs index 4678774..e25a6a2 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,6 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + output: 'standalone', +}; export default nextConfig; diff --git a/prisma/seed.mjs b/prisma/seed.mjs new file mode 100644 index 0000000..b198de6 --- /dev/null +++ b/prisma/seed.mjs @@ -0,0 +1,23 @@ +import { PrismaClient } from '@prisma/client' +import { hash } from 'bcryptjs' + +const prisma = new PrismaClient() + +const password = process.env.SEED_ADMIN_PASSWORD +if (!password) { + console.error('SEED_ADMIN_PASSWORD requis') + process.exit(1) +} + +await prisma.user.upsert({ + where: { email: 'mathieu.fort@gmail.com' }, + update: {}, + create: { + email: 'mathieu.fort@gmail.com', + name: 'Mathieu', + password: await hash(password, 12), + role: 'admin', + }, +}) +console.log('✅ Compte admin créé : mathieu.fort@gmail.com') +await prisma.$disconnect() diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100755 index 0000000..9f4740e --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +echo "▶ Migration base de données…" +node_modules/.bin/prisma migrate deploy +echo "▶ Démarrage du serveur…" +exec node server.js