Tutorial
30 min read
36 views

Workflows modernes pour développeurs & intégrations avancées d'infrastructure

Découvrez pourquoi les proxies HTTP standard abandonnent Next.js 15+ Server Actions et les connexions WebSocket HMR de Vite, et comment maintenir un hot-reload sous la milliseconde sur tunnels distants.

IT
InstaTunnel Team
Published by the InstaTunnel team | Editorial policy
Workflows modernes pour développeurs & intégrations avancées d'infrastructure

Quick answer

Tunneling Vite 6 & Next.js Server Actions : Résoudre HMR: webhook testing answer

For local webhook testing, run your app locally, expose it with a public HTTPS tunnel, and paste the stable callback URL into the provider dashboard.

How do I test webhooks on localhost?

Start your local server, open a public HTTPS tunnel to that port, configure the provider webhook URL, and inspect events in your local logs.

Why does a stable webhook URL matter?

Stable URLs prevent provider dashboards from needing manual callback updates every time you restart a tunnel.

Une architecture full-stack moderne équilibre les runtimes cloud distants avec des boucles de rétroaction instantanées sur les machines des développeurs. Atteindre une itération rapide — que ce soit dans des applications frontend Next.js ou des microservices distribués — nécessite de router le trafic en direct entre les frontières cloud et les environnements locaux.

Ce guide fournit des stratégies techniques pour proxyfier les serveurs de développement locaux, transmettre des spans de télémétrie, router des webhooks multi-locataires, et attacher des aperçus cloud à des instances de base de données éphémères.

1. Hot-Reload transfrontalier : Tunneling Vite 6 et Next.js Server Actions via des proxies HMR-aware

Les proxies HTTP inverses traditionnels (comme Nginx par défaut ou des tunnels SSH basiques) cassent les applications web stateful car ils évaluent le trafic de façon stateless. Les outils modernes comme Vite 6 et Next.js 15+ dépendent de connexions bidirectionnelles, à faible latence, pour synchroniser les états client, compiler des modules côté serveur, et traiter les Server Actions.

+-------------------------------------------------------------------------------+
|                             TUNNEL CLOUD PUBLIC                               |
|                     https://dev-tenant.app.example.com                        |
+-------------------------------------------------------------------------------+
                                       |
                                       | Terminaison TLS & WSS
                                       v
+-------------------------------------------------------------------------------+
|                       PROXY INVERSE HMR-AWARE                                   |
|  - Réécriture de l'en-tête Host (Vérification d'origine)                        |
|  - Gestion de la mise à niveau HTTP/1.1 (101 Switching Protocols)             |
|  - Pings Keep-Alive & Mappage dynamique des ports clients                        |
+-------------------------------------------------------------------------------+
                                       |
            +--------------------------+--------------------------+
            | (gRPC / TCP multiplexé)                            | (Actions Server HTTP/2)
            v                                                     v
+-----------------------+                             +-----------------------+
|  Serveur de dev Vite  |                             | Router d'application Next.js |
|  (localhost:5173)      |                             | (localhost:3000)      |
|                       |                             |                       |
| - WebSocket HMR Path: |                             | - Host autorisé CSRF: |
|   /_vite_hmr          |                             |   dev-tenant.example |
+-----------------------+                             +-----------------------+

Pourquoi les proxies traditionnels cassent HMR et Server Actions

  1. Encadrement WebSocket abandonné : Les proxies HTTP standards traitent le trafic entrant comme des échanges request/response courts. Lorsqu’une tentative d’upgrade HTTP/1.1 Upgrade: websocket est faite pour établir le canal HMR, les proxies stateless ne maintiennent pas la socket TCP persistante. Cela force Vite à des rechargements de secours continus.
  2. Vérifications Host & CSRF dans Next.js 15+ : Les Server Actions de Next.js s’exécutent via des requêtes POST HTTP utilisant des endpoints cachés. Pour prévenir les attaques CSRF, Next.js inspecte les en-têtes Origin et Host. Si un tunnel réécrit Host: localhost:3000 sans correspondre à l’URL publique du tunnel, l’invocation est bloquée.
  3. Ports WebSocket non cohérents : Vite injecte un script runtime côté client qui tente d’ouvrir une WebSocket vers le port HMR. Si le navigateur se connecte à [https://app.example.com](https://app.example.com) (port 443) mais que Vite indique au client d’ouvrir une socket à ws://localhost:5173, la sécurité cross-origin du navigateur bloque la connexion.

Architecture de préservation pour Vite 6

Pour maintenir un HMR sous la milliseconde via des tunnels publics (comme Cloudflare Tunnels, frp, ou ngrok), configurez le serveur WebSocket interne de Vite pour dissocier son port d’écoute interne de son port public côté client.

// vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  server: {
    host: '0.0.0.0',
    port: 5173,
    strictPort: true,
    hmr: {
      // Nom d'hôte public exposé par votre tunnel
      host: 'vite-tunnel.dev.example.com',
      // Forcer le client à utiliser le port HTTPS/WSS au lieu de 5173 en interne
      clientPort: 443,
      protocol: 'wss',
      path: '/_vite_hmr',
    },
    // Empêcher la déconnexion HMR due à un mismatch d'hôte
    cors: true,
  },
});

Configuration du tunnel d’action serveur Next.js 15+

Pour Next.js 15, mettez à jour next.config.ts pour permettre l’invocation des Server Actions via des tunnels de développement publics.

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    serverActions: {
      // Liste blanche des origines du tunnel pour passer les vérifications CSRF
      allowedOrigins: [
        'next-tunnel.dev.example.com',
        '*.tunnel.dev.example.com',
      ],
    },
  },
};

export default nextConfig;

2. Routage des traces distribuées du cloud staging vers votre interface Jaeger locale

Lors du débogage de microservices en environnement de staging, tracer une requête asynchrone à travers plusieurs services est essentiel. Cependant, envoyer des données de télémétrie vers un backend central crée du bruit et complique l’isolement.

En utilisant des collecteurs OpenTelemetry (OTLP), les ingénieurs backend peuvent proxyfier les flux de télémétrie vers une instance locale de Jaeger UI sans polluer le stockage distant.

+-----------------------------------------------------------------------------------+
|                              CLUSTER DE STAGING CLOUD                             |
|                                                                                   |
|  +---------------------+      +---------------------+      +-------------------+  |
|  | Microservice Auth   | --- | Microservice Commande | --- | Service de paiement |
|  +---------------------+      +---------------------+      +-------------------+  |
|                                          |                                        |
|                                          | OTLP / gRPC (Port 4317)                |
|                                          v                                        |
|                      +---------------------------------------+                    |
|                      | Collecteur OTLP de staging cloud     |                    |
|                      +---------------------------------------+                    |
+------------------------------------------|----------------------------------------+
                                           |
                                           | Routage via Tailscale/SSH Tunnel inverse
                                           v
+-----------------------------------------------------------------------------------+
|                             POSTE DE DÉVELOPPEUR LOCAL                            |
|                                                                                   |
|  +-----------------------------------------------------------------------------+  |
|  | Collecteur OpenTelemetry local                                              |  |
|  | - Reçoit OTLP / gRPC sur 127.0.0.1:4317                                    |  |
|  | - Filtre : attributes["x-developer-id"] == "dev-alice"                     |  |
|  +-----------------------------------------------------------------------------+  |
|                                          |                                        |
|                                          v OTLP / gRPC (Insecure)                 |
|  +-----------------------------------------------------------------------------+  |
|  | Conteneur Jaeger local                                                      |  |
|  | - Port d'ingestion : 4317                                                    |  |
|  | - Web UI : http://localhost:16686                                              |  |
|  +-----------------------------------------------------------------------------+  |
+-----------------------------------------------------------------------------------+

Le problème de détournement de trace

Envoyer directement des spans de trace vers des stockages cloud comme Datadog, Honeycomb, ou une instance AWS OpenSearch partagée pose deux problèmes distincts :

  • Contamination de l’index : Les logs de débogage et payloads mal formés encombrent les dashboards de production et staging.
  • Latence & limites de débit : Exporter des spans à haut volume via Internet augmente les coûts d’ingestion cloud et le risque de dépasser les limites de débit du fournisseur.

Architecture : Routage OTLP sélectif inversé

Les ingénieurs peuvent isoler et router sélectivement des traces en utilisant des en-têtes contextuels (comme x-developer-id: dev-alice) traités par un connecteur de routage OpenTelemetry.

Étape 1 : Configuration du collecteur OTLP de staging

Configurer le collecteur OTLP de staging pour évaluer les attributs de trace entrants et router les spans tagués via un pipeline gRPC inverse vers une machine locale.

# otel-collector-staging.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317

processors:
  batch:
    timeout: 1s
    send_batch_size: 256

exporters:
  # Destination de stockage cloud standard
  otlp/staging_backend:
    endpoint: "tempo-staging.internal.net:4317"
    tls:
      insecure: true

  # Destination tunnel inverse pointant vers la machine du développeur
  otlp/dev_alice_local:
    endpoint: "host.docker.internal:14317"
    tls:
      insecure: true

connector:
  routing:
    default_exporters: [otlp/staging_backend]
    from_attribute: "x-developer-id"
    table:
      - value: "dev-alice"
        exporters: [otlp/dev_alice_local]

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [routing]

Étape 2 : Établir le tunnel inverse et ingestion locale

Établissez un tunnel SSH inverse depuis votre poste de développement vers la passerelle de staging, en mappant le port 14317 sur le nœud de staging vers le port 4317 localement.

# Établir un tunnel gRPC SSH inverse
ssh -R 14317:localhost:4317 developer@staging-gateway.internal.net -N

Lancez un conteneur Jaeger léger local (configuré avec ingestion OTLP native) :

docker run -d --name jaeger-local \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 16686:16686 \
  -p 4317:4317 \
  jaegertracing/all-in-one:latest

Lorsqu’une requête HTTP contenant l’en-tête x-developer-id: dev-alice entre dans l’environnement de staging, toute sa trace se branche et est envoyée directement à votre interface Jaeger locale à http://localhost:16686.

3. Tester les webhooks Stripe Connect locaux avec sous-domaines multi-locataires dynamiques

Tester des plateformes SaaS multi-locataires nécessite d’isoler les événements pour différentes organisations. Lors de la construction d’architectures multi-locataires avec Stripe Connect (où une plateforme gère plusieurs comptes connectés), le débogage des webhooks via un seul endpoint masque les problèmes de résolution dynamique des locataires.

                                  CLOUD STRIPE
                                        |
                 +----------------------+----------------------+
                 | Événement webhook Connect                     |
                 | Compte : acct_tenant_A                        | Compte : acct_tenant_B
                 v                                             v
  +------------------------------+             +------------------------------+
  | https://tenant-a.tunnel.dev  |             | https://tenant-b.tunnel.dev  |
  +------------------------------+             +------------------------------+
                 |                                             |
                 +----------------------+----------------------+
                                        |
                                        v
                        +-------------------------------+
                        | Proxy d'entrée wildcard        |
                        | *.tunnel.dev -> localhost:8080|
                        +-------------------------------+
                                        |
                                        v
                        +-------------------------------+
                        | Routeur multi-locataires local |
                        | Extrait l'en-tête Host        |
                        | Mappe le locataire A vs B    |
                        +-------------------------------+

Configuration du routage Webhook multi-locataires

En utilisant un proxy inverse wildcard (tel que frp ou caddy), pointez *.tunnel.yourdomain.dev vers votre routeur d’application local.

1. Configuration du reverse proxy Caddy (routeur d’entrée local)

# Caddyfile - Proxy local multi-locataires wildcard
*.tunnel.dev.localhost {
    tls internal
    
    @tenant_a header_regexp host Host ^([a-zA-Z0-9-]+)\.tunnel\.dev\.localhost$
    
    handle {
        reverse_proxy localhost:3000 {
            header_up Host {http.request.host}
            header_up X-Forwarded-Host {http.request.host}
        }
    }
}

2. Script avancé de forwarding webhook multi-locataires

Au lieu d’exécuter des commandes stripe listen individuelles par locataire, utilisez ce script proxy Node.js multi-locataires. Il écoute les événements Stripe et les forwarde dynamiquement vers le sous-domaine local correspondant selon l’ID account de l’événement.

// scripts/stripe-multitenant-proxy.ts
import Stripe from 'stripe';
import axios from 'axios';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2026-01-28',
});

// Map des IDs de comptes Stripe connectés vers sous-domaines locaux
const TENANT_MAPPING: Record<string, string> = {
  'acct_1N01AAA000000000': 'acme',
  'acct_1N02BBB000000000': 'globex',
};

async function handleWebhookEvent(event: Stripe.Event) {
  const connectedAccountId = event.account;
  const tenantSlug = connectedAccountId ? TENANT_MAPPING[connectedAccountId] : 'app';

  if (!tenantSlug) {
    console.warn(`[WARN] ID de compte non mappé : ${connectedAccountId}`);
    return;
  }

  const targetUrl = `http://${tenantSlug}.tunnel.dev.localhost:3000/api/webhooks/stripe`;

  try {
    console.log(`[FORWARD] Event ${event.type} -> ${targetUrl}`);
    await axios.post(targetUrl, event, {
      headers: {
        'Stripe-Signature': 'sig_locale_simulée',
        'Content-Type': 'application/json',
        'Host': `${tenantSlug}.tunnel.dev.localhost`,
      },
    });
  } catch (err: any) {
    console.error(`[ERREUR] Échec de livraison du webhook : ${err.message}`);
  }
}

4. Exposer des instances locales de Supabase et Postgres aux déploiements de prévisualisation cloud Vercel/Netlify

Les workflows de branches features lancent automatiquement des déploiements de prévisualisation éphémères sur des plateformes comme Vercel ou Netlify. Cependant, fournir un état de base de données backend isolé pour chaque PR peut être difficile à gérer.

En utilisant un tunneling TCP Layer 4 (tel que ngrok tcp, bore, ou frp), vous pouvez exposer en toute sécurité votre instance locale de PostgreSQL ou Supabase Dockerisée directement aux déploiements de prévisualisation cloud.

+-----------------------------------------------------------------------------+
|                        VERCEL / NETLIFY PR #42 de prévisualisation            |
|                     https://app-git-feature-pr42.vercel.app               |
|                                                                             |
|   DATABASE_URL = postgresql://postgres:pass@tcp.tunnel.dev:19432/postgres   |
+-----------------------------------------------------------------------------+
                                       |
                                       | Tunnel TCP chiffré (Port 19432)
                                       v
+-----------------------------------------------------------------------------+
|                            Proxy TCP inverse                                |
|  - Passage TLS / pipeline TCP L4 pur                                    |
+-----------------------------------------------------------------------------+
                                       |
                                       | Tunnel inverse sécurisé
                                       v
+-----------------------------------------------------------------------------+
|                        Poste de développement local                         |
|                                                                             |
|  +-----------------------------------------------------------------------+  |
|  | Proxy firewall Postgres / PgBouncer local                                |  |
|  | - Écoute sur 127.0.0.1:5432                                              |  |
|  | - Limite SSL / Session validation                                         |  |
|  +-----------------------------------------------------------------------+  |
|                                      |                                      |
|                                      v                                      |
|  +-----------------------------------------------------------------------+  |
|  | Instance Supabase Dockerisée                                              |  |
|  | - Moteur PostgreSQL (Port 5432)                                             |  |
|  | - API PostgREST (Port 54321)                                                 |  |
|  | - Système d'authentification GoTrue (Port 9999)                              |  |
|  +-----------------------------------------------------------------------+  |
+-----------------------------------------------------------------------------+

Comparaison de protocole : Layer 4 (TCP) vs Layer 7 (HTTP)

  • Proxies HTTP (Layer 7): Inadaptés pour moteurs de base de données. Attendent du HTTP/WebSockets en clair, cassent les protocoles de wire comme StartupMessage de Postgres, et abandonnent les connexions non-HTTP.
  • Tunnels TCP (Layer 4): Transmettent les paquets TCP bruts au niveau transport, conservant les protocoles wire.

Exposer la stack locale de Supabase via FRP (Fast Reverse Proxy)

Pour tunneliser votre stack locale de Supabase, configurez frp pour exposer PostgreSQL local (port 5432) et PostgREST (port 54321) via TCP L4.

Configuration serveur (frps.ini sur la passerelle distante)

[common]
bind_port = 7000
vhost_extra_db_port = 19432

Configuration client (frpc.ini sur la machine du développeur)

[common]
server_addr = gateway.yourdomain.dev
server_port = 7000

[supabase-postgres-tcp]
type = tcp
local_ip = 127.0.0.1
local_port = 54322
remote_port = 19432

[supabase-postgrest-http]
type = http
local_ip = 127.0.0.1
local_port = 54321
custom_domains = api-pr42.tunnel.yourdomain.dev

Automatisation via GitHub Actions & API Vercel

Automatisez vos workflows de pull request en configurant dynamiquement des variables d’environnement sur des déploiements de prévisualisation éphémères avec une Action GitHub.

# .github/workflows/preview-environment.yml
name: Injecteur de base de données pour environnement de prévisualisation

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  attach-local-db:
    runs-on: ubuntu-latest
    steps:
      - name: Injecter l'URL dynamique du tunnel DB dans Vercel
        env:
          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
        run: |
          PR_NUM=${{ github.event.number }}
          # Construire l'URL de la base de données dynamique pointant vers le port TCP du tunnel du développeur
          TUNNEL_DB_URL="postgresql://postgres:postgres@gateway.yourdomain.dev:19432/postgres?sslmode=require"

          # Assigner la chaîne de connexion à la base de données à l'environnement de déploiement de prévisualisation Vercel
          curl -X POST "https://api.vercel.com/v10/projects/${VERCEL_PROJECT_ID}/env" \
            -H "Authorization: Bearer ${VERCEL_TOKEN}" \
            -H "Content-Type: application/json" \
            -d '{
              "key": "DATABASE_URL",
              "value": "'"${TUNNEL_DB_URL}"'",
              "type": "encrypted",
              "target": ["preview"],
              "gitBranch": "${{ github.head_ref }}"
            }'

Continue from this article into the most relevant product guides and workflows.

Related Topics

#vite 6 hmr#nextjs server actions#websocket proxy#hmr over proxy#hot module replacement#vite tunnel#nextjs 15 tunneling#localhost tunnel#reverse proxy hmr#websocket drops proxy#nextjs server actions debug#local developer environment#vite dev server proxy#hmr websocket reconnect#server action proxy#tunnel localhost#local dev tunneling#remote hmr debugging#web sockets over reverse proxy#sub millisecond hmr#vite HMR configuration#nextjs server actions deployment#developer workflow optimization#modern frontend frameworks#local dev environment tools#web development proxies#tunneling tools for developers#nextjs preview local database#remote webhook debugging#local dev setup#web development workflow#fullstack local debugging#software development tools#devops local environment#local proxy configuration#developer networking tools#frontend developer environment#backend developer environment#fullstack developer tools#real time hot reload#continuous development workflow#local dev server port forwarding#local port tunnel#secure localhost exposure#web development productivity#server action execution#websocket connection handling#developer tooling 2026#remote development server#web dev tunneling solutions

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles