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,15 +1,74 @@
|
||||
# ---------------------------------------------------------------
|
||||
# Docker build context — exclusions
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
# Dependencies (réinstallés dans l'image)
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# Build artifacts
|
||||
.next
|
||||
.git
|
||||
out
|
||||
dist
|
||||
build
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# Env (les secrets ne doivent jamais être copiés dans l'image)
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
npm-debug.log
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
.env.production
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Docker (évite la récursion). On NE PEUT PAS exclure docker/ car
|
||||
# l'image a besoin de docker/entrypoint.sh ; on se contente d'exclure
|
||||
# le compose et le dockerignore qui sont inutiles dans l'image.
|
||||
docker/docker-compose.yml
|
||||
docker/docker-compose.bridge.yml
|
||||
.dockerignore
|
||||
|
||||
# Bases locales (SQLite dev)
|
||||
data
|
||||
*.db
|
||||
*.db-journal
|
||||
prisma/data
|
||||
prisma/*.db
|
||||
prisma/*.db-journal
|
||||
|
||||
# Tests & coverage
|
||||
tests
|
||||
coverage
|
||||
.nyc_output
|
||||
__tests__
|
||||
|
||||
# Docs (sauf README)
|
||||
*.md
|
||||
!README.md
|
||||
|
||||
# CI / Misc
|
||||
.github
|
||||
.husky
|
||||
|
||||
52
.env.docker.example
Normal file
52
.env.docker.example
Normal file
@@ -0,0 +1,52 @@
|
||||
# ---------------------------------------------------------------
|
||||
# IPAM — Variables pour un déploiement Docker
|
||||
# ---------------------------------------------------------------
|
||||
# Copie ce fichier en `.env` à la racine du projet avant de lancer
|
||||
# `docker compose`. Le compose lit `../.env` (env_file).
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
NODE_ENV=production
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Base de données
|
||||
# ---------------------------------------------------------------
|
||||
# Choix par défaut : SQLite — aucune dépendance externe.
|
||||
# Pour basculer sur PostgreSQL :
|
||||
# 1) Lance le profil postgres : `docker compose --profile postgres up -d`
|
||||
# 2) Décommente la section PG ci-dessous et commente celle SQLite.
|
||||
DATABASE_PROVIDER=sqlite
|
||||
DATABASE_URL="file:/app/data/ipam.db"
|
||||
|
||||
# --- Variante PostgreSQL --------------------------------------
|
||||
# DATABASE_PROVIDER=postgresql
|
||||
# DATABASE_URL="postgresql://ipam:ipam@127.0.0.1:5432/ipam?schema=public"
|
||||
# POSTGRES_PASSWORD=ipam
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Application
|
||||
# ---------------------------------------------------------------
|
||||
PORT=3000
|
||||
APP_URL=http://localhost:3000
|
||||
|
||||
# Seed initial au premier démarrage (catégories d'apps, etc.)
|
||||
RUN_SEED=true
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Découverte réseau
|
||||
# ---------------------------------------------------------------
|
||||
# Adapte la plage à ton LAN (séparées par des virgules)
|
||||
DISCOVERY_DEFAULT_CIDRS=192.168.1.0/24
|
||||
|
||||
DISCOVERY_DEFAULT_PORTS=22,53,80,81,443,445,3000,3306,5432,6379,7878,8080,8081,8096,8123,8443,8989,9000,9090,9091,9117,9443,32400
|
||||
DISCOVERY_PING_TIMEOUT=1000
|
||||
DISCOVERY_PORT_TIMEOUT=800
|
||||
DISCOVERY_CONCURRENCY=32
|
||||
DISCOVERY_ENABLE_PING=true
|
||||
DISCOVERY_ENABLE_PORT_SCAN=true
|
||||
DISCOVERY_ENABLE_ARP=true
|
||||
DISCOVERY_ENABLE_MDNS=true
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# Logs
|
||||
# ---------------------------------------------------------------
|
||||
LOG_LEVEL=info
|
||||
@@ -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"]
|
||||
|
||||
109
docker/README.md
Normal file
109
docker/README.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# IPAM — Déploiement Docker
|
||||
|
||||
Tout ce qu'il faut pour lancer l'application en une commande.
|
||||
|
||||
## Pré-requis
|
||||
|
||||
- Docker Engine ≥ 24
|
||||
- Docker Compose v2 (`docker compose` et non `docker-compose`)
|
||||
- Linux conseillé (le mode `network_mode: host` n'est pas pleinement supporté sur Docker Desktop macOS/Windows ; voir la section *Bridge mode* plus bas)
|
||||
|
||||
## Fichiers fournis
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---|---|
|
||||
| `Dockerfile` | Image multi-stage (deps → build → runner) basée sur `node:20-alpine` |
|
||||
| `entrypoint.sh` | Attente PostgreSQL, migrations Prisma, seed optionnel, lancement Next |
|
||||
| `docker-compose.yml` | Compose principal — profils `sqlite` et `postgres`, mode host |
|
||||
| `docker-compose.bridge.yml` | Override pour passer en mode bridge (sans découverte LAN) |
|
||||
|
||||
## Démarrage rapide — profil SQLite
|
||||
|
||||
```bash
|
||||
# 1. Prépare la config
|
||||
cp .env.docker.example .env
|
||||
# (édite .env si besoin — surtout DISCOVERY_DEFAULT_CIDRS)
|
||||
|
||||
# 2. Build + run
|
||||
docker compose -f docker/docker-compose.yml --profile sqlite up -d --build
|
||||
|
||||
# 3. Logs
|
||||
docker compose -f docker/docker-compose.yml logs -f ipam
|
||||
```
|
||||
|
||||
L'UI est disponible sur <http://localhost:3000>.
|
||||
|
||||
## Profil PostgreSQL
|
||||
|
||||
```bash
|
||||
cp .env.docker.example .env
|
||||
# Dans .env, bascule sur PostgreSQL :
|
||||
# DATABASE_PROVIDER=postgresql
|
||||
# DATABASE_URL="postgresql://ipam:ipam@127.0.0.1:5432/ipam?schema=public"
|
||||
|
||||
docker compose -f docker/docker-compose.yml --profile postgres up -d --build
|
||||
```
|
||||
|
||||
Le container `ipam-postgres` expose le port `5432` sur l'hôte (utile pour `prisma studio` ou un client SQL externe).
|
||||
|
||||
## Bridge mode (sans découverte LAN)
|
||||
|
||||
Utile sur macOS / Windows ou pour un test rapide de l'UI :
|
||||
|
||||
```bash
|
||||
docker compose \
|
||||
-f docker/docker-compose.yml \
|
||||
-f docker/docker-compose.bridge.yml \
|
||||
--profile sqlite up -d --build
|
||||
```
|
||||
|
||||
⚠️ En bridge, **ARP / mDNS / ping sweep ne fonctionneront pas** sur ton LAN — seule la saisie manuelle reste pleinement utilisable.
|
||||
|
||||
## Commandes utiles
|
||||
|
||||
```bash
|
||||
# Arrêter
|
||||
docker compose -f docker/docker-compose.yml down
|
||||
|
||||
# Tout supprimer (y compris les volumes — perte des données !)
|
||||
docker compose -f docker/docker-compose.yml down -v
|
||||
|
||||
# Re-seeder manuellement
|
||||
docker exec -it ipam npx tsx prisma/seed.ts
|
||||
|
||||
# Prisma studio (depuis l'hôte, profil postgres)
|
||||
DATABASE_URL="postgresql://ipam:ipam@localhost:5432/ipam?schema=public" npx prisma studio
|
||||
|
||||
# Shell dans le container
|
||||
docker exec -it ipam sh
|
||||
```
|
||||
|
||||
## Variables d'environnement clés
|
||||
|
||||
Toutes les variables sont documentées dans [`.env.docker.example`](../.env.docker.example).
|
||||
Les plus importantes pour Docker :
|
||||
|
||||
- `DATABASE_PROVIDER` — `sqlite` (défaut) ou `postgresql`
|
||||
- `DATABASE_URL` — fichier `file:/app/data/ipam.db` ou DSN PostgreSQL
|
||||
- `RUN_SEED` — `true` pour exécuter `prisma/seed.ts` au premier boot
|
||||
- `DISCOVERY_DEFAULT_CIDRS` — plages scannées par défaut, à adapter à ton LAN
|
||||
|
||||
## Persistance
|
||||
|
||||
| Volume | Contenu |
|
||||
|---|---|
|
||||
| `ipam-data` | Base SQLite (`/app/data/ipam.db`) |
|
||||
| `ipam-postgres` | Données PostgreSQL |
|
||||
|
||||
Les deux survivent à `docker compose down`, mais pas à `down -v`.
|
||||
|
||||
## Pourquoi `network_mode: host` ?
|
||||
|
||||
Pour qu'un container puisse :
|
||||
- envoyer des paquets ICMP (ping sweep)
|
||||
- lire la table ARP (`ip neigh`) du réseau local
|
||||
- recevoir les annonces mDNS (port 5353 UDP multicast)
|
||||
|
||||
…il doit partager la pile réseau de l'hôte. Sans `host`, ces fonctionnalités sont aveugles au LAN.
|
||||
|
||||
Les `cap_add: [NET_RAW, NET_ADMIN]` permettent par ailleurs au binaire `ping` du container d'ouvrir un socket ICMP en non-root.
|
||||
43
docker/docker-compose.bridge.yml
Normal file
43
docker/docker-compose.bridge.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
# ---------------------------------------------------------------
|
||||
# IPAM — Override : bridge network (sans host mode)
|
||||
# ---------------------------------------------------------------
|
||||
# À combiner avec docker-compose.yml :
|
||||
# docker compose \
|
||||
# -f docker/docker-compose.yml \
|
||||
# -f docker/docker-compose.bridge.yml \
|
||||
# --profile sqlite up -d
|
||||
#
|
||||
# ATTENTION : en mode bridge la découverte ARP / mDNS / ping sweep
|
||||
# ne fonctionnera PAS sur le LAN (le container n'a pas accès direct
|
||||
# au réseau de l'hôte). À utiliser uniquement pour la saisie manuelle
|
||||
# ou un test rapide de l'UI.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
services:
|
||||
ipam:
|
||||
network_mode: bridge
|
||||
ports:
|
||||
- "3000:3000"
|
||||
networks:
|
||||
- ipam-net
|
||||
|
||||
ipam-pg:
|
||||
network_mode: bridge
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
# En bridge, on cible le service postgres par son nom DNS Docker
|
||||
DATABASE_URL: "postgresql://ipam:${POSTGRES_PASSWORD:-ipam}@postgres:5432/ipam?schema=public"
|
||||
networks:
|
||||
- ipam-net
|
||||
|
||||
postgres:
|
||||
network_mode: bridge
|
||||
ports:
|
||||
- "5432:5432"
|
||||
networks:
|
||||
- ipam-net
|
||||
|
||||
networks:
|
||||
ipam-net:
|
||||
driver: bridge
|
||||
@@ -2,60 +2,115 @@
|
||||
# IPAM — Docker Compose
|
||||
# ---------------------------------------------------------------
|
||||
# Deux profils :
|
||||
# - `sqlite` → ipam seul, base dans un volume
|
||||
# - `sqlite` → ipam seul, base SQLite dans un volume
|
||||
# - `postgres` → ipam + postgres
|
||||
#
|
||||
# Usage :
|
||||
# docker compose --profile sqlite up -d
|
||||
# docker compose --profile postgres up -d
|
||||
# docker compose -f docker/docker-compose.yml --profile sqlite up -d
|
||||
# docker compose -f docker/docker-compose.yml --profile postgres up -d
|
||||
#
|
||||
# Le mode `network_mode: host` est indispensable pour que la découverte
|
||||
# (ARP, mDNS, ping sweep, port scan) atteigne le LAN. Sans lui, le
|
||||
# container ne voit que le bridge Docker.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
services:
|
||||
# =========================================================
|
||||
# Service IPAM — variante SQLite (autonome, sans PostgreSQL)
|
||||
# =========================================================
|
||||
ipam:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
args:
|
||||
DATABASE_PROVIDER: sqlite
|
||||
image: ipam-homelab:sqlite
|
||||
container_name: ipam
|
||||
restart: unless-stopped
|
||||
# Network mode host : indispensable pour ARP / mDNS / ping sweep
|
||||
# sur le réseau local. Commenter cette ligne si non nécessaire.
|
||||
network_mode: host
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3000
|
||||
HOSTNAME: 0.0.0.0
|
||||
DATABASE_PROVIDER: sqlite
|
||||
DATABASE_URL: "file:/app/data/ipam.db"
|
||||
RUN_SEED: "${RUN_SEED:-false}"
|
||||
env_file:
|
||||
- ../.env
|
||||
volumes:
|
||||
- ipam-data:/app/data
|
||||
# Capabilities requises pour le ping ICMP raw
|
||||
cap_add:
|
||||
- NET_RAW
|
||||
- NET_ADMIN
|
||||
profiles: [sqlite, postgres]
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q --spider http://localhost:3000/ || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
profiles: ["sqlite"]
|
||||
|
||||
# =========================================================
|
||||
# Service IPAM — variante PostgreSQL
|
||||
# =========================================================
|
||||
ipam-pg:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
args:
|
||||
DATABASE_PROVIDER: postgresql
|
||||
image: ipam-homelab:postgres
|
||||
container_name: ipam
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3000
|
||||
HOSTNAME: 0.0.0.0
|
||||
DATABASE_PROVIDER: postgresql
|
||||
DATABASE_URL: "postgresql://ipam:${POSTGRES_PASSWORD:-ipam}@127.0.0.1:5432/ipam?schema=public"
|
||||
RUN_SEED: "${RUN_SEED:-false}"
|
||||
env_file:
|
||||
- ../.env
|
||||
cap_add:
|
||||
- NET_RAW
|
||||
- NET_ADMIN
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
required: false
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q --spider http://localhost:3000/ || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
profiles: ["postgres"]
|
||||
|
||||
# =========================================================
|
||||
# PostgreSQL (profil "postgres" uniquement)
|
||||
# =========================================================
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: ipam-postgres
|
||||
restart: unless-stopped
|
||||
# network_mode host → expose le port 5432 directement sur l'hôte.
|
||||
network_mode: host
|
||||
environment:
|
||||
POSTGRES_USER: ipam
|
||||
POSTGRES_PASSWORD: ipam
|
||||
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-ipam}"
|
||||
POSTGRES_DB: ipam
|
||||
PGPORT: 5432
|
||||
volumes:
|
||||
- ipam-postgres:/var/lib/postgresql/data
|
||||
ports:
|
||||
- '5432:5432'
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -U ipam']
|
||||
test: ["CMD-SHELL", "pg_isready -U ipam -d ipam"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 10
|
||||
profiles: [postgres]
|
||||
profiles: ["postgres"]
|
||||
|
||||
volumes:
|
||||
ipam-data:
|
||||
driver: local
|
||||
ipam-postgres:
|
||||
driver: local
|
||||
|
||||
@@ -44,8 +44,15 @@ if [ "${DATABASE_PROVIDER:-sqlite}" = "sqlite" ]; then
|
||||
fi
|
||||
|
||||
# --- 3. Migrations Prisma -----------------------------------------
|
||||
# Si des migrations existent → migrate deploy (production-safe)
|
||||
# Sinon (premier démarrage sans baseline) → db push pour initialiser le schéma
|
||||
if [ -d /app/prisma/migrations ] && [ "$(find /app/prisma/migrations -mindepth 1 -maxdepth 1 -type d 2>/dev/null | head -n 1)" != "" ]; then
|
||||
log "Application des migrations Prisma…"
|
||||
npx prisma migrate deploy
|
||||
else
|
||||
log "Aucune migration trouvée — initialisation du schéma via 'prisma db push'…"
|
||||
npx prisma db push --skip-generate --accept-data-loss
|
||||
fi
|
||||
|
||||
# --- 4. Seed optionnel --------------------------------------------
|
||||
if [ "${RUN_SEED:-false}" = "true" ]; then
|
||||
|
||||
Reference in New Issue
Block a user