Tous les projets
Projet perso

Déploiement automatisé de ce portfolio (CI/CD)

Comment ce portfolio est construit avec Astro puis déployé automatiquement via GitLab CI/CD, une image Docker Nginx, Watchtower et Traefik — le tout auto-hébergé.

Introduction

Pour présenter mes projets et compétences, je voulais un site simple à maintenir, facilement modifiable et intégré dans une logique DevOps. Ce portfolio est un site statique généré avec Astro, déployé automatiquement sur mon infrastructure personnelle.

🔗 Dépôt GitLab : gitlab.ggcorp.it/GGauzins/portfolio

Pourquoi GitLab (auto-hébergé) ?

  • Self-hosting : GitLab tourne sur mes propres serveurs — contrôle total sur l’infra, la sécurité et les données.
  • Simplicité : je clone, je modifie, je git push.
  • Automatisation CI/CD : GitLab construit l’image Docker à chaque commit sur main.
  • Développement structuré : je développe sur une branche dev en local (npm run dev), et la production (main) n’est mise à jour qu’après validation.

Stratégie de déploiement : Docker + Watchtower

Mon idée de départ était GitLab Pages, mais l’usage d’un domaine personnalisé (www.ggauzins.fr) imposait une 2ᵉ IP publique sur le serveur GitLab — incompatible avec mon infra. J’ai donc opté pour une solution Dockerisée :

  • Le site est construit avec Astro via GitLab CI.
  • Une image Docker (Nginx) est construite et poussée dans le GitLab Container Registry.
  • Une VM sous Docker exécute un conteneur basé sur cette image.
  • Watchtower surveille ce conteneur et tire automatiquement la dernière version publiée.

Résultat : je garde la simplicité d’un git push tout en maîtrisant l’hébergement et mon domaine.

Technologies utilisées

Dockerfile (multi-stage)

# --- Étape 1 : build du site avec Node ---
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# --- Étape 2 : runtime léger avec Nginx ---
FROM nginx:1.27-alpine AS runtime
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;"]

Pipeline GitLab CI

Seule la branche main déclenche le build et le push de l’image. La VM, via Watchtower, récupère ensuite l’image :latest.

stages:
  - build_image

build_image:
  stage: build_image
  image: docker:latest
  services:
    - name: docker:dind
      alias: docker
  variables:
    DOCKER_HOST: "tcp://docker:2375"
    DOCKER_TLS_CERTDIR: ""
  before_script:
    - docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
  script:
    - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
    - docker tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" "$CI_REGISTRY_IMAGE:latest"
    - docker push "$CI_REGISTRY_IMAGE:latest"
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'

Reverse proxy Traefik

http:
  routers:
    portfolio:
      entryPoints: [websecure]
      rule: "Host(`www.ggauzins.fr`)"
      tls:
        certResolver: lets-encr
      service: portfolio
    redirect-naked:
      entryPoints: [websecure]
      rule: "Host(`ggauzins.fr`)"
      middlewares: [redirect-to-www]
      service: noop@internal
      tls:
        certResolver: lets-encr
  middlewares:
    redirect-to-www:
      redirectRegex:
        regex: "^https?://ggauzins\\.fr/(.*)"
        replacement: "https://www.ggauzins.fr/$1"
        permanent: true
  services:
    portfolio:
      loadBalancer:
        servers:
          - url: "http://172.16.20.7:8086/"

Cela permet de sécuriser les deux domaines (www. et nu) en HTTPS via Let’s Encrypt, et de rediriger ggauzins.fr vers www.ggauzins.fr.

Docker Compose (VM de prod)

services:
  portfolio:
    image: registry.ggcorp.it/ggauzins/portfolio:latest
    container_name: portfolio
    restart: unless-stopped
    ports:
      - "8086:80"

  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    environment:
      - WATCHTOWER_POLL_INTERVAL=300
      - WATCHTOWER_CLEANUP=true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: portfolio

Résultat

  • Site en ligne avec HTTPS : www.ggauzins.fr
  • Déploiement 100 % automatisé : un simple git push sur main
  • Image Docker toujours à jour grâce à Watchtower
  • Domaine personnalisé et infrastructure maîtrisée

Conclusion

Ce projet met en pratique des compétences DevOps complètes : CI/CD, conteneurisation, reverse proxy, gestion de certificats SSL et automatisation du déploiement — appliquées à un site statique moderne sous Astro.