From 8da1d1edc98e193a6b14e72812cde62f9568a557 Mon Sep 17 00:00:00 2001 From: "kevin.lhereec" Date: Mon, 17 Aug 2026 11:44:07 +0200 Subject: [PATCH] feat: dockerize client (nginx) and server (node) with docker-compose --- .idea/misc.xml | 6 ++++++ .idea/modules.xml | 8 ++++++++ .idea/regnum.iml | 9 +++++++++ .idea/vcs.xml | 6 ++++++ client/.dockerignore | 4 ++++ client/.env.production | 3 +++ client/Dockerfile | 19 +++++++++++++++++++ client/nginx.conf | 27 +++++++++++++++++++++++++++ client/src/services/socket.js | 9 ++++++--- docker-compose.yml | 32 ++++++++++++++++++++++++++++++++ server/.dockerignore | 3 +++ server/Dockerfile | 20 ++++++++++++++++++++ 12 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/regnum.iml create mode 100644 .idea/vcs.xml create mode 100644 client/.dockerignore create mode 100644 client/.env.production create mode 100644 client/Dockerfile create mode 100644 client/nginx.conf create mode 100644 docker-compose.yml create mode 100644 server/.dockerignore create mode 100644 server/Dockerfile diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9bb6421 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d485b69 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/regnum.iml b/.idea/regnum.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/regnum.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/client/.dockerignore b/client/.dockerignore new file mode 100644 index 0000000..5edb67d --- /dev/null +++ b/client/.dockerignore @@ -0,0 +1,4 @@ +node_modules +dist +.env.local +*.log diff --git a/client/.env.production b/client/.env.production new file mode 100644 index 0000000..5f3c675 --- /dev/null +++ b/client/.env.production @@ -0,0 +1,3 @@ +# En production Docker, nginx proxifie /socket.io vers le container server +# Le client se connecte donc sur la même origine (pas de port différent) +VITE_SERVER_URL= diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 0000000..6f1b229 --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,19 @@ +# ── Stage 1 : build ────────────────────────────────────────────────────────── +FROM node:20-alpine AS builder + +WORKDIR /app + +COPY package.json package-lock.json* ./ +RUN npm ci + +COPY . . +RUN npm run build + +# ── Stage 2 : serve with nginx ──────────────────────────────────────────────── +FROM nginx:1.27-alpine + +COPY --from=builder /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/client/nginx.conf b/client/nginx.conf new file mode 100644 index 0000000..37cf89b --- /dev/null +++ b/client/nginx.conf @@ -0,0 +1,27 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Vue Router - renvoyer toutes les routes vers index.html + location / { + try_files $uri $uri/ /index.html; + } + + # Proxy WebSocket + API vers le serveur Node + location /socket.io/ { + proxy_pass http://server:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + + # Compression gzip + gzip on; + gzip_types text/plain text/css application/javascript application/json; + gzip_min_length 1024; +} diff --git a/client/src/services/socket.js b/client/src/services/socket.js index 1f3e55e..999d510 100644 --- a/client/src/services/socket.js +++ b/client/src/services/socket.js @@ -4,9 +4,12 @@ let socket = null export function useSocket() { if (!socket) { - socket = io(import.meta.env.VITE_SERVER_URL || 'http://localhost:3000', { - autoConnect: true - }) + // En dev : pointe vers localhost:3000 + // En prod Docker : connexion sur la même origine (nginx proxifie /socket.io) + const url = import.meta.env.VITE_SERVER_URL || ( + import.meta.env.PROD ? window.location.origin : 'http://localhost:3000' + ) + socket = io(url, { autoConnect: true }) } return socket } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9226b66 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +services: + + server: + build: + context: ./server + dockerfile: Dockerfile + container_name: regnum-server + restart: unless-stopped + environment: + NODE_ENV: production + PORT: 3000 + expose: + - "3000" + networks: + - regnum-net + + client: + build: + context: ./client + dockerfile: Dockerfile + container_name: regnum-client + restart: unless-stopped + ports: + - "8080:80" + depends_on: + - server + networks: + - regnum-net + +networks: + regnum-net: + driver: bridge diff --git a/server/.dockerignore b/server/.dockerignore new file mode 100644 index 0000000..1373ff3 --- /dev/null +++ b/server/.dockerignore @@ -0,0 +1,3 @@ +node_modules +*.log +.env diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..04159a5 --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,20 @@ +# ── Stage 1 : deps ─────────────────────────────────────────────────────────── +FROM node:20-alpine AS deps + +WORKDIR /app +COPY package.json package-lock.json* ./ +RUN npm ci --omit=dev + +# ── Stage 2 : runtime ───────────────────────────────────────────────────────── +FROM node:20-alpine + +WORKDIR /app + +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +ENV NODE_ENV=production +ENV PORT=3000 + +EXPOSE 3000 +CMD ["node", "src/index.js"]