From 8061887176dcd723d9c7ba6f7699202399ffafce Mon Sep 17 00:00:00 2001 From: Manus Deploy Date: Thu, 11 Jun 2026 14:18:26 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20ajout=20Dockerfile,=20docker-compose=20?= =?UTF-8?q?et=20nginx=20pour=20d=C3=A9ploiement=20recette?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.recette | 29 ++++++++++++++++++++ Dockerfile | 37 +++++++++++++++++++++++++ docker-compose.yml | 68 ++++++++++++++++++++++++++++++++++++++++++++++ nginx.conf | 20 ++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 .env.recette create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 nginx.conf diff --git a/.env.recette b/.env.recette new file mode 100644 index 0000000..9f11b2e --- /dev/null +++ b/.env.recette @@ -0,0 +1,29 @@ +# Environnement de recette — itinova-budget-si +NODE_ENV=production + +# Base de données locale MySQL +MYSQL_ROOT_PASSWORD=BudgetSI2027! +MYSQL_DATABASE=budget_si +MYSQL_USER=budget_user +MYSQL_PASSWORD=BudgetSI2027! +DATABASE_URL=mysql://budget_user:BudgetSI2027!@db:3306/budget_si + +# JWT +JWT_SECRET=budget-si-recette-jwt-secret-2027 + +# OAuth Manus (désactivé en recette — auth locale uniquement) +VITE_APP_ID= +OAUTH_SERVER_URL= +VITE_OAUTH_PORTAL_URL= +OWNER_OPEN_ID= +OWNER_NAME= + +# Forge API (désactivé en recette) +BUILT_IN_FORGE_API_URL= +BUILT_IN_FORGE_API_KEY= +VITE_FRONTEND_FORGE_API_KEY= +VITE_FRONTEND_FORGE_API_URL= + +# Analytics (désactivé en recette) +VITE_ANALYTICS_ENDPOINT= +VITE_ANALYTICS_WEBSITE_ID= diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..35082fb --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM node:22-alpine AS builder + +WORKDIR /app + +# Copier les fichiers de dépendances +COPY package.json pnpm-lock.yaml ./ +RUN npm install -g pnpm && pnpm install --frozen-lockfile + +# Copier le reste du code +COPY . . + +# Build +RUN pnpm build + +# ── Image de production ────────────────────────────────────────────────────── +FROM node:22-alpine AS runner + +WORKDIR /app + +RUN npm install -g pnpm + +# Copier les dépendances de production uniquement +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --prod + +# Copier le build +COPY --from=builder /app/dist ./dist + +# Copier les fichiers de configuration nécessaires au runtime +COPY drizzle ./drizzle +COPY drizzle.config.ts ./ + +EXPOSE 3000 + +ENV NODE_ENV=production + +CMD ["node", "dist/index.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3578755 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,68 @@ +version: "3.9" + +services: + app: + build: . + container_name: itinova-budget-si-app + restart: unless-stopped + ports: + - "3042:3000" + environment: + - NODE_ENV=production + - DATABASE_URL=${DATABASE_URL} + - JWT_SECRET=${JWT_SECRET} + - VITE_APP_ID=${VITE_APP_ID} + - OAUTH_SERVER_URL=${OAUTH_SERVER_URL} + - VITE_OAUTH_PORTAL_URL=${VITE_OAUTH_PORTAL_URL} + - OWNER_OPEN_ID=${OWNER_OPEN_ID} + - OWNER_NAME=${OWNER_NAME} + - BUILT_IN_FORGE_API_URL=${BUILT_IN_FORGE_API_URL} + - BUILT_IN_FORGE_API_KEY=${BUILT_IN_FORGE_API_KEY} + - VITE_FRONTEND_FORGE_API_KEY=${VITE_FRONTEND_FORGE_API_KEY} + - VITE_FRONTEND_FORGE_API_URL=${VITE_FRONTEND_FORGE_API_URL} + - VITE_ANALYTICS_ENDPOINT=${VITE_ANALYTICS_ENDPOINT} + - VITE_ANALYTICS_WEBSITE_ID=${VITE_ANALYTICS_WEBSITE_ID} + depends_on: + db: + condition: service_healthy + networks: + - budget-net + + db: + image: mysql:8.0 + container_name: itinova-budget-si-db + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-BudgetSI2027!} + MYSQL_DATABASE: ${MYSQL_DATABASE:-budget_si} + MYSQL_USER: ${MYSQL_USER:-budget_user} + MYSQL_PASSWORD: ${MYSQL_PASSWORD:-BudgetSI2027!} + volumes: + - db_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-BudgetSI2027!}"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - budget-net + + nginx: + image: nginx:alpine + container_name: itinova-budget-si-nginx + restart: unless-stopped + ports: + - "3043:80" + volumes: + - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - app + networks: + - budget-net + +volumes: + db_data: + +networks: + budget-net: + driver: bridge diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..e507e83 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,20 @@ +server { + listen 80; + server_name _; + + client_max_body_size 50M; + + location / { + proxy_pass http://app:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_cache_bypass $http_upgrade; + proxy_read_timeout 300s; + proxy_connect_timeout 75s; + } +}