Alane Jaunet

Déployer sans Vercel ni Railway — VPS + PM2 + Caddy en 2026

Pourquoi j'ai choisi un VPS plutôt que Vercel ou Railway pour mon SaaS, et comment j'ai mis en place PM2, Caddy et GitHub webhooks.

Par Alane Jaunet20 mars 2026

Déployer sans Vercel ni Railway — VPS + PM2 + Caddy en 2026

Quand j'ai commencé à construire mon SaaS de productivité, la question de l'hébergement s'est vite posée. Vercel ? Railway ? Fly.io ? J'ai choisi un VPS à quelques euros par mois. Voici pourquoi, et comment j'ai tout mis en place.

Pourquoi pas Vercel ou Railway ?

Ce n'est pas par idéologie. Vercel est excellent pour les sites Next.js. Railway simplifie énormément le déploiement. Mais pour mon projet, trois choses m'ont fait choisir le VPS :

1. Le coût prévisible

Mon app utilise Express + PostgreSQL. Sur Railway, chaque service est facturé à l'usage. PostgreSQL seul peut coûter 10-20$/mois. Avec un VPS, tout tourne sur la même machine pour un prix fixe.

2. Le contrôle total

Mon app chiffre toutes les données utilisateur de bout en bout. Je voulais savoir exactement où sont stockées les données et ne dépendre d'aucun service tiers pour la base de données.

3. Les connexions persistantes

Vercel serverless ne supporte pas les connexions persistantes. Express sur un VPS, si.

L'architecture

Deux environnements sur le même VPS :

  • Production sur un premier port
  • Staging sur un second port

Caddy en reverse proxy devant, PostgreSQL en local, PM2 pour gérer les processus.

Caddy — le reverse proxy qui simplifie tout

Caddy remplace Nginx pour une raison : le TLS automatique. Pas de Let's Encrypt à configurer, pas de cron pour renouveler les certificats :

monapp.example.com {
  reverse_proxy localhost:3000
}

staging.monapp.example.com {
  reverse_proxy localhost:3001
}

HTTPS, HTTP/2, compression — tout est automatique.

PM2 — garder l'app en vie

PM2 gère les processus Node.js : restart automatique en cas de crash, logs centralisés, monitoring mémoire.

pm2 logs monapp # Logs en temps réel pm2 restart monapp # Restart propre pm2 status # Vue d'ensemble

CI/CD — GitHub webhook + script bash

Le déploiement est déclenché par un webhook GitHub. Quand je push sur main :

git pull origin main pnpm install --frozen-lockfile pnpm build npx prisma migrate deploy pm2 restart monapp

5 commandes. Le déploiement prend environ 30 secondes.

Je push sur dev, je vérifie sur le staging, puis je merge dans main pour la prod.

PostgreSQL en local

PostgreSQL tourne directement sur le VPS. Pas de latence réseau, pas de cold start, pas de limites de connexions artificielles.

Les migrations sont gérées par Prisma. Un cron job quotidien dump la base et l'envoie sur un stockage distant pour les backups.

Le setup initial

Un script bash installe tout depuis zéro : Node.js, PostgreSQL, PM2, crée les bases et configure les services. Un nouveau VPS est opérationnel en 10 minutes.

Ce que j'aurais fait différemment

Docker ? Pour un projet solo sur un seul VPS, Docker ajoute de la complexité sans bénéfice réel. Si je devais scaler horizontalement, Docker Compose serait le bon choix.

GitHub Actions pour le deploy ? Le webhook est plus simple et plus rapide. Mais GitHub Actions serait plus robuste pour un projet avec plus de contributeurs.

Le résultat

  • Coût : quelques euros par mois pour tout
  • Performance : temps de réponse inférieur à 50ms (pas de cold start)
  • Fiabilité : PM2 restart automatique, backups quotidiens
  • Déploiement : push sur main, en prod en 30 secondes

Pour qui c'est fait ?

Ce setup est idéal si vous avez un projet avec une base de données, si vous voulez un coût fixe et prévisible, ou si vous avez besoin de connexions persistantes.

Si vous faites un site Next.js sans backend custom, Vercel reste imbattable. Mais pour un SaaS complet avec DB, chiffrement et sync temps réel, un VPS bien configuré reste la solution la plus simple et la moins chère.