Skip to content
Learni
Voir tous les tutoriels
Déploiement

Comment déployer une app Node.js sur Fly.io en 2026

Read in English

Introduction

Fly.io est une plateforme de déploiement serverless qui excelle dans les déploiements globaux à faible latence grâce à son réseau edge étendu sur 35+ régions. Contrairement à Vercel ou Heroku, Fly.io utilise des conteneurs Firecracker pour une scalabilité horizontale native et un pricing au volume CPU/mémoire. En 2026, avec l'essor des apps full-stack et des microservices, maîtriser Fly.io permet de réduire les coûts de 40-60% par rapport aux alternatives cloud traditionnelles tout en offrant des performances mondiales.

Ce tutoriel intermédiaire vous guide pour déployer une API Node.js Express : de l'installation de flyctl à la mise en production scalable. Vous apprendrez à configurer un Dockerfile optimisé, un fly.toml personnalisé, gérer les secrets et scaler automatiquement. À la fin, votre app sera live sur un domaine .fly.dev avec HTTPS gratuit, prête pour la prod. Idéal pour les devs qui veulent bookmarker un guide actionnable et sans fluff.

Prérequis

  • Node.js 20+ installé
  • Docker Desktop (pour builds locaux)
  • Compte GitHub gratuit (optionnel pour CI/CD)
  • Connaissances de base en Docker et CLI
  • Terminal Unix-like (WSL sur Windows)

Installer flyctl

terminal
curl -L https://fly.io/install.sh | sh

# Vérifier l'installation
fly version
fly auth signup

Ce script one-liner installe flyctl, la CLI officielle de Fly.io. La commande fly auth signup crée un compte gratuit (avec 3$ de crédit initial). Évitez les proxies d'entreprise qui bloquent curl ; utilisez brew install flyctl sur macOS comme fallback.

Créer l'application Node.js de base

Avant de déployer, initialisons une API Express minimaliste. Imaginez-la comme une maison : le serveur est la fondation, les routes les pièces. Nous créons un projet complet avec health-check pour les probes Kubernetes-like de Fly.io.

Initialiser le projet Express

terminal
mkdir flyio-node-app && cd flyio-node-app
npm init -y
npm install express
npm install -D nodemon typescript @types/express @types/node tsx

On crée un projet Node avec Express pour l'API et TypeScript pour la robustesse. nodemon et tsx facilitent le dev local. Testez localement avec npx tsx server.ts avant de passer au Docker.

Écrire le serveur Express

server.ts
import express from 'express';

const app = express();
const PORT = process.env.PORT || 8080;

app.use(express.json());

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok', timestamp: new Date().toISOString() });
});

app.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]);
});

app.post('/api/users', (req, res) => {
  const user = req.body;
  res.status(201).json({ id: 3, ...user });
});

const server = app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server running on port ${PORT}`);
});

process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  server.close(() => {
    console.log('Process terminated');
  });
});

Ce serveur TypeScript complet expose /health pour les checks Fly.io, gère users CRUD basique et écoute sur 0.0.0.0 (requis pour conteneurs). Le handler SIGTERM assure un shutdown gracieux, évitant les pertes de connexions en scaling.

Containeriser avec Dockerfile

Fly.io build et déploie via Docker. Notre Dockerfile est multi-stage pour un image légère (<100MB), comme un expresso concentré : build rapide, runtime minimal.

Créer le Dockerfile optimisé

Dockerfile
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json tsconfig.json ./
RUN npm ci --only=production && npm cache clean --force

COPY . .

RUN npm run build || true  # Si build step existe

FROM node:20-alpine AS runner

WORKDIR /app

ENV NODE_ENV=production

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/server.ts ./server.ts

EXPOSE 8080

CMD ["npx", "tsx", "server.ts"]

Multi-stage réduit la taille : builder installe deps, runner copie seulement prod. Utilisez Alpine pour légèreté. Ajoutez tsconfig.json basique si absent : {"compilerOptions": {"target": "ES2022", "module": "ESNext"}}.

Configurer fly.toml

fly.toml est le manifest de déploiement : ports, régions, scaling. C'est comme le blueprint d'une usine : définit processes, volumes et HTTP.

Générer et personnaliser fly.toml

fly.toml
app = "flyio-node-demo-2026"
primary_region = "cdg"  # Paris pour latence EU

[build]
  builder = "paketobuildpacks/builder:base"

[env]
  PORT = "8080"

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]

[[http_service.checks]]
  path = "/health"
  port = 8080
  type = "http"
  interval = "10s"
  grace_period = "5s"
  method = "GET"

[[services]]
  internal_port = 8080
  protocol = "tcp"

  [[services.ports]]
    port = 80
    handlers = ["http"]

  [[services.ports]]
    port = 443
    handlers = ["tls", "http"]

Ce fly.toml configure un app nommé, région EU (cdg=Paris), health-checks pour auto-scaling et HTTPS forcé. auto_stop_machines économise ~90% en idle. Lancez fly launch --no-deploy pour générer auto et éditez.

Définir les secrets d'environnement

terminal
flyctl apps create flyio-node-demo-2026 --region cdg
flyctl secrets set DATABASE_URL=postgres://user:pass@db.flycast:5432/db
flyctl secrets set API_KEY=sk-1234567890abcdef
flyctl secrets list

Secrets sont chiffrés et injectés au runtime, invisibles en logs. Utilisez pour DB creds ou API keys. fly apps create si pas de launch ; list vérifie sans exposer valeurs.

Déployer l'application

terminal
flyctl deploy --ha=false

# Vérifier status
flyctl status
flyctl logs
curl https://flyio-node-demo-2026.fly.dev/health

deploy build/push l'image et rollout zero-downtime. --ha=false pour single region init ; retirez pour global. Logs en temps réel aident debug ; health endpoint confirme readiness.

Scaling et monitoring

Une fois live, scalez horizontalement. Fly.io autoscaler ajuste VMs (machines) par CPU/load, comme un thermostat intelligent.

Scaler et config autoscaler

terminal
flyctl scale count 2 --max-per-region 3
flyctl scale vm shared-cpu-1x --memory 512

# Autoscaler
flyctl scale set-autoscaler --min 1 --max 10

# Metrics
flyctl metrics
flyctl dashboard

Scale à 2 instances min, max 3/region pour HA. Autoscaler gère bursts (min1 idle). metrics montre CPU/RAM live ; dashboard web pour graphs avancés.

Bonnes pratiques

  • Régions intelligentes : Choisissez primary_region près de vos users (fly regions list), ajoutez [[services]] pour multi-régions.
  • Images légères : <200MB max ; utilisez .dockerignore pour node_modules/src.
  • Health checks stricts : Toujours /healthz avec timeout <5s pour restarts rapides.
  • CI/CD GitHub : Ajoutez flyctl/deploy dans Actions pour zero-config.
  • Volumes persistants : fly volumes create data --region cdg --size 10 pour DB locale.

Erreurs courantes à éviter

  • Port binding : Écoutez sur 0.0.0.0:8080, pas localhost ; sinon OOMKilled.
  • No Dockerfile : Fly fallback sur buildpacks, mais lent ; toujours Dockerfile custom.
  • Secrets exposés : Jamais en fly.toml ou logs ; utilisez fly secrets set uniquement.
  • Scaling sans checks : Machines stuck en crashed sans /health ; ajoutez toujours.

Pour aller plus loin

Maîtrisez les Postgres managed (fly postgres create), Workers KV ou intégration Tailscale VPN. Consultez la doc officielle Fly.io et nos formations Learni Dev sur le déploiement cloud-native pour des ateliers pratiques avancés.