From 4b988706cc861f3c7d91de59caa7524ef0ca963e Mon Sep 17 00:00:00 2001 From: kyuno053 <31762247+kyuno053@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:45:04 +0200 Subject: [PATCH] fix(docker): n'installe plus/ne build plus Cypress dans l'image de prod (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README : le dev local cible désormais `docker compose up -d postgres` explicitement. `docker-compose.yml` définit aussi le service `app` (celui que Portainer build en prod) — sans nom de service, `docker compose up -d` construisait et démarrait aussi ce conteneur en local, déclenchant un `pnpm install` sur tout le monorepo (donc le `cypress` d'apps/web, avec son téléchargement de binaire) pour une image dont le dev local n'a pas besoin. - Dockerfile (apps/api) : `CYPRESS_INSTALL_BINARY=0` sur le stage `build` — évite le téléchargement du binaire Cypress (~200 Mo, Electron) à chaque build de l'image de prod, qu'il vienne de `docker compose` ou du pipeline de release. Le package `cypress` lui-même reste installé (vraie entrée du lockfile) ; `pnpm prune --prod` puis un wipe+reinstall complet ont été testés pour l'éliminer aussi, mais se sont révélés dangereux dans ce monorepo pnpm (prune ignore les node_modules des autres packages du workspace ; le wipe+reinstall a fait sauter le binding natif compilé d'argon2, crash silencieux au démarrage du conteneur) — pas justifié pour ~10 Mo de JS inerte une fois le téléchargement du binaire évité. - apps/api/package.json : déplace `prisma` (le CLI, invoqué directement par le `CMD` du conteneur pour `migrate deploy`) de devDependencies vers dependencies — classification plus correcte indépendamment du point ci-dessus. Vérifié par un vrai `docker build` + `docker run` contre un Postgres réel (migrations, seed, démarrage du serveur, signup avec hash argon2 réel). --- README.md | 10 +++++++++- apps/api/Dockerfile | 18 ++++++++++++++++++ apps/api/package.json | 2 +- pnpm-lock.yaml | 6 +++--- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 80f253a..f02b09b 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ hors du repo). ```bash # Base de données Postgres locale -docker compose up -d +docker compose up -d postgres # Applique le schéma (première fois / après un changement de prisma/schema.prisma) pnpm --filter api exec prisma migrate dev @@ -94,6 +94,14 @@ pnpm dev:web > Dans ce cas, mets `POSTGRES_PORT=5433` (ou autre) dans ton `.env` **et** adapte le > port dans la `DATABASE_URL` de `apps/api/.env`. +> **Toujours cibler `postgres`, jamais `docker compose up -d` tout court.** Le même +> `docker-compose.yml` définit aussi le service `app` (voir [Déploiement](#déploiement)) — +> celui que Portainer construit en production. Sans nom de service, `docker compose up -d` +> démarre les deux : ça déclenche un `pnpm install` sur tout le monorepo (donc aussi le +> `cypress` d'`apps/web`, avec son téléchargement de binaire) rien que pour builder une +> image dont le dev local n'a pas besoin (on sert le front/back directement via +> `pnpm dev:web`/`pnpm dev:api`, pas ce conteneur). + ## Qualité / Tests ```bash diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index 9e4441a..1a31a6b 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -14,6 +14,24 @@ WORKDIR /repo # process, one container, no separate nginx/static host. Builds both so the # runtime stage below can copy each app's build output independently. FROM base AS build +# `pnpm install` (below) installs every workspace's dependencies, including +# apps/web's `cypress` devDependency — this image never runs it, so skip its +# (large, Electron-bundled) binary download: saves build time/bandwidth and +# removes a network dependency on Cypress's CDN from every production build. +# The `cypress` npm *package* itself still ends up in `node_modules` (it's a +# real lockfile entry) and gets copied into `runtime` below — a deliberate +# tradeoff. Tried to prune it out too (`pnpm prune --prod`, then a full +# wipe-and-reinstall with `--prod`), but in this pnpm workspace both proved +# actively unsafe rather than just ineffective: `prune` doesn't cascade into +# sibling workspace projects' `node_modules` at all, and even a *scoped* +# `pnpm --filter web prune --prod` emptied out apps/api's entire +# `node_modules` as a side effect; the wipe-and-reinstall variant silently +# dropped argon2's compiled native binding (no postinstall re-run to rebuild +# it), which only surfaced as a crash *after* deploy +# (`Cannot find module '.../argon2.node'`) — not something to risk on the +# real production image for what's ~10MB of inert JS once the binary +# download above is already skipped. +ENV CYPRESS_INSTALL_BINARY=0 COPY . . RUN pnpm install --frozen-lockfile RUN pnpm --filter api build diff --git a/apps/api/package.json b/apps/api/package.json index e8bdb61..283cf99 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -27,6 +27,7 @@ "dotenv": "^16.4.5", "express": "^4.21.1", "jsonwebtoken": "^9.0.3", + "prisma": "^5.22.0", "zod": "^3.23.8" }, "devDependencies": { @@ -39,7 +40,6 @@ "chai": "^5.1.2", "cross-env": "^10.1.0", "mocha": "^10.8.2", - "prisma": "^5.22.0", "supertest": "^7.0.0", "tsx": "^4.19.2", "typescript": "^5.7.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88b6a91..bf6ace9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: jsonwebtoken: specifier: ^9.0.3 version: 9.0.3 + prisma: + specifier: ^5.22.0 + version: 5.22.0 zod: specifier: ^3.23.8 version: 3.25.76 @@ -75,9 +78,6 @@ importers: mocha: specifier: ^10.8.2 version: 10.8.2 - prisma: - specifier: ^5.22.0 - version: 5.22.0 supertest: specifier: ^7.0.0 version: 7.2.2