Déploiement d’une application React sur VPS avec Traefik et CI/CD
Ce document résume la procédure pour héberger une application React (construite avec Vite) sur un serveur VPS (Ubuntu) déjà équipé de Traefik. Le même socle de VPS avec Docker et Traefik permet aussi d’héberger Supabase en auto-hébergement.
L’architecture finale utilise GitHub Actions pour un workflow CI/CD : le build Docker est effectué par GitHub, et le VPS se contente de télécharger et de redémarrer l’image Docker finale. Le même serveur peut aussi héberger n8n et ses outils d’IA, une fois préparé pour l’auto-hébergement sur VPS avec sudo et un espace d’échange.
Prérequis
- Un VPS (Ubuntu) avec Docker, Docker Compose et Traefik opérationnel.
- Un nom de domaine pointant vers l’IP du VPS.
- Un dépôt GitHub privé pour l’application (
votre-organisation/mon-projet-react). - Un compte Docker Hub ou GitHub Container Registry (GHCR) pour héberger l’image.
Phase 1 : Fichiers de l’application React
À la racine de votre projet React local, trois fichiers sont nécessaires.
1. .dockerignore
# .dockerignore - Exclude development files from the Docker context
node_modules
dist
.git
.env
2. Dockerfile
Ce fichier utilise un multi-stage build pour créer une image légère contenant Nginx, qui sert les fichiers statiques de React.
# Dockerfile - Build and serve the React application
# Stage 1: Build the React app (using Vite's output dir 'dist')
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install --frozen-lockfile
COPY . .
RUN npm run build
# Stage 2: Serve the build with Nginx
FROM nginx:1.27-alpine
WORKDIR /usr/share/nginx/html
# Clean default Nginx content
RUN rm -rf ./*
# Copy built assets from builder stage (Vite outputs to 'dist')
COPY --from=builder /app/dist .
# Expose port 80 (Nginx default)
EXPOSE 80
# Run Nginx
CMD ["nginx", "-g", "daemon off;"]
3. docker-compose.yml
Ce fichier est utilisé par le VPS pour exécuter le conteneur. Notez qu’il n’utilise pas build: . ; il référence directement l’image qui sera construite par la CI/CD.
# docker-compose.yml - Defines the service for production pulling from a registry
services:
react_app:
# Pull the image built by GitHub Actions (GHCR)
image: ghcr.io/votre-organisation/mon-projet-react:latest
container_name: react_app_prod
# Ensure Docker Compose always pulls the newest 'latest' image
pull_policy: always
restart: unless-stopped
networks:
# Connect to the existing Traefik network
- traefik_web
labels:
# === Traefik Configuration ===
- "traefik.enable=true"
# --- HTTP Router Definition ---
- "traefik.http.routers.react-app.rule=Host(`react.votre-domaine.com`)"
- "traefik.http.routers.react-app.entrypoints=websecure"
- "traefik.http.routers.react-app.tls.certresolver=mon-resolver-tls"
# --- Service Definition ---
- "traefik.http.services.react-app.loadbalancer.server.port=80"
networks:
traefik_web:
# Connect to the external network managed by Traefik
external: true
Phase 2 : Configuration des accès (Clés SSH)
Trois clés SSH distinctes sont nécessaires pour sécuriser le flux :
- Clé SSH du compte GitHub (Locale)
- Emplacement :
~/.ssh/id_ed25519(sur votre machine de développement locale). - Usage : Pousser (
git push) le code local vers GitHub. - Configuration : À ajouter dans
GitHub > Settings > SSH and GGPG keys.
- Emplacement :
- Clé de déploiement (VPS)
- Emplacement :
/home/user/.ssh/id_deploy(sur le VPS). - Usage : Permettre au VPS de cloner (
git clone) le dépôt privé (uniquement pour la configuration initiale). - Configuration : Clé publique à ajouter dans
Dépôt GitHub > Settings > Deploy keys(lecture seule).
- Emplacement :
- Clé de déploiement (CI/CD)
- Emplacement :
~/.ssh/id_github_action(générée localement, mais utilisée par l’action). - Usage : Permettre à GitHub Actions de se connecter en SSH au VPS pour exécuter les commandes de déploiement.
- Configuration (Clé privée) : À ajouter dans
Dépôt GitHub > Settings > Secrets > Actions(ex:VPS_SSH_PRIVATE_KEY). - Configuration (Clé publique) : À ajouter au fichier
/home/user/.ssh/authorized_keyssur le VPS.
- Emplacement :
Phase 3 : Workflow CI/CD (GitHub Actions)
Créez ce fichier à la racine de votre projet pour automatiser le déploiement.
Chemin : .github/workflows/deploy.yml
# .github/workflows/deploy.yml - Workflow to build and deploy the React app
name: Build and Deploy React App
on:
push:
# Triggers on push to the 'main' branch
branches: [ "main" ]
workflow_dispatch:
# Allows manual triggering from the GitHub Actions tab
permissions:
contents: read
packages: write
jobs:
build-and-push-image:
name: Build and Push Docker Image
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry (GHCR)
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/votre-organisation/mon-projet-react:latest
deploy-to-vps:
name: Deploy to VPS
runs-on: ubuntu-latest
needs: build-and-push-image
steps:
- name: SSH and Deploy
uses: appleboy/[email protected]
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USERNAME }}
key: ${{ secrets.VPS_SSH_PRIVATE_KEY }}
# 'script' runs these commands on the VPS
script: |
cd /opt/stacks/mon-projet-react
docker pull ghcr.io/votre-organisation/mon-projet-react:latest
docker compose up -d
docker image prune -f
Secrets GitHub Actions Requis
VPS_HOST: L’adresse IP ou le domaine du VPS.VPS_USERNAME: Le nom d’utilisateur pour la connexion SSH (ex:user).VPS_SSH_PRIVATE_KEY: La clé privée de la Clé de déploiement (CI/CD) (voir Phase 2).
Phase 4 : Stratégies de Déploiement
Option A : Déploiement par Branche (Standard)
Cette approche utilise une branche develop pour l’itération et main pour la production.
- Itération : Travaillez localement, poussez sur la branche
develop.git checkout develop git push origin developAucun déploiement n’est déclenché. - Production : Lorsque le code est prêt, fusionnez
developdansmain.git checkout main git merge develop git push origin mainLe push surmaindéclenche le workflow GitHub Actions et met à jour le site.
Option B : Déploiement Manuel (Adapté aux services tiers)
Si un service tiers (ex: un outil d’itération front-end) force les push sur la branche main, modifiez le workflow (deploy.yml) pour empêcher les déploiements automatiques.
- Modifier deploy.yml :Supprimez la section on: push: et ne conservez que on: workflow_dispatch:.
- Itération : Le service tiers pousse sur main.Aucun déploiement n’est déclenché.
- Production :
- Allez sur la page du dépôt GitHub > Actions.
- Sélectionnez le workflow « Build and Deploy React App ».
- Cliquez sur le bouton Run workflow (Exécuter le workflow).



