J'utilise Next.js en production depuis la version 9. Pendant longtemps, Vercel était le choix évident — déployer, oublier, passer à autre chose. Mais vers 2024, les factures ont commencé à ressembler à des paiements de voiture. Quand votre facture d'hébergement pour un site marketing dépasse vos coûts réels d'infrastructure cloud, quelque chose ne va pas. C'est là que j'ai commencé à explorer OpenNext, et après avoir migré trois applications de production hors de Vercel au cours de la dernière année, j'ai des opinions bien arrêtées.

Ce n'est pas un article « Vercel c'est mal ». Vercel est véritablement excellent. Mais ce n'est plus la seule option, et pour de nombreuses équipes, ce n'est pas la bonne. Laissez-moi vous guider dans tout ce que j'ai appris sur l'auto-hébergement de Next.js avec OpenNext — le bon, le mauvais, et l'étonnamment abordable.

Table des matières

OpenNext: Self-Host Next.js on AWS, Cloudflare, or VPS Without Vercel

Qu'est-ce qu'OpenNext et pourquoi existe-t-il

Next.js a été conçu pour s'exécuter sur Vercel. Ce n'est pas une théorie du complot — c'est l'architecture. Des fonctionnalités comme ISR (Incremental Static Regeneration), les middlewares, l'optimisation d'images et les actions serveur ont tous des implémentations spécifiques à Vercel intégrées. Quand vous essayez de faire next start sur un serveur quelconque, vous ne récupérez qu'un sous-ensemble de ce que Next.js peut faire.

OpenNext est un adaptateur open-source qui prend votre sortie de construction Next.js et la transforme en packages de déploiement qui fonctionnent sur d'autres plateformes. Il a commencé comme un projet communautaire SST axé sur AWS Lambda, mais à partir de v3 (la version majeure actuelle en 2025), il supporte plusieurs cibles de déploiement, notamment Cloudflare Workers, les serveurs Node.js traditionnels, et bien d'autres.

Voici ce qu'OpenNext gère réellement :

  • ISR et revalidation — Le système de revalidation basé sur les tags que Vercel implémente avec son infrastructure interne ? OpenNext le recréé en utilisant DynamoDB + SQS sur AWS, ou les magasins KV sur Cloudflare.
  • Optimisation d'images — Le composant <Image> de Next.js s'appuie sur une API d'optimisation. OpenNext empaquète un optimiseur basé sur Sharp ou les routes vers des solutions spécifiques à la plateforme.
  • Middleware — S'exécute à la périphérie sur Vercel. OpenNext le mappe aux CloudFront Functions, Cloudflare Workers, ou le lance in-process sur VPS.
  • Actions serveur — Support complet, acheminé via la fonction serveur appropriée.
  • Streaming et prerendering partiel — Le support s'est considérablement amélioré dans OpenNext v3.x.

Ce qu'OpenNext n'est pas

Ce n'est pas une plateforme d'hébergement. Ce n'est pas un CDN. C'est un adaptateur de construction — une couche de traduction entre la sortie de Next.js et votre infrastructure. Vous devez toujours exécuter le code quelque part.

Le paysage de l'auto-hébergement en 2025-2026

L'écosystème a explosé depuis que j'ai commencé à regarder ça. Voici où les choses en sont :

Plateforme Support OpenNext Maturité Idéal pour
AWS (via SST) Première classe Production-ready Équipes déjà sur AWS
Cloudflare Workers Adaptateur officiel Stable (quelques cas limites) Applications edge-first, optimisation des coûts
Docker/VPS Communauté + officiel Stable Déploiements simples, infrastructure existante
Kubernetes Charts Helm communautaires En maturation Entreprise, clusters K8s existants
Netlify Adaptateur intégré (propre) Production-ready Équipes engagées avec Netlify
Google Cloud Run Communauté Expérimental Boutiques GCP

Les deux chemins que j'ai personnellement testés en combat et que je peux approuver sont AWS via SST et Docker sur VPS. Cloudflare est le nouvel arrivant passionnant qui s'améliore chaque mois.

Cible de déploiement : AWS avec SST

C'est le chemin doré. SST (Serverless Stack) a le support Next.js intégré alimenté par OpenNext, et c'est là que la plupart des efforts d'ingénierie ont porté.

Aperçu de l'architecture

Quand vous déployez Next.js via SST sur AWS, voici ce qui est créé :

  • Distribution CloudFront — Votre CDN, gère les ressources statiques et le routage
  • Fonction(s) Lambda — Server-side rendering, routes API, actions serveur
  • Bucket S3 — Ressources statiques, pages prérendues, cache ISR
  • Table DynamoDB — Mappage des tags ISR pour la revalidation
  • Queue SQS — Traitement asynchrone de la revalidation
  • CloudFront Function ou Lambda@Edge — Exécution du middleware

Ça fait beaucoup. C'est vrai. Mais SST abstraite tout en environ 20 lignes de config.

Configuration SST

Voici une vraie sst.config.ts d'un de mes projets en production :

/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
  app(input) {
    return {
      name: "my-nextjs-app",
      removal: input.stage === "production" ? "retain" : "remove",
      home: "aws",
      providers: {
        aws: {
          region: "us-east-1",
        },
      },
    };
  },
  async run() {
    const site = new sst.aws.Nextjs("Site", {
      domain: {
        name: "myapp.com",
        dns: sst.aws.dns(),
      },
      warm: 5, // keep 5 Lambda instances warm
      memory: "1024 MB",
      environment: {
        DATABASE_URL: process.env.DATABASE_URL!,
        NEXT_PUBLIC_API_URL: "https://api.myapp.com",
      },
    });

    return {
      url: site.url,
    };
  },
});

Puis déployez :

npx sst deploy --stage production

Le premier déploiement prend 8-12 minutes (propagation de la distribution CloudFront). Les déploiements ultérieurs prennent 2-4 minutes.

Considérations Lambda

Le plus gros piège avec l'hébergement basé sur Lambda est le cold start. Les fonctions serveur Next.js ne sont pas petites — vous regardez des bundles de 20-80MB selon vos dépendances. Les cold starts vont de 800ms à 3 secondes.

Atténuations que j'ai utilisées :

  1. Concurrence provisionnée — Le paramètre warm de SST garde les instances actives. À $0.0000041667 par GB-seconde, garder 5 instances d'une fonction de 1GB actives coûte ~$15/mois.
  2. Bundles plus petits — Auditez vos dépendances côté serveur. J'ai trouvé un projet qui importait lodash côté serveur quand nous avions seulement besoin de lodash/get. Le bundle a chuté de 68MB à 31MB.
  3. Déploiement régional — N'utilisez pas Lambda@Edge pour SSR à moins que vous n'en ayez absolument besoin. Une Lambda à région unique avec mise en cache CloudFront est bien pour 95% des applications.

OpenNext: Self-Host Next.js on AWS, Cloudflare, or VPS Without Vercel - architecture

Cible de déploiement : Cloudflare Workers

Cloudflare a fait des mouvements sérieux. Leur runtime Workers supporte maintenant suffisamment d'APIs Node.js pour que Next.js puisse réellement s'y exécuter, et l'adaptateur OpenNext Cloudflare est devenu remarquablement stable.

Configuration avec OpenNext Cloudflare

npm install @opennext/cloudflare

Ajoutez à votre wrangler.toml :

name = "my-nextjs-app"
main = ".open-next/worker.js"
compatibility_date = "2025-01-01"
compatibility_flags = ["nodejs_compat_v2"]

[assets]
directory = ".open-next/assets"
binding = "ASSETS"

[[kv_namespaces]]
binding = "NEXT_CACHE_KV"
id = "your-kv-namespace-id"

Construisez et déployez :

npx @opennext/cloudflare build
npx wrangler deploy

Les compromis Cloudflare

Avantages :

  • Pas de cold starts — Les Workers démarrent en moins de 5ms globalement
  • Edge global par défaut — Votre SSR s'exécute dans 300+ emplacements
  • Tarification absurde — $5/mois pour 10 millions de requêtes sur le plan payant

Inconvénients :

  • Limites de mémoire — 128MB en gratuit, 256MB en payant. Les grandes applications Next.js peuvent atteindre cette limite.
  • Limites de temps CPU — 30 secondes sur plan payant. Les pages SSR lourdes peuvent poser problème.
  • Lacunes de compatibilité Node.js — La plupart des choses fonctionnent, mais si vous utilisez des modules Node natifs comme sharp directement, vous aurez besoin de solutions de contournement. Cloudflare Images peut gérer l'optimisation à la place.
  • Certaines fonctionnalités Next.js ne sont pas supportées — Depuis début 2025, le support du prerendering partiel est encore expérimental sur Cloudflare.

Pour les sites riches en contenu et les pages marketing, Cloudflare Workers est incroyablement convaincant. Pour les applications web complexes avec une logique serveur lourde, j'inclinerais toujours vers AWS ou Docker.

Cible de déploiement : VPS avec Docker

Parfois, vous voulez juste un serveur. Pas de fonctions Lambda, pas de runtime edge, pas de diagramme d'architecture à 47 services. Une boîte qui exécute votre code. Je respecte ça.

Le Dockerfile

Voici le Dockerfile de production que j'utilise. C'est multi-étages, optimisé, et ça fonctionne vraiment :

# Étape 1 : Dépendances
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Étape 2 : Construction
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production

RUN corepack enable pnpm && pnpm build

# Étape 3 : Production
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

Critique : vous avez besoin de output: 'standalone' dans votre next.config.js :

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
};

module.exports = nextConfig;

Recommandations VPS

J'ai exécuté cette configuration sur plusieurs fournisseurs :

Fournisseur Spec Coût mensuel Notes
Hetzner CAX21 4 vCPU ARM, 8GB RAM €7,49 (~$8) Meilleur rapport qualité-prix, datacenters EU
DigitalOcean Droplet 2 vCPU, 4GB RAM $24 Bonne couverture US
Fly.io (machine) 2 vCPU, 4GB RAM ~$30 Auto-scaling, régions globales
Railway Basé sur l'utilisation $5-50 Configuration la plus facile, DX style Vercel
AWS EC2 t4g.medium 2 vCPU, 4GB RAM ~$25 Déjà sur AWS

Pour un déploiement Docker simple, Hetzner offre un rapport qualité-prix absurdement bon. J'exécute une application Next.js servant plus de 2M+ vues de page/mois sur une instance ARM Hetzner à €7,49 derrière le tier CDN gratuit de Cloudflare. Le serveur respire à peine.

Ce que vous perdez avec Docker/VPS

Soyons honnête sur ce que next start sur VPS ne vous donne pas comparé à Vercel ou la configuration SST :

  • La revalidation ISR est basique — Cache du système de fichiers uniquement. Pas de cache distribué entre plusieurs instances. Si vous exécutez un serveur unique, c'est bien. Plusieurs serveurs ? Vous avez besoin de Redis ou une couche de cache partagée.
  • Pas de middleware edge — Le middleware s'exécute in-process, ce qui est totalement bien pour la plupart des cas d'usage.
  • Optimisation d'images — Fonctionne via Sharp, mais vous servez des images optimisées depuis votre origine unique. Mettez Cloudflare ou un CDN devant.
  • Pas de déploiements atomiques — Vous devez gérer les déploiements sans temps d'arrêt vous-même (Docker Compose avec health checks, ou un reverse proxy comme Caddy/Traefik).

Pour la plupart des applications chez Social Animal, en particulier les builds headless CMS que nous faisons dans nos travaux de développement headless CMS, un VPS unique avec un CDN devant est parfaitement adéquat.

Comparaison des coûts : Vercel vs Auto-hébergé

Parlons argent. C'est basé sur des données de facturation réelles d'une application Next.js faisant ~5M requêtes/mois avec ISR, optimisation d'images, et server-side rendering modéré.

Facteur de coût Vercel Pro Vercel Enterprise AWS/SST Cloudflare Hetzner VPS
Plateforme de base $20/utilisateur/mois Custom (~$3k+/mois) $0 $5/mois €7,49/mois
Compute/requêtes $150-400/mois Inclus $40-80/mois $0-15/mois Inclus
Bande passante (100GB) Inclus Inclus $8,50 (CloudFront) Inclus Inclus
Optimisation d'images $50-200/mois Inclus $5-15/mois (Lambda) $5/mois (CF Images) Inclus (Sharp)
ISR/Cache Inclus Inclus $2-5/mois (DynamoDB) $0-5/mois (KV) $0
Total estimé $300-700/mois $3,000+/mois $55-110/mois $10-25/mois $8-15/mois

Ces chiffres Vercel ne sont pas hypothétiques. J'ai vu les factures. La tarification par siège, les frais supplémentaires d'exécution de fonctions et les frais de bande passante sur le tier Pro s'ajoutent rapidement pour les équipes de 5+.

Les chiffres AWS/SST supposent un trafic modéré avec concurrence provisionnée. La tarification de Cloudflare est véritablement sauvage — il est difficile de dépenser de l'argent réel là-bas à moins de faire quelque chose d'exotique.

Quand quitter Vercel

Ne partez pas juste parce que vous pouvez. Partez parce que vous devriez. Voici mon cadre :

Restez sur Vercel si :

  • Votre équipe est petite (1-3 développeurs) et le temps des développeurs est votre ressource la plus chère
  • Vous dépensez moins de $100/mois sur Vercel
  • Personne n'aime le travail d'infrastructure
  • Vous itérez rapidement et avez besoin de prévisualisations instantanées pour chaque PR
  • Vous utilisez des fonctionnalités spécifiques à Vercel comme Analytics, Speed Insights, ou les intégrations Vercel AI SDK

Quittez Vercel si :

  • La facture mensuelle dépasse $500 et augmente
  • Vous avez besoin d'infrastructure dans des régions spécifiques pour la conformité (RGPD, résidence des données)
  • Vous exécutez déjà une infrastructure AWS/GCP/Cloudflare significative
  • Les cold starts sur serverless sont inacceptables pour votre cas d'usage
  • Vous avez besoin de stratégies de cache personnalisées qui ne rentrent pas dans le modèle de Vercel
  • Vous avez atteint les limites de taille de fonction ou de temps d'exécution de Vercel

Envisagez sérieusement de partir si :

  • Vous êtes sur tarification Vercel Enterprise et le renouvellement de contrat vient d'arriver
  • Votre application est surtout statique/ISR et vous payez des prix SSR dynamiques
  • Vous voulez exécuter votre frontend à côté de votre backend dans la même infrastructure

Le playbook de migration

J'ai fait ça trois fois maintenant. Voici le processus que je suis, affiné par une expérience douloureuse.

Étape 1 : Auditez vos fonctionnalités Next.js

Avant de toucher à quoi que ce soit, cataloguez quelles fonctionnalités Next.js vous utilisez réellement :

# Trouvez les middlewares
find . -name "middleware.ts" -o -name "middleware.js"

# Trouvez les routes API
find ./app -name "route.ts" -o -name "route.js" | head -20

# Vérifiez ISR
grep -r "revalidate" ./app --include="*.ts" --include="*.tsx" | head -20

# Vérifiez les actions serveur
grep -r "use server" ./app --include="*.ts" --include="*.tsx" | head -20

# Vérifiez next.config pour les fonctionnalités spéciales
cat next.config.js

Étape 2 : Choisissez votre cible

Selon l'audit :

  • ISR lourd + middleware + optimisation d'images → AWS/SST
  • SSR simple + site de contenu → Cloudflare ou VPS
  • Vous avez déjà l'infrastructure Docker/K8s → VPS/Docker
  • Vous devez le faire d'ici vendredi → Docker sur Railway ou Fly.io

Si vous construisez avec Next.js ou Astro, le choix de la plateforme cible affecte considérablement les décisions d'architecture.

Étape 3 : Configurez CI/CD

Le CI/CD de Vercel est véritablement excellent. Vous le regretterez. Reproduisez-le avec GitHub Actions :

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - run: pnpm test

      # Pour SST :
      - run: npx sst deploy --stage production
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      # Pour Docker/VPS (alternative) :
      # - run: docker build -t myapp .
      # - run: docker push registry.example.com/myapp:latest
      # - run: ssh deploy@server 'cd /app && docker compose pull && docker compose up -d'

Étape 4 : Déploiements de prévisualisation

C'est la chose que les gens regrettent le plus de Vercel. Pour SST, utilisez les étapes :

# Dans votre workflow CI PR
npx sst deploy --stage pr-${{ github.event.pull_request.number }}

Pour Docker, des outils comme Coolify (auto-hébergé) ou Railway gèrent bien les déploiements de prévisualisation.

Étape 5 : Basculement DNS

Le moment réel de la migration. Je recommande toujours :

  1. Déployez sur la nouvelle infrastructure à côté de Vercel
  2. Testez complètement avec un domaine de staging
  3. Réduisez le TTL DNS à 60 secondes un jour avant
  4. Basculez le DNS pendant les heures de faible trafic
  5. Gardez le déploiement Vercel en cours pendant 48 heures comme secours
  6. Surveillez étroitement les taux d'erreur, TTFB et Core Web Vitals

Étape 6 : Démantelez Vercel

Une fois que vous êtes confiant (donnez-vous au moins une semaine), annulez l'abonnement Vercel et supprimez le projet. Ne laissez pas de projets zombie générer des frais.

Pièges courants et comment les éviter

Les variables d'environnement disparaissent. Next.js a des variables préfixées NEXT_PUBLIC_ (regroupées au moment de la construction) et des variables serveronly (disponibles à l'exécution). Sur Vercel, cette distinction est quelque peu floue. En auto-hébergé, c'est strict. Assurez-vous que toutes les variables NEXT_PUBLIC_ sont disponibles au moment de la construction dans votre CI.

Le cache ISR ne persiste pas. Sur Docker, le répertoire .next/cache doit être sur un volume persistant. Sinon, chaque redémarrage de conteneur perd vos pages en cache :

# docker-compose.yml
services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - next-cache:/app/.next/cache

volumes:
  next-cache:

Échecs d'installation Sharp. La bibliothèque d'optimisation d'images sharp a besoin de binaires spécifiques à la plateforme. Dans Docker, assurez-vous d'installer les dépendances à l'intérieur de la même architecture que votre runtime. Le Dockerfile ci-dessus gère cela en utilisant des builds multi-étages avec la même image de base.

Différences de comportement du middleware. Vercel exécute le middleware sur son réseau edge. Sur AWS/SST, il s'exécute comme une CloudFront Function (limitée à 10ms d'exécution, taille de 2MB). Le middleware complexe peut avoir besoin d'être déplacé vers la fonction serveur. J'ai dû refactoriser le middleware d'authentification à cause de ces limites.

En-têtes et rewrites manquants. Si vous vous appuyiez sur vercel.json pour les en-têtes, redirections ou rewrites, vous devez les déplacer vers la configuration next.config.js ou votre configuration CDN/reverse proxy.

Si tout cela semble accablant, c'est exactement le genre de travail d'infrastructure que nous gérons chez Social Animal. Consultez notre tarification ou contactez-nous — nous avons fait suffisamment de ces migrations pour avoir un processus affiné.

FAQ

OpenNext est-il production-ready en 2025 ? Oui. OpenNext v3.x exécute des charges de travail en production pour des milliers d'entreprises. Le chemin SST/AWS est le plus testé en combat, avec le support Cloudflare de près derrière. Je n'appellerais pas le support Google Cloud ou Kubernetes nu mature encore, mais AWS et Cloudflare sont solides.

OpenNext supporte-t-il Next.js App Router et Server Components ? Support complet. App Router, Server Components, Server Actions, streaming et Suspense fonctionnent tous. L'équipe OpenNext suit étroitement les versions de Next.js, bien qu'il y ait généralement un délai de 1-3 semaines après les versions majeures de Next.js avant que OpenNext ne rattrape.

Combien puis-je réellement économiser en quittant Vercel ? Ça dépend fortement de vos modèles d'utilisation. Pour une équipe de 5 développeurs exécutant une application à trafic modéré, j'ai vu des équipes passer de $600-800/mois sur Vercel Pro à $30-80/mois sur AWS/SST ou moins de $20/mois sur VPS. Les économies sont réelles mais il y a aussi un fardeau de maintenance supplémentaire.

Puis-je utiliser ISR (Incremental Static Regeneration) sans Vercel ? Absolument. Sur AWS/SST, ISR utilise DynamoDB pour le cache des tags et SQS pour la revalidation asynchrone — c'est complètement fonctionnel y compris la revalidation à la demande via revalidateTag() et revalidatePath(). Sur VPS, ISR fonctionne avec le cache du système de fichiers, ce qui est bien pour les déploiements à serveur unique.

Qu'en est-il des déploiements de prévisualisation de Vercel ? Puis-je reproduire ceux-ci ? Vous pouvez obtenir 80% de l'expérience. SST supporte les déploiements basés sur les étapes, donc chaque PR peut obtenir son propre stack. Coolify et des outils similaires offrent des déploiements de prévisualisation pour les configurations basées sur Docker. Ce que vous ne reproduirez pas facilement, c'est le système de commentaire visuel de Vercel et l'intégration GitHub étroite pour le statut de déploiement. La plupart des équipes trouvent le compromis acceptable.

Devrais-je utiliser OpenNext avec Cloudflare ou AWS pour un site CMS headless ? Pour les sites CMS headless riches en contenu (Sanity, Contentful, Storyblok), Cloudflare Workers est un excellent choix. Ces sites ont tendance à être lourds en ISR avec une logique côté serveur relativement légère — parfait pour le modèle de tarification de Cloudflare. Je n'irais sur AWS que si vous avez besoin de fonctionnalités que Cloudflare ne supporte pas encore ou si vous êtes déjà profondément dans l'écosystème AWS.

L'auto-hébergement de Next.js est-il plus difficile que l'auto-hébergement d'Astro ou Remix ? Honnêtement ? Oui. Next.js a la sortie de construction la plus complexe de tous les frameworks à cause de fonctionnalités comme ISR, middleware, optimisation d'images et prerendering partiel. Astro et Remix ont des histoires de déploiement beaucoup plus simples. Si vous commencez un nouveau projet et l'auto-hébergement est une priorité, envisagez Astro — c'est dramatiquement plus simple à héberger. Mais si vous êtes déjà sur Next.js, OpenNext rend la migration pratique.

Que se passe-t-il si OpenNext cesse d'être maintenu ? OpenNext est soutenu par SST et a une communauté active avec d'importants sponsors. Cela dit, c'est une préoccupation légitime pour n'importe quelle dépendance open-source. L'atténuation est que l'approche Docker/standalone (next start) fonctionne sans OpenNext du tout — vous perdez simplement certaines des fonctionnalités plus avancées comme la revalidation des tags ISR et le middleware edge. C'est une dégradation gracieuse, pas une falaise.