diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..a17cdcf --- /dev/null +++ b/.npmrc @@ -0,0 +1,4 @@ +prefer-workspace-packages=true +strict-peer-dependencies=false +auto-install-peers=true +strict-engines=true \ No newline at end of file diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index d7abcc2..bffef8d 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -1,88 +1,55 @@ # ============================================================================= -# DOCKERFILE - API NESTJS DROPIT (Version optimisée) +# DOCKERFILE - API NESTJS DROPIT # ============================================================================= -# Inspiré des meilleures pratiques pour monorepos # ----------------------------------------------------------------------------- -# STAGE 1: Base avec pnpm +# STAGE 1: Base # ----------------------------------------------------------------------------- FROM node:20-alpine AS base ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" -# Version fixe pour éviter les conflits de lockfile +# Use pnpm version according to our package.json, if not the pnpm store will not be in synced later on, resulting in errors RUN corepack enable && corepack prepare pnpm@8.15.4 --activate WORKDIR /app # ----------------------------------------------------------------------------- -# STAGE 2: Builder - Installation et build +# STAGE 2: Builder - Installing deps, building and deploying # ----------------------------------------------------------------------------- FROM base AS builder -# Installation des outils système nécessaires -RUN apk add --no-cache python3 make g++ +# pnpm fetch does require only lockfile +COPY pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +RUN pnpm fetch -# pnpm fetch nécessite seulement le lockfile -COPY pnpm-lock.yaml pnpm-workspace.yaml ./ -RUN pnpm fetch --ignore-scripts - -# Copier le code source après fetch +# Copy source after fetch COPY . . -RUN pnpm install -r --offline --prefer-offline --ignore-scripts - -# Build des packages dans le bon ordre (pnpm gère les dépendances) -RUN pnpm --filter "@dropit/schemas" build -RUN pnpm --filter "@dropit/contract" build -RUN pnpm --filter "@dropit/permissions" build - -# Build de l'API -RUN pnpm --filter api build +RUN pnpm install -r --offline --prefer-offline -# Créer un dossier de déploiement avec seulement les deps nécessaires -RUN pnpm deploy --prod --filter="./apps/api" /app/deploy +RUN pnpm --filter {apps/api}... build -# Copier manuellement le dossier dist car pnpm deploy ne l'inclut pas toujours -RUN cp -r /app/apps/api/dist /app/deploy/dist +# Create a deploy folder with only the required deps +# This respects gitignore, so remember to include your dist folder in the "files" section of your package.json +RUN pnpm deploy --prod --filter="./apps/api" /app/api # ----------------------------------------------------------------------------- -# STAGE 3: Production - Image finale ultra-légère +# STAGE 3: Production - Final Image # ----------------------------------------------------------------------------- FROM base AS runner -# Installation de dumb-init pour gestion des signaux -RUN apk add --no-cache dumb-init - -# Création utilisateur non-root -RUN addgroup -g 1001 -S nodejs && adduser -S nestjs -u 1001 - WORKDIR /app -# Copier les fichiers de production depuis le stage deploy -COPY --from=builder /app/deploy/node_modules ./node_modules -COPY --from=builder /app/deploy/dist ./dist -COPY --from=builder /app/deploy/package.json ./package.json - -# Copier les packages buildés (nécessaires pour les imports workspace) -COPY --from=builder /app/packages/schemas/dist ./node_modules/@dropit/schemas/dist -COPY --from=builder /app/packages/contract/dist ./node_modules/@dropit/contract/dist -COPY --from=builder /app/packages/permissions/dist ./node_modules/@dropit/permissions/dist - -# Configuration des permissions -RUN chown -R nestjs:nodejs /app -USER nestjs - -# Variables d'environnement +# Set environment ENV NODE_ENV=production -ENV PORT=3000 -# Exposition du port -EXPOSE 3000 +COPY --from=builder /app/api/node_modules ./node_modules +COPY --from=builder /app/api/dist ./dist +COPY --from=builder /app/api/package.json ./package.json -# Health check -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD node -e "require('http').get('http://localhost:3000/api/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })" +# Expose port +EXPOSE 3000 -# Point d'entrée avec dumb-init -ENTRYPOINT ["dumb-init", "--"] +ENV MIKRO_ORM_CLI_USE_TS_NODE=false +ENV MIKRO_ORM_CLI_CONFIG=dist/config/mikro-orm.config.js -# Commande de démarrage -CMD ["node", "dist/main.js"] \ No newline at end of file +# Start the application after syncing the database +CMD ["sh", "-c", "pnpm db:sync && pnpm run start:prod"] \ No newline at end of file diff --git a/apps/api/package.json b/apps/api/package.json index a0b6c16..2dcab43 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -5,6 +5,10 @@ "author": "", "private": true, "license": "UNLICENSED", + "packageManager": "pnpm@8.15.4", + "files": [ + "dist" + ], "scripts": { "build": "nest build", "start": "nest start", @@ -13,14 +17,14 @@ "start:prod": "node dist/main", "typecheck": "tsc --noEmit", "clean": "rm -rf dist", - "db:create": "mikro-orm database:create && pnpm db:migration:up", - "db:sync": "mikro-orm schema:update --run", - "db:fresh": "mikro-orm schema:fresh --seed --run --config=./src/config/mikro-orm.config.ts", - "db:migration:up": "mikro-orm migration:up", - "db:migration:down": "mikro-orm migration:down", - "db:migration:create": "mikro-orm migration:create", - "db:migration:list": "mikro-orm migration:list", - "db:seed": "mikro-orm seeder:run --config=./src/config/mikro-orm.config.ts", + "db:create": "npx mikro-orm database:create && pnpm db:migration:up", + "db:sync": "npx mikro-orm schema:update --run", + "db:fresh": "npx mikro-orm schema:fresh --seed --run --config=./src/config/mikro-orm.config.ts", + "db:migration:up": "npx mikro-orm migration:up", + "db:migration:down": "npx mikro-orm migration:down", + "db:migration:create": "npx mikro-orm migration:create", + "db:migration:list": "npx mikro-orm migration:list", + "db:seed": "npx mikro-orm seeder:run --config=./src/config/mikro-orm.config.ts", "test": "jest", "test:unit": "jest --testPathIgnorePatterns=src/test/", "test:unit:watch": "jest --testPathIgnorePatterns=src/test/ --watch",