Blog

Écrit le 01/11/2025
  • Drupal
  • Figma
  • Tailwind
  • CI/CD

En tant que Tech Lead PHP et passionné de tech, cela faisait un moment que je souhaitais mettre en place un espace personnel. Un endroit hybride, capable de servir à la fois de portfolio pour mes projets et de carnet de bord pour mes articles techniques, mes découvertes, ou même mes passions en dehors du code.

L'objectif principal était clair : concevoir un outil simple, rapide et efficace. Je voulais un site performant, fiable et agréable à utiliser, reflétant mon exigence sur la qualité du code.

Pour y parvenir, j'ai défini un workflow précis et structuré, fidèle à ce que j'applique au quotidien : Figma ➔ Intégration HTML ➔ Implantation back-end ➔ Déploiement.

Voici comment j'ai construit adsy.dev (dont le code source est disponible sur mon repo GitHub ads6yy/blog).

 

  1. Figma

Tout projet solide commence par une bonne conception. Avant d'écrire la moindre ligne de code, j'ai ouvert Figma pour prototyper l'interface.

Je voulais un design épuré, qui met en valeur le contenu (les articles et les projets) sans le surcharger d'effets inutiles. J'ai travaillé sur :

  • L'architecture de l'information : une navigation claire entre l'accueil, les projets et le blog.
  • Le responsive design : anticiper le comportement de l'interface sur mobile, tablette et desktop.

Cette étape m'a permis de valider la direction visuelle et de gagner un temps précieux pour la suite.

 

 

  1. Intégration HTML

Une fois les maquettes validées, place à l'intégration front-end. Mon objectif était de produire un code propre et facilement maintenable.

Pour la stack front, je suis parti sur :

  • HTML5 & Twig : pour la structuration sémantique et la flexibilité des templates.
  • Tailwind CSS & SCSS : Tailwind m'a permis d'itérer très rapidement sur le style directement depuis mes templates, tout en gardant une cohérence globale (design system).
  • JavaScript (Vanilla) : gardé au strict minimum pour les interactions essentielles, afin de préserver d'excellentes performances.

Le passage de Figma à l'intégration s'est fait de manière fluide, en traduisant mes composants visuels en composants Twig réutilisables.

 

  1. Backend

Étant expert Drupal et Symfony, le choix du back-end a été naturel. J'ai opté pour Drupal comme CMS pour propulser le site.

La stack back-end et infrastructure repose sur :

  • Drupal & PHP : pour la robustesse de la modélisation des données. J'ai créé des types de contenus sur-mesure pour gérer mes "Projets" (avec leurs taxonomies de technologies : Symfony, Bootstrap, Highcharts...) et mes "Articles".
  • Composer : pour une gestion rigoureuse des dépendances PHP.
  • Docker : l'ensemble de l'environnement de développement est conteneurisé. Cela me garantit un environnement isolé, reproductible et identique, peu importe la machine sur laquelle je travaille.

Le travail s'est concentré sur la création d'une architecture de données intelligente, la configuration des vues (Views) pour remonter dynamiquement 

les derniers articles/projets sur l'accueil, et le mapping des données avec les templates Twig.

 

 

  1. Déploiement

La dernière étape, et non des moindres : rendre le site accessible au monde entier de manière fiable et automatisée.

Plutôt que de gérer les mises en production manuellement, j'ai mis en place un pipeline CI/CD robuste utilisant les GitHub Workflows (GitHub Actions). Désormais, chaque modification poussée sur la branche principale de mon dépôt déclenche un processus de déploiement automatisé. Ce workflow s'occupe de tout :

  • Préparation de l'environnement et installation des dépendances PHP de manière propre (composer install --no-dev).
  • Compilation des assets frontend (Tailwind, SCSS, JS) qui sont minifiés pour la production.
  • Transfert des fichiers de la nouvelle build vers le serveur de production.
  • Exécution des scripts de post-déploiement : synchronisation des configurations Drupal et purge des caches pour servir la nouvelle version instantanément.

L'utilisation des GitHub Workflows rend les déploiements prédictifs, sécurisés et totalement transparents. Je peux ainsi me concentrer uniquement sur le code et l'écriture.

on:
  workflow_dispatch:
    inputs:
      ref:
        description: 'Branch or ref to deploy'
        required: true
        default: 'main'

name: Manual deploy to remote server

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.ref }}

      - name: Ensure rsync/ssh available
        run: sudo apt-get update && sudo apt-get install -y rsync openssh-client

      - name: Setup SSH
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }}
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
        run: |
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          printf "%s\n" "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa

          if [ -n "$SSH_KNOWN_HOSTS" ]; then
            printf "%s\n" "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
          else
            ssh-keyscan -p "${REMOTE_PORT:-22}" "${REMOTE_HOST}" >> ~/.ssh/known_hosts
          fi
          ssh-keygen -lf ~/.ssh/known_hosts || true

      - name: Rsync files to remote (preserve .htaccess)
        env:
          REMOTE_USER: ${{ secrets.REMOTE_USER }}
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          REMOTE_PATH: ${{ secrets.REMOTE_PATH }}
          REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
        run: |
          RSYNC_EXCLUDES=(
            --exclude='.git'
            --exclude='.github'
            --exclude='web/sites/default/files'
            --exclude='web/sites/default/settings.php'
            --exclude='deploy'
            --exclude='int'
          )

          # Protect .htaccess files on the destination from being deleted.
          # 'P' = protect (prevent deletion even with --delete).
          RSYNC_FILTERS=(
            --filter='P .htaccess'
          )

          # Actual deploy
          rsync -avz --delete "${RSYNC_EXCLUDES[@]}" "${RSYNC_FILTERS[@]}" \
            -e "ssh -p ${REMOTE_PORT:-22} -o StrictHostKeyChecking=yes" \
            ./ ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}

      - name: Run composer install, fix simple permissions and drush deploy on remote
        env:
          REMOTE_USER: ${{ secrets.REMOTE_USER }}
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          REMOTE_PATH: ${{ secrets.REMOTE_PATH }}
          REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
          REMOTE_WEBGROUP: ${{ secrets.REMOTE_WEBGROUP }}
        run: |
          ssh -p ${REMOTE_PORT:-22} ${REMOTE_USER}@${REMOTE_HOST} "set -e
            cd ${REMOTE_PATH}
            composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction --no-scripts
            vendor/bin/drush deploy -y
          "

 

Conclusion

Créer adsy.dev de A à Z a été un excellent exercice. Cela me permet d'avoir un terrain de jeu personnel où je maîtrise la chaîne complète, du design jusqu'au pipeline d'intégration continue, tout en gardant cette rigueur technique qui m'est chère.

Le site est amené à évoluer au gré de mes envies et de mes découvertes.

N'hésitez pas à jeter un œil au code source sur mon GitHub : ads6yy/blog.