Tous mes projets tournent sur mon propre VPS. Pas par idéologie anti-cloud : parce que déployer soi-même est le meilleur cours d'infra qu'on puisse suivre, et qu'un VPS à quelques euros héberge sans effort un portfolio, un dashboard et ce qui viendra ensuite.
## L'architecture, en une ligne
GitHub Actions se connecte en SSH au VPS et lance un script : git pull, npm i, prisma db push, next build, pm2 restart. C'est tout. Pas de Docker, pas de Kubernetes — un process Node géré par pm2 derrière un reverse proxy.
# .github/workflows/deploy.yml — l'essentiel
on:
push:
branches: [main]
jobs:
deploy:
steps:
- uses: appleboy/ssh-action@v1.2.0
with:
script: bash $HOME/portfolio-v2/scripts/server-deploy.sh## Piège n°1 : le Node fantôme
Mon premier déploiement a explosé avec des erreurs incompréhensibles. La cause : la session SSH non-interactive de GitHub Actions ne charge pas nvm, et retombait sur le Node système — un antique v12, alors que Next 15 exige ≥ 18.18. En interactif tout marchait, ce qui rendait le bug invisible.
Le fix, dans le script de déploiement :
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && nvm use 20
# garde-fou : refuser de continuer avec un Node trop vieux
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
[ "$NODE_MAJOR" -ge 18 ] || exit 1## Piège n°2 : le script qui se met à jour lui-même
Plus vicieux : le script de déploiement fait git pull… qui met à jour le script en train de tourner. Le run en cours continue d'exécuter l'ancienne version (bash garde son descripteur sur l'ancien fichier). Concrètement : le jour où j'ai ajouté prisma db push au script, le déploiement qui apportait ce changement ne l'a pas exécuté — il a fallu relancer le workflow une deuxième fois.
À retenir : toute modification du script de déploiement ne prend effet qu'au run suivant. Prévoyez un déclenchement manuel (workflow_dispatch) pour ces cas-là.
## Ce que je retiens
- Un garde-fou qui échoue bruyamment (version de Node) vaut mieux qu'un échec mystérieux trois étapes plus loin.
- Le déploiement est du code : il a ses bugs, ses versions, et mérite la même rigueur.
- Posséder la chaîne entière — du CSS au reverse proxy — change la façon dont on écrit l'application elle-même.