diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5dd21e3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules +dist +.git +.env +.env.* +uploads +mysql-data +src +deployment-package +*.tar.gz +*.pdf +*.docx diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1a8ec60 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,40 @@ +FROM node:20-alpine AS builder + +WORKDIR /app + +# Corepack applique la version de pnpm verrouillĂ©e dans package.json. +RUN npm install -g corepack@latest && corepack enable +COPY . . +RUN pnpm install --frozen-lockfile + +# Les variables Vite doivent ĂȘtre disponibles pendant la compilation frontend. +ARG VITE_APP_ID +ARG VITE_OAUTH_PORTAL_URL +ARG VITE_APP_TITLE +ARG VITE_FRONTEND_FORGE_API_URL +ARG VITE_FRONTEND_FORGE_API_KEY +ARG VITE_ANALYTICS_ENDPOINT +ARG VITE_ANALYTICS_WEBSITE_ID +ARG VITE_APP_LOGO +ENV VITE_APP_ID=${VITE_APP_ID} \ + VITE_OAUTH_PORTAL_URL=${VITE_OAUTH_PORTAL_URL} \ + VITE_APP_TITLE=${VITE_APP_TITLE} \ + VITE_FRONTEND_FORGE_API_URL=${VITE_FRONTEND_FORGE_API_URL} \ + VITE_FRONTEND_FORGE_API_KEY=${VITE_FRONTEND_FORGE_API_KEY} \ + VITE_ANALYTICS_ENDPOINT=${VITE_ANALYTICS_ENDPOINT} \ + VITE_ANALYTICS_WEBSITE_ID=${VITE_ANALYTICS_WEBSITE_ID} \ + VITE_APP_LOGO=${VITE_APP_LOGO} +RUN pnpm run build + +FROM node:20-alpine AS runner + +WORKDIR /app +ENV NODE_ENV=production + +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/dist ./dist +COPY --from=builder /app/drizzle ./drizzle +COPY --from=builder /app/package.json ./package.json + +EXPOSE 3000 +CMD ["node", "dist/index.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..55774d6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + args: + VITE_APP_ID: ${VITE_APP_ID} + VITE_OAUTH_PORTAL_URL: ${VITE_OAUTH_PORTAL_URL} + VITE_APP_TITLE: ${VITE_APP_TITLE} + VITE_FRONTEND_FORGE_API_URL: ${VITE_FRONTEND_FORGE_API_URL} + VITE_FRONTEND_FORGE_API_KEY: ${VITE_FRONTEND_FORGE_API_KEY} + VITE_ANALYTICS_ENDPOINT: ${VITE_ANALYTICS_ENDPOINT} + VITE_ANALYTICS_WEBSITE_ID: ${VITE_ANALYTICS_WEBSITE_ID} + VITE_APP_LOGO: ${VITE_APP_LOGO} + image: formation-manager-itinova-app:v2 + container_name: formation-manager-itinova + restart: unless-stopped + env_file: + - .env + environment: + NODE_ENV: production + PORT: 3000 + TRUST_PROXY: 1 + volumes: + - /opt/manus-deploy/apps/formation-manager-itinova/uploads:/app/uploads + networks: + - web + labels: + - "traefik.enable=true" + - "traefik.docker.network=web" + - "traefik.http.routers.formations-prod.entrypoints=websecure" + - "traefik.http.routers.formations-prod.rule=Host(`formations.itinova.org`) || Host(`formations.santinova-soft.org`)" + - "traefik.http.routers.formations-prod.tls=true" + - "traefik.http.routers.formations-prod.tls.certresolver=letsencrypt" + - "traefik.http.routers.formations-prod.service=formations-prod-svc" + - "traefik.http.services.formations-prod-svc.loadbalancer.server.port=3000" + +networks: + web: + external: true