diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..16abb4d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,27 @@ +# Dépendances (réinstallées dans l'image) +node_modules/ +vendor/ +__pycache__/ +*.pyc + +# Git et IDE +.git/ +.gitignore +.vscode/ +.idea/ +*.swp + +# Fichiers de build locaux +dist/ +build/ +*.log + +# Secrets et config locale (CRITIQUE : risque d'exfiltration) +.env +.env.local +*.pem +*.key +secrets/ +.npmrc +.pypirc +kubeconfig \ No newline at end of file diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml new file mode 100644 index 0000000..98d5d53 --- /dev/null +++ b/.github/workflows/frontend.yml @@ -0,0 +1,77 @@ +name: Frontend +# Pipeline à choix multiple + +on: + # workflow_dispatch -> lancement manuel des jobs + workflow_dispatch: + inputs: + job_choice: + required: true + description: "Choix du job" + type: choice + default: all + options: + - build + - sonarqube + - test + - all # lancer tous les jobs + push: + paths: + - "apps/frontend/**" + - ".github/workflows/frontend.yml" + pull_request: + paths: + - "apps/frontend/**" + - ".github/workflows/frontend.yml" +# Ordre de lancement des jobs +# build -> test -> sonarqube -> deploy + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 24 + cache: npm + cache-dependency-path: apps/frontend/package-lock.json + + - run: npm ci + working-directory: apps/frontend + - run: npm run build + working-directory: apps/frontend + + test: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 24 + cache: npm + cache-dependency-path: apps/frontend/package-lock.json + - run: npm ci + working-directory: apps/frontend + - run: npm test -- --watch=false + working-directory: apps/frontend + + sonarqube: + needs: [build, test] + name: SonarQube + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + - name: SonarQube Scan + uses: SonarSource/sonarqube-scan-action@7006c4492b2e0ee0f816d36501671557c97f5995 # v8.1.0 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + + # deploy: + # runs-on: ubuntu-latest + # steps: + # - run: echo "DEPLOY job is running" diff --git a/apps/frontend/Dockerfile b/apps/frontend/Dockerfile new file mode 100644 index 0000000..1890bc1 --- /dev/null +++ b/apps/frontend/Dockerfile @@ -0,0 +1,47 @@ +# ================== +# Étape 1 : Build +# ================== + +# Image pour frontend +FROM node:24-alpine3.22 AS builder + +WORKDIR /app + +COPY package.json package-lock.json* ./ + +# Installation des dépendances du projet avec npm +RUN npm ci + +# Copie du code source vers le conteneur +COPY . . + +# Build +RUN npm run build + +# ================== +# Étape 2 : Runner +# ================== + + +FROM dhi.io/nginx:1.28.0-alpine3.21-dev AS runner + +# Copie de la configuration de nginx +COPY --chown=root:root --chmod=755 nginx.conf /etc/nginx/nginx.conf + +# Copy the static build output from the build stage to Nginx's default HTML serving directory +COPY --chown=root:root --chmod=755 --from=builder /app/dist/*/browser /usr/share/nginx/html + +# Create necessary directories with proper permissions for nginx +RUN mkdir -p /var/log/nginx /var/cache/nginx && \ + chown -R nginx:nginx /var/log/nginx /var/cache/nginx /usr/share/nginx/html + +# Use a non-root user for security best practices +USER nginx + +# Frontend : port 3000 +# Backend : port 8000 +EXPOSE 3000 + +# Start Nginx directly with custom config +ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"] +CMD ["-g", "daemon off;"] \ No newline at end of file diff --git a/apps/frontend/nginx.conf b/apps/frontend/nginx.conf new file mode 100644 index 0000000..08e703d --- /dev/null +++ b/apps/frontend/nginx.conf @@ -0,0 +1,32 @@ +worker_processes auto; +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + sendfile on; + keepalive_timeout 65; + + + server { + listen 3000; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location ~ /\. { + deny all; + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml index d8569c9..3d0ea63 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,5 +43,12 @@ services: - "${BACKEND_PORT:-8000}:8000" restart: unless-stopped + frontend: + build: ./apps/frontend + ports: + - "${FRONTEND_PORT:-3000}:80" + restart: unless-stopped + + volumes: pgdata: diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..3c1af86 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,14 @@ +sonar.projectKey=ProjetPiscine_EnerVision +sonar.organization=groupe3-ener-vision + + +# This is the name and version displayed in the SonarCloud UI. +#sonar.projectName=ProjetPiscine_EnerVision +#sonar.projectVersion=1.0 + + +# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. +#sonar.sources=. + +# Encoding of the source code. Default is default system encoding +#sonar.sourceEncoding=UTF-8 \ No newline at end of file