Anaïs Sparesotto
Déploiement · HébergementIntermédiaire≈ 2h30 · 8 chapitres

Déploiement et hébergement d'apps fullstack

Mettre une app en production : choisir la bonne plateforme, configurer DNS, gérer les environnements, monitorer, et tenir en cas de pic.

À la fin du cours, tu sais

  • Comprendre l'architecture d'une app fullstack en prod
  • Choisir la bonne plateforme selon ta stack et ton trafic
  • Configurer un domaine, du HTTPS et des sous-domaines
  • Gérer 3 environnements (dev, staging, prod) sans fuiter de secrets
  • Conteneuriser une app avec Docker multi-stage
  • Mettre en place observabilité (logs, Sentry, uptime)

Prérequis

  • Avoir une app fullstack à déployer (Next.js, Express + DB)
  • Notions Git/GitHub, CI (cours « Tuto CI pour GitHub » recommandé)

Chapitre 1

Pourquoi déployer hors de ta machine

Ton localhost:3000 n'existe que pour toi. Déployer, c'est rendre l'app accessible, fiable, observable et partageable.

  • Disponibilité : 24/7, sans dépendre que ton laptop reste allumé
  • Scalabilité : encaisser plus d'un·e utilisateur·ice à la fois
  • Sécurité : HTTPS, isolation réseau, mises à jour automatiques
  • Collaboration : partager une URL de staging à un client ou un PO
  • Mesure : sans prod, pas de vraies métriques d'usage

Déploie tôt

Le réflexe gagnant : déploie une page « Hello world » en prod dès le jour 1 du projet. Tu identifies les frictions DNS, HTTPS, env vars, build avant qu'elles te bloquent au moment critique.

Chapitre 2

Anatomie d'une app fullstack en prod

Comprendre ce que tu déploies avant de choisir où le déployer.

  • Frontend : statique (HTML/CSS/JS), ou rendu serveur (SSR) avec Next.js, Remix, Astro
  • Backend : API REST/GraphQL, jobs cron, workers de file d'attente
  • Base de données : Postgres, MySQL, MongoDB. Managées en prod (Neon, Supabase, PlanetScale...)
  • Cache : Redis pour sessions, rate limiting, données chaudes
  • Storage : S3, R2, Supabase Storage pour fichiers et images
  • Edge functions : exécution proche de l'utilisateur·ice (CDN)

Le schéma de référence

Utilisateur·ice
       │
       ▼
[ CDN / Edge ]  ← cache statique + edge functions
       │
       ▼
[ Frontend SSR ]  ← Next.js, Remix
       │
       ▼
[ API / Backend ]  ← routes API, jobs
       │
   ┌───┴───┐
   ▼       ▼
[ DB ]  [ Redis ]
   │
   └── [ Object Storage / S3 ]

Chapitre 3

Choisir sa plateforme en 2025

Le bon outil dépend de ta stack, de ton trafic, et de ton budget. Voici les options qui marchent vraiment.

Plateformes recommandées

  • Vercel : roi du Next.js, preview deploys automatiques, edge functions. Gratuit pour usage perso, premium au-delà.
  • Netlify : très bon pour Astro, Remix, sites statiques. Edge functions.
  • Railway : fullstack simple, DB Postgres incluse en quelques clics, idéal MVP
  • Fly.io : containers proches des users, multi-régions, supporte WebSockets et long-running tâches
  • Render : alternative équilibrée, web service + DB + cron jobs dans une seule interface
  • AWS Amplify / GCP Cloud Run : quand tu scales sérieusement (10k+ users actifs)

Heroku, encore vivant ?

Heroku reste utilisable mais plus de plan gratuit depuis 2022 et les tarifs ne sont plus compétitifs. Pour une migration, regarde Railway ou Fly.io en premier.

Critères de choix rapides

  • App Next.js et tu veux zéro config → Vercel
  • App Node/Python + Postgres pour un MVP → Railway
  • App qui a besoin de WebSockets ou de tâches longues → Fly.io
  • Tu veux du multi-services dans une même UI → Render
  • Tu scales à des millions de requêtes → AWS / GCP
Exemple fly.toml minimal
app = "mon-api"
primary_region = "cdg"   # Paris

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  min_machines_running = 0

Chapitre 4

DNS, domaines et certificats

Une fois déployé, il te faut une vraie URL. Quelques notions de DNS pour ne pas paniquer.

Acheter son domaine

  • Cloudflare Registrar : prix coûtant, recommandé en 2025
  • OVH : registrar français, bonne référence
  • Namecheap : alternative connue, interface ok
  • Évite GoDaddy (pratiques commerciales agressives) et Google Domains (racheté par Squarespace, friction)

Les enregistrements DNS principaux

  • A : pointe un nom de domaine vers une IPv4
  • AAAA : pareil mais IPv6
  • CNAME : pointe vers un autre nom de domaine (sous-domaines)
  • MX : pour le mail (Google Workspace, Mailgun...)
  • TXT : vérification de propriété, SPF/DKIM/DMARC pour le mail
Exemple d'une zone DNS pour un site sur Vercel
Type    Nom              Valeur
A       @                76.76.21.21
CNAME   www              cname.vercel-dns.com
CNAME   staging          cname.vercel-dns.com
TXT     @                v=spf1 include:_spf.mx.cloudflare.net ~all

Certificats HTTPS

Toutes les plateformes modernes (Vercel, Netlify, Railway, Fly.io) configurent Let's Encrypt automatiquement dès que tu ajoutes un domaine. Tu n'as plus rien à gérer côté certificat. C'est gratuit, renouvelé tous les 60 jours automatiquement.

Propagation DNS

Quand tu modifies un enregistrement DNS, la propagation peut prendre jusqu'à 24 heures. En pratique, c'est souvent quelques minutes avec Cloudflare. Si tu vois une erreur, attends, c'est rarement un vrai problème.

Chapitre 5

Environnements, variables et secrets

Ne jamais commiter une clé API. Jamais. Voici l'organisation propre des environnements.

3 environnements minimum

  • development : ta machine, DB locale ou containerisée
  • staging : preview, accessible à l'équipe et au PO, mêmes contraintes que la prod (HTTPS, DB managée)
  • production : ce que voient les vrais utilisateur·ices

Variables d'environnement

.env.example (commité)
DATABASE_URL=postgres://user:pass@host:5432/db
NEXTAUTH_SECRET=
SENTRY_DSN=
NEXT_PUBLIC_API_URL=https://api.tonsite.fr
RESEND_API_KEY=
.env.local (jamais commité, dans .gitignore)
DATABASE_URL=postgres://anais:pass@localhost:5432/dev
NEXTAUTH_SECRET=valeur-aleatoire-32-bytes
SENTRY_DSN=https://xxx@yyy.ingest.sentry.io/zzz
NEXT_PUBLIC_API_URL=http://localhost:3000
RESEND_API_KEY=re_xxx

Variables NEXT_PUBLIC_*

Avec Next.js, les variables préfixées par NEXT_PUBLIC_ sont exposées dans le navigateur. Une clé secrète préfixée comme ça fuite immédiatement. Réserve ce préfixe aux URLs publiques et aux identifiants non sensibles.

Où stocker les secrets

  • Vercel / Railway / Fly.io : interface de gestion d'env vars intégrée, secrets chiffrés
  • Doppler : SaaS dédié au secret management, intégrations CI/plateformes
  • AWS Secrets Manager / GCP Secret Manager : quand tu scales
  • 1Password CLI : pour les secrets manipulés en local par l'équipe

Chapitre 6

Docker, images et CI/CD

Conteneuriser, c'est garantir que ton app tourne pareil partout (dev, staging, prod, machine de ta collègue). Et la CI déploie automatiquement.

Dockerfile multi-stage pour Next.js

Dockerfile
# Stage 1 : build
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Stage 2 : runtime minimal
FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/.next ./.next
COPY --from=build /app/public ./public
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
USER node
EXPOSE 3000
CMD ["npm", "start"]

Déploiement automatique via GitHub Actions

.github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'
      - run: npm ci
      - run: npm test
      - name: Deploy to Fly.io
        run: flyctl deploy --remote-only
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

Vercel et Netlify : pas besoin de Dockerfile

Si tu déploies sur Vercel ou Netlify, le framework est détecté automatiquement et le build se fait dans leur infra. Pas besoin de Dockerfile. Tu pousses, ça déploie.

Chapitre 7

Observabilité et monitoring

Si tu ne vois rien, tu ne répares rien. Trois couches : logs, métriques, alertes.

Logs structurés

Pas de console.log sauvage en prod. Utilise un logger comme Pino qui sort du JSON structuré : tu peux ensuite filtrer, agréger, alerter sur ces logs dans un outil centralisé (Logtail, Datadog, Vercel Logs).

import pino from 'pino';

const logger = pino({
  level: process.env.LOG_LEVEL ?? 'info',
});

logger.info({ userId: 42, action: 'login' }, 'User logged in');
logger.error({ err, orderId }, 'Order processing failed');

Error tracking : Sentry

// Installation automatique pour Next.js
// npx @sentry/wizard@latest -i nextjs

import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 0.2,           // 20% des requêtes tracées
  environment: process.env.NODE_ENV,
});

Sentry capture les erreurs front et back avec la stack trace complète, les source maps pour voir le code original, et le contexte (user, URL, navigateur). C'est la première chose à brancher en prod.

Uptime monitoring

  • UptimeRobot : 50 checks gratuits, alerte par email/Slack
  • BetterStack : plus moderne, page de statut publique, intégrations PagerDuty
  • Vercel/Fly.io intégré : analytics et health checks de base

Endpoint de health check

app/api/health/route.ts (Next.js)
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';

export async function GET() {
  try {
    await db.$queryRaw`SELECT 1`;
    return NextResponse.json({ status: 'ok' });
  } catch (err) {
    return NextResponse.json({ status: 'ko' }, { status: 503 });
  }
}

Health checks utiles

Configure ton health check pour vérifier les dépendances vitales : DB, Redis, services tiers critiques. Ton load balancer (Vercel, Fly.io) route automatiquement le trafic loin d'une instance qui répond 503.

Chapitre 8

CDN, performance et résilience

Un site lent en prod, c'est un site mort. Quelques réflexes pour garder de la vélocité.

CDN devant le front

  • Vercel Edge : intégré, sans config
  • Cloudflare : gratuit, à mettre devant n'importe quel hébergeur
  • Fastly : pour les grosses charges

Cache HTTP

Cache d'une route Next.js
// app/api/products/route.ts
export async function GET() {
  const products = await fetchProducts();

  return Response.json(products, {
    headers: {
      'Cache-Control': 's-maxage=60, stale-while-revalidate=300',
    },
  });
}

s-maxage=60 : caché 60 secondes côté CDN. stale-while-revalidate=300 : pendant 5 minutes après expiration, on sert la version stale en arrière-plan le temps de rafraîchir. UX rapide, charge serveur réduite.

Images optimisées

// Avec next/image, formats AVIF / WebP automatiques, lazy loading natif
import Image from 'next/image';

<Image
  src="/portrait.jpg"
  alt="Anaïs"
  width={400}
  height={400}
  loading="lazy"
/>

Résilience : rollback en 1 clic

  • Toujours garder la version N-1 déployable sans effort
  • Sur Vercel : onglet Deployments → bouton Promote to Production sur l'ancien déploiement
  • Sur Fly.io : flyctl releases + flyctl deploy --image <ancienne-image>
  • Backups DB automatiques et testés (restaurer pour vérifier que ça marche)

Le pattern à retenir

Déploie souvent, en petites bouchées. Plus tu déploies, moins chaque déploiement est risqué, plus tu rollback vite si ça casse. Move fast and don't break things est la version 2025 du vieux Facebook.

🛠️ Exercice optionnel

Déployer une app Next.js + Postgres en prod

Tu vas mettre en ligne une application Next.js connectée à Postgres, avec monitoring et health check. Compte 45 minutes la première fois.

Ta mission

  1. Push ton repo Next.js (existant ou create-next-app) sur GitHub.
  2. Crée une DB Postgres sur Neon (neon.tech, plan gratuit). Récupère la DATABASE_URL.
  3. Importe le repo dans Vercel, colle la DATABASE_URL dans les env vars du projet.
  4. Configure un domaine custom (si tu en as un) avec le CNAME vers Vercel.
  5. Ajoute Sentry : npx @sentry/wizard@latest -i nextjs, configure le DSN.
  6. Crée une route /api/health qui ping la DB.
  7. Configure UptimeRobot pour ping cette route toutes les 5 min, alerte par email si KO.
  8. Test rollback : pousse une régression volontaire, regarde l'erreur dans Sentry, rollback en 1 clic depuis Vercel.

Tu bloques ? Des indices, à dévoiler quand tu en as besoin.

Indice 1

Indice masqué.

Indice 2

Indice masqué.

Indice 3

Indice masqué.

✅ QCM de fin de cours

Teste tes acquis

10 questions, plusieurs réponses parfois possibles. Coche tout ce qui te semble juste, puis valide pour voir ton score et les explications.

  1. 1

    Pourquoi ne pas héberger en prod sur sa machine ?

  2. 2

    Quelle plateforme pour déployer un Next.js sans config particulière ?

  3. 3

    Que met-on dans .env.example commité dans le repo ?

  4. 4

    Rôle d'un CDN ?

  5. 5

    À quoi sert Sentry ?

  6. 6

    Que fait un health check ?

  7. 7

    Quel enregistrement DNS pour pointer un sous-domaine vers Vercel ?

  8. 8

    Bonne pratique pour les secrets ?

  9. 9

    Avantage d'un preview deploy sur PR ?

  10. 10

    Que vérifier avant un gros lancement ?

Tu peux laisser des questions sans réponse, elles compteront comme fausses.

Tu veux ce cours pour ton équipe ?

Je peux adapter et animer ce cours pour tes formateur·ices ou tes apprenant·es, en présentiel ou en distanciel. Parlons-en pendant l'audit gratuit.

Réserver un audit gratuit →