Où faire tourner votre application ? Du VPS au serverless
Point de théorie · à lire après avoir choisi votre hébergeur, pour comprendre ce que vous avez choisi
Slides du cours
- deck5-hebergement.pdfPDF — les slides du point de théorie
Au premier cours, vous avez comparé des hébergeurs et vous en avez choisi un pour votre chat. Ce chapitre explique ce qui se cache derrière ce choix. Un hébergeur n'est pas qu'un prix et un quota : c'est un partage des tâches entre vous et lui. Selon la formule, vous installez tout vous-même ou vous ne touchez à rien, et chaque formule a ses bugs typiques. Les connaître vous évite de découvrir en semaine 5 que votre base de données a été effacée ou que vos WebSockets ne passeront jamais.
À la fin de ce chapitre, vous serez capables de :
- situer un hébergeur sur l'échelle qui va du serveur nu aux fonctions à la demande, et dire ce que vous gérez vous-même à chaque marche ;
- décrire ce qu'un serveur classique contient et pourquoi chaque couche est là ;
- expliquer ce qu'est le serverless, comment une fonction vit et meurt, et pourquoi elle n'a pas de mémoire ;
- reconnaître les trois pièges du serverless dans votre propre code ;
- justifier le choix d'hébergement de votre projet avec des arguments techniques, dans votre rapport et à l'oral.
1. Une même application, quatre façons de la faire tourner
Prenez votre chat. Un backend en Laravel, Django ou Node, une base de données, des WebSockets pour le temps réel. Pour le rendre accessible sur une URL publique, il faut une machine quelque part qui exécute ce code. La question de l'hébergement, c'est : qui s'occupe de cette machine, et jusqu'où ?
| Formule | Exemples | Ce que vous gérez | Ce que l'hébergeur gère |
|---|---|---|---|
| VPS nu | Hetzner, OVH, DigitalOcean | Tout : système, sécurité, runtime, base, HTTPS, déploiement, sauvegardes | La machine virtuelle et le réseau |
| VPS + panneau | Coolify ou Dokploy installé sur le VPS | Le VPS (mises à jour, sécurité) et vos réglages dans le panneau | Rien de plus, mais le panneau automatise déploiement, HTTPS, bases |
| PaaS managé | Render, Railway, Fly.io, Laravel Cloud | Votre code, vos variables d'environnement | Système, runtime, HTTPS, déploiement, base, sauvegardes |
| Serverless | Vercel, Netlify, Cloudflare Workers | Vos fonctions et vos pages | Tout le reste, y compris le nombre de machines |
Un VPS (Virtual Private Server) est une machine virtuelle louée, allumée en permanence, sur laquelle vous avez tous les droits. Un PaaS (Platform as a Service) est un service qui prend votre code et le fait tourner sans que vous voyiez la machine. Le serverless va un cran plus loin : il n'y a plus d'application qui tourne en continu, seulement des fonctions lancées à chaque requête.
Plus vous montez dans le tableau, plus vous avez de contrôle et de travail. Plus vous descendez, moins vous avez de travail et plus vous acceptez les règles de la plateforme. Il n'y a pas de bonne marche. Il y a la marche qui correspond à votre projet, à votre budget et à vos compétences. La suite du chapitre parcourt l'échelle de haut en bas.
2. Le VPS de l'intérieur
Ce qu'il y a dans un serveur
Sur votre PC, php artisan serve, python manage.py runserver ou node server.js suffit. Sur un serveur public, ce serveur de développement ne convient plus : il n'est pas prévu pour tenir la charge, il ne fait pas de HTTPS et il meurt avec votre terminal. Un serveur de production empile six couches.
| Couche | Exemples | Ce qu'elle fait | Sans elle |
|---|---|---|---|
| Système et pare-feu | Ubuntu, ufw, fail2ban |
Ferme tous les ports sauf 22, 80 et 443, bloque les tentatives de connexion répétées | Un serveur exposé sans pare-feu reçoit des attaques par mot de passe dès la première heure |
| Runtime | PHP-FPM, Python, Node 24 | Exécute votre code | Rien ne tourne |
| Gestionnaire de processus | systemd, PM2, Gunicorn |
Lance l'application au démarrage, la relance si elle plante | Un crash à 3h du matin, et le site reste mort jusqu'à ce que quelqu'un le remarque |
| Reverse proxy | Caddy, Nginx | Reçoit le trafic sur les ports 80 et 443, gère le certificat HTTPS, le transmet à votre application sur son port interne | Pas de HTTPS, une application exposée directement |
| Base de données | MySQL, PostgreSQL | Stocke vos données sur le disque | Vos messages disparaissent au redémarrage |
| Sauvegardes | mysqldump + un cron, ou un outil dédié |
Copie la base ailleurs chaque nuit | Une mauvaise commande, et sept semaines de données sont perdues |
Un reverse proxy est un serveur qui se place devant votre application. Le navigateur lui parle en HTTPS sur le port 443, et lui parle à votre application en HTTP sur un port interne, par exemple 3000. C'est lui qui porte le certificat.
À quoi ressemble l'installation
Voici le strict minimum pour une application Node sur un VPS Ubuntu neuf. Chaque ligne correspond à une couche du tableau.
# Système à jour et pare-feu : seuls SSH, HTTP et HTTPS passent
sudo apt update && sudo apt upgrade -y
sudo ufw allow 22 && sudo ufw allow 80 && sudo ufw allow 443
sudo ufw enable
# Runtime : Node 24 LTS
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs
# Base de données
sudo apt install -y postgresql
# Reverse proxy avec HTTPS automatique
sudo apt install -y caddy
Le fichier /etc/caddy/Caddyfile tient en trois lignes. Caddy obtient et renouvelle le certificat HTTPS tout seul, ce qui explique qu'on le préfère à Nginx pour un premier serveur :
chat.exemple.be {
reverse_proxy localhost:3000
}
Reste à lancer l'application et à la faire survivre aux redémarrages. Un service systemd décrit comment la démarrer, avec quel utilisateur et quoi faire si elle plante :
# /etc/systemd/system/chat.service
[Unit]
Description=Chat 5IDEV
After=network.target postgresql.service
[Service]
User=chat
WorkingDirectory=/srv/chat
EnvironmentFile=/srv/chat/.env
ExecStart=/usr/bin/node server.js
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now chat
Pour Laravel, remplacez le runtime par PHP-FPM et le service par une configuration Caddy qui exécute PHP ; pour Django, le service lance Gunicorn au lieu de node. Le schéma est le même : un pare-feu, un runtime, un processus surveillé, un proxy, une base.
Ce que ce script ne montre pas, c'est le temps. Comptez une soirée pour le faire marcher la première fois, et une heure par mois ensuite : mises à jour de sécurité, renouvellement d'une clé SSH, disque plein à cause des logs, mise à jour de Node. Sur un VPS, la maintenance est votre travail, et personne ne vous préviendra si vous l'oubliez.
Ce que ça vous donne
En échange de ce travail, le VPS vous donne tout ce que les autres formules limitent :
- Un processus qui reste allumé. Une variable en mémoire garde sa valeur d'une requête à l'autre. Une connexion WebSocket reste ouverte des heures. Une tâche peut tourner toute la nuit.
- Un disque. Vous écrivez des fichiers où vous voulez, la base est à côté de l'application, sans limite de taille autre que le disque.
- Un prix fixe. Entre 4 et 10 € par mois pour une petite machine, quel que soit le trafic. Zéro surprise sur la facture.
- Le contrôle. Vous pouvez installer n'importe quoi, lire n'importe quel log, brancher n'importe quel outil.
Pour un chat en temps réel, ce sont exactement les propriétés dont vous avez besoin. Retenez-le pour la partie 5.
Coolify et Dokploy : le VPS avec le confort d'un PaaS
Le chapitre CI/CD vous l'a présenté : sur un VPS, vous pouvez installer un panneau de déploiement comme Coolify ou Dokploy. C'est une application web qui tourne sur votre serveur et qui fait pour vous ce que le script ci-dessus fait à la main. Vous lui donnez l'adresse de votre dépôt GitHub, elle détecte votre stack, construit l'application dans un conteneur, obtient le certificat HTTPS, crée une base de données et redéploie à chaque push sur main.
Un conteneur est un paquet qui contient votre application et tout ce dont elle a besoin pour tourner, isolé du reste du serveur. C'est l'unité de déploiement de Coolify, de Dokploy, mais aussi de Fly.io ou de Cloud Run : la même image tourne partout de la même façon.
Ce que le panneau ne fait pas : il ne met pas à jour le système, il ne surveille pas le disque, il ne vous protège pas d'une mauvaise commande. La machine reste la vôtre. Vous gardez le prix fixe et le contrôle, vous perdez la moitié de la maintenance.
3. Quand un serveur ne suffit plus
Imaginez que votre chat marche et que le trafic monte. Un petit VPS tient sans effort quelques centaines d'utilisateurs simultanés sur une application bien écrite, et une vingtaine sur une application qui fait cinquante requêtes SQL par page. Le jour où la machine sature, deux voies s'ouvrent.
Le scaling vertical consiste à louer une machine plus grosse. Plus de mémoire, plus de processeurs, même configuration. C'est simple et sans changement dans le code, mais le prix grimpe vite et il existe un plafond : à un moment, il n'y a plus de machine plus grosse.
Le scaling horizontal consiste à multiplier les machines et à placer devant elles un répartiteur de charge (load balancer), qui distribue chaque requête à l'un des serveurs et écarte ceux qui ne répondent plus. Si un serveur tombe, le site reste en ligne. Mais le code doit changer, parce que deux requêtes du même utilisateur peuvent atterrir sur deux machines différentes.
Le premier symptôme, ce sont les sessions. Une session stockée en mémoire sur le serveur A n'existe pas sur le serveur B : l'utilisateur est déconnecté une requête sur deux. La solution est de sortir la session de la machine, dans un magasin partagé comme Redis, une base clé-valeur en mémoire :
// Session en mémoire : ne survit pas au passage sur un autre serveur
app.use(session({ store: new MemoryStore() }));
// Session dans Redis : la même pour tous les serveurs
app.use(session({ store: new RedisStore({ client: redis }) }));
Le même raisonnement vaut pour les fichiers envoyés par les utilisateurs, pour le cache et pour les WebSockets, dont les connexions se répartissent elles aussi entre serveurs. Dès qu'il y a plusieurs machines, tout état doit vivre en dehors d'elles. Retenez cette phrase : c'est aussi la règle du serverless, poussée à l'extrême.
Le scaling horizontal a un coût : trois serveurs, un répartiteur, un Redis, et les compétences pour faire tenir l'ensemble. La plupart des équipes ne veulent pas de ce travail. C'est précisément ce que les PaaS et le serverless vendent : le scaling sans l'infrastructure.
4. Le serverless, vraiment
Un serveur qui n'existe qu'au moment de la requête
Le mot est trompeur. Il y a toujours des serveurs, mais ce ne sont plus les vôtres, et votre application ne tourne plus en continu dessus. Vous déployez des fonctions. Quand une requête arrive, la plateforme démarre une instance de la fonction, lui passe la requête, renvoie la réponse, puis détruit l'instance au bout de quelques minutes sans trafic. Vous payez le temps d'exécution, pas le temps d'allumage.
Un VPS est un restaurant dont la cuisine tourne jour et nuit. Vous payez le cuisinier même à 4 h du matin, quand la salle est vide. Le serverless est un food truck : il ne vient que quand quelqu'un commande, et il repart ensuite. À midi, la plateforme envoie dix food trucks ; à 4 h, aucun. C'est ce que fait Vercel quand mille utilisateurs arrivent en même temps : mille instances, sans que vous ayez rien configuré.
Dans ce chapitre, Vercel sert d'exemple parce que c'est la plateforme que vous rencontrerez le plus souvent avec Next.js, Nuxt ou SvelteKit. Netlify fonctionne de la même façon. Cloudflare Workers pousse l'idée plus loin, avec des fonctions plus légères qui démarrent en quelques millisecondes dans des centaines de villes. Le modèle est le même partout.
Deux temps : le build et la requête
Sur un VPS, vous lancez l'application et elle attend les requêtes. En serverless, le déploiement se coupe en deux moments bien distincts.
Le build se produit une fois, à chaque push. La plateforme installe les dépendances, compile le projet, produit d'un côté des fichiers statiques (HTML, CSS, JavaScript, images) envoyés sur un CDN, un réseau de serveurs répartis dans le monde qui servent ces fichiers au plus près du visiteur, et de l'autre des fonctions prêtes à être lancées. Une page qui ne dépend d'aucune donnée est construite ici, une fois pour toutes.
La requête se produit à chaque visite. Une page statique vient du CDN en quelques millisecondes. Un appel d'API réveille une fonction, qui interroge la base et répond. Rien ne tourne entre deux requêtes.
À quoi ressemble une fonction
Voici la route qui liste et crée les messages d'une conversation, en Next.js. Le fichier app/api/messages/route.js devient une fonction serverless au déploiement sur Vercel :
import { sql } from "./db"; // client de base de données, voir plus bas
// Chaque export nommé d'après une méthode HTTP devient un point d'entrée
export async function GET() {
const messages = await sql`SELECT * FROM messages ORDER BY id DESC LIMIT 50`;
return Response.json(messages);
}
export async function POST(request) {
const { body } = await request.json();
if (!body?.trim()) {
return Response.json({ error: "Le message ne peut pas être vide" }, { status: 422 });
}
const [message] = await sql`INSERT INTO messages (body) VALUES (${body}) RETURNING *`;
return Response.json(message, { status: 201 });
}
Comparez avec le serveur Express du chapitre CI/CD : pas de app.listen(), pas de port, pas de processus qui attend. Le fichier exporte des fonctions, et la plateforme décide quand les appeler. Vercel accepte aussi des fonctions Python (api/messages.py, avec Flask ou FastAPI) et, pour Laravel, l'équivalent s'appelle Laravel Cloud : votre application dort quand personne ne l'utilise et se réveille à la première requête, base de données comprise.
Le cycle de vie : cold start, warm start, disparition
Quand une requête arrive et qu'aucune instance n'existe, la plateforme en crée une : elle réserve de la mémoire, charge votre code et ses dépendances, puis exécute la fonction. C'est le démarrage à froid (cold start), et il coûte entre quelques dizaines et quelques centaines de millisecondes selon la taille de votre code. Si une deuxième requête arrive juste après, l'instance est encore là et répond en quelques millisecondes : démarrage à chaud (warm start). Après quelques minutes sans requête, l'instance est détruite. La suivante repartira à froid.
Trois conséquences pratiques :
- La première visite après une période calme est plus lente. Un site peu fréquenté a un cold start sur presque chaque visite.
- Vous ne pouvez pas savoir si deux requêtes tomberont sur la même instance. Deux visiteurs simultanés peuvent avoir deux instances, ou une seule.
- Tout ce que vous mettez en mémoire dans une instance disparaît avec elle.
Les limites, en chiffres
Une fonction n'est pas un serveur allégé. Elle vit dans un cadre strict, que la plateforme impose pour pouvoir en lancer des milliers en parallèle. Chez Vercel, en septembre 2026 :
| Limite | Plan gratuit (Hobby) | Plan Pro | Ce que ça change pour vous |
|---|---|---|---|
| Durée maximale d'une exécution | 5 minutes | 13 minutes | Un export PDF de 20 minutes est impossible dans une fonction |
| Mémoire | 2 Go | jusqu'à 4 Go | Une conversion vidéo ne rentre pas |
| Corps d'une requête ou d'une réponse | 4,5 Mo | 4,5 Mo | Un upload de photo passe, une vidéo non |
| Disque | /tmp seulement, effacé avec l'instance |
idem | Rien ne s'écrit durablement sur le disque |
| Facturation | gratuit dans les quotas | au temps de CPU actif et à la mémoire réservée | Le prix suit le trafic, dans les deux sens |
Ces chiffres changent chaque année, toujours à la hausse. Il y a deux ans, la limite gratuite était de 10 secondes. Ce qui ne change pas, c'est la nature de ces limites : une fonction est faite pour répondre vite et disparaître.
5. Les trois pièges du serverless
Les trois erreurs qui suivent viennent toutes du même réflexe : écrire du code de VPS dans une fonction. Chacune a sa solution, et cette solution est toujours la même que celle du scaling horizontal : sortir l'état de la machine.
Piège n°1 : garder quelque chose en mémoire
let visites = 0; // vit dans l'instance, pas dans l'application
export async function GET() {
visites++;
return Response.json({ visites });
}
Sur un VPS, ce compteur affiche 1, 2, 3, 4. Sur Vercel, il affiche 1, 2, 1, 3, 1, 1. Chaque nouvelle instance repart de zéro, et plusieurs instances vivent en parallèle. Le même problème touche un cache maison, une liste d'utilisateurs connectés, une session stockée dans une variable.
La solution est d'écrire l'état dans un service qui survit aux instances. Pour un compteur ou une session, Redis. Vercel ne propose plus son propre Redis depuis fin 2024 : on en installe un depuis sa place de marché, chez Upstash par exemple, et on l'appelle en HTTP :
import { Redis } from "@upstash/redis";
const redis = Redis.fromEnv(); // lit l'URL et le jeton dans les variables d'environnement
export async function GET() {
const visites = await redis.incr("visites");
return Response.json({ visites });
}
Attention
Une connexion à une base de données est aussi un état. Sur un VPS, votre application ouvre dix connexions au démarrage et les réutilise. En serverless, mille instances ouvriraient mille connexions et feraient tomber la base. Les bases pensées pour le serverless (Neon, PlanetScale, Supabase) placent un pooler devant elles, un intermédiaire qui partage un petit nombre de connexions réelles entre toutes les fonctions. Utilisez l'URL de connexion « pooled » qu'elles fournissent, jamais l'URL directe.
Piège n°2 : écrire un fichier sur le disque
import { writeFile } from "node:fs/promises";
export async function POST(request) {
const photo = await request.arrayBuffer();
await writeFile("./uploads/photo.jpg", Buffer.from(photo)); // ne persiste pas
return Response.json({ ok: true });
}
L'écriture réussit peut-être dans /tmp, puis le fichier disparaît avec l'instance, et une autre instance ne le verra jamais. Les fichiers envoyés par vos utilisateurs vont dans un stockage d'objets : Vercel Blob, Cloudflare R2, Amazon S3. Vous y envoyez le fichier, vous recevez une URL, vous stockez l'URL en base :
import { put } from "@vercel/blob";
export async function POST(request) {
const photo = await request.arrayBuffer();
const blob = await put("photos/photo.jpg", photo, { access: "public" });
return Response.json({ url: blob.url });
}
Piège n°3 : lancer un traitement long
Convertir une vidéo, générer un PDF de mille pages, envoyer dix mille e-mails : tout ce qui dépasse la durée maximale d'une fonction est coupé net, avec une erreur 504 pour l'utilisateur. Et même sous la limite, faire attendre un visiteur trois minutes sur une requête HTTP est une mauvaise idée sur n'importe quel hébergeur.
La solution est une file de tâches. La fonction reçoit la demande, dépose une tâche dans la file et répond tout de suite « c'est en cours ». Un worker, un programme qui reste allumé sur un VPS ou chez un service dédié, prend les tâches une par une et fait le travail, sans limite de durée. Quand il a fini, il prévient l'application. Avec Trigger.dev, un service de files pensé pour Vercel, la tâche s'écrit comme une fonction ordinaire :
// trigger/transcode.js : tourne chez Trigger.dev, pas dans la fonction Vercel
import { task } from "@trigger.dev/sdk";
export const transcode = task({
id: "transcode-video",
run: async ({ videoUrl }) => {
await convertir(videoUrl); // vingt minutes, personne n'attend
},
});
// app/api/videos/route.js : la fonction Vercel ne fait que déposer la tâche
import { transcode } from "@/trigger/transcode";
export async function POST(request) {
const { videoUrl } = await request.json();
const run = await transcode.trigger({ videoUrl });
return Response.json({ runId: run.id, status: "en cours" }, { status: 202 });
}
Laravel a ses queues et ses workers depuis toujours, Django a Celery : si vous êtes sur un VPS ou un PaaS, vous avez déjà ce mécanisme sous la main, et la même règle s'applique. Un traitement long ne se fait jamais dans la requête.
Note
Les WebSockets sont un quatrième cas du même problème. Une connexion WebSocket reste ouverte pendant des heures, et une fonction est faite pour vivre quelques secondes. Vercel expérimente un support depuis 2026, mais la pratique courante reste de confier le temps réel à un service dédié (Pusher, Ably) ou à un serveur qui reste allumé. Pour un chat, c'est la question qui décide de tout.
6. Choisir, pour de vrai
Quatre questions
Vous avez maintenant tout ce qu'il faut pour relire la grille d'hébergement que vous avez remplie au premier cours. Quatre questions suffisent à écarter les mauvaises options.
- Votre application garde-t-elle une connexion ouverte ? WebSockets, flux en continu, jeu en ligne. Si oui, il vous faut un processus qui reste allumé : VPS, avec ou sans panneau, ou un PaaS qui accepte les connexions longues. Le serverless pur est écarté, sauf à déléguer le temps réel à un service tiers.
- Avez-vous des traitements longs ou des fichiers à écrire ? Si oui, prévoyez un worker et un stockage d'objets, quelle que soit la formule. Sur un VPS, c'est votre disque et un worker à côté. En serverless, c'est une file de tâches et un Blob.
- Votre trafic est-il prévisible ? Un projet étudiant, un outil interne, un site à trafic constant : le prix fixe du VPS ou d'un petit PaaS est imbattable. Un lancement public avec des pics inconnus : le serverless absorbe les pics sans que vous ayez à dimensionner quoi que ce soit, et la facture suit.
- Qui fera la maintenance ? Si personne dans l'équipe n'a envie de passer une heure par mois dans un terminal SSH, prenez un PaaS ou un VPS avec Coolify. Un VPS nu sans maintenance devient une machine compromise en quelques mois.
Par type de projet
| Projet | Formule qui convient | Pourquoi |
|---|---|---|
| Site vitrine, blog, documentation | Serverless ou hébergement statique | Pages construites au build, servies par le CDN, coût nul |
| Application web classique, trafic modéré | PaaS, ou VPS avec Coolify | Un processus allumé, un prix fixe, peu de maintenance |
| Chat, jeu, tableau collaboratif en temps réel | VPS ou PaaS avec connexions longues | Les WebSockets ont besoin d'un processus qui dure |
| API publique aux pics imprévisibles | Serverless | Mille instances à midi, zéro la nuit, sans configuration |
| Traitements lourds : vidéo, PDF, données | Hybride : serverless ou PaaS devant, workers derrière | La requête reste courte, le travail se fait ailleurs |
| Application interne, données sensibles | VPS | Contrôle total sur la machine et sur l'emplacement des données |
Ce que ça donne pour votre chat
Votre Projet 1 coche la case du temps réel. C'est pour cela que l'activité du premier cours vous demandait de vérifier les WebSockets et la persistance de la base avant tout le reste. Un groupe sur Render ou Railway a un processus allumé et peut ouvrir des WebSockets ; il doit surveiller la mise en veille du plan gratuit, qui endort l'application après un quart d'heure sans trafic et la réveille en une bonne minute, et la durée de vie de la base gratuite. Un groupe sur un VPS avec Coolify a tout ce qu'il faut et paie un prix fixe, en échange d'une machine à tenir à jour. Un groupe sur Vercel peut y mettre le front et l'API, mais doit confier le temps réel à un service tiers ou à un second serveur.
Dans votre rapport, la section « hébergement » attend exactement ce raisonnement : la formule choisie, la marche de l'échelle où elle se situe, ce que vous gérez vous-même, et ce qui vous a fait écarter les autres. Trois phrases par question du point précédent suffisent.
En résumé
- Héberger, c'est partager le travail. Du VPS nu au serverless, chaque marche déplace des tâches de vous vers la plateforme, et du contrôle dans l'autre sens.
- Un VPS est un processus qui reste allumé, avec un disque et un prix fixe. Il donne tout, y compris la maintenance. Coolify ou Dokploy en enlève la moitié.
- Une fonction serverless naît à la requête et meurt après. Elle démarre à froid, ne garde rien en mémoire, n'écrit pas sur le disque et s'arrête après quelques minutes.
- Tout état vit en dehors de la machine : Redis pour les sessions et les compteurs, un stockage d'objets pour les fichiers, une file et un worker pour les traitements longs, un pooler devant la base. C'est la règle du scaling horizontal, et le serverless l'impose dès la première requête.
- Les WebSockets décident. Une connexion longue demande un processus qui dure. Pour un chat, cette question passe avant le prix.
Pour aller plus loin
- Limites des fonctions Vercel : https://vercel.com/docs/functions/limitations
- Route Handlers Next.js : https://nextjs.org/docs/app/api-reference/file-conventions/route
- Redis sur Vercel via Upstash : https://vercel.com/docs/redis · Vercel Blob : https://vercel.com/docs/vercel-blob
- Trigger.dev, tâches en arrière-plan : https://trigger.dev/docs
- Laravel Cloud : https://cloud.laravel.com/docs · Cloudflare Workers : https://developers.cloudflare.com/workers
- Coolify : https://coolify.io · Dokploy : https://dokploy.com · Caddy : https://caddyserver.com/docs
- Le plan gratuit de Render et sa mise en veille : https://render.com/docs/free