Intégration Phénix
bext se trouve devant une application Élixir Phénix en tant que couche périphérique. Phoenix conserve l'intégralité de l'expérience du framework (contrôleurs, LiveView, canaux, Ecto, PubSub, OTP) et bext ajoute les problèmes de production que chaque équipe Phoenix doit développer ou intégrer : terminaison TLS, HTTP/2 et HTTP/3, pare-feu d'application Web, cache périphérique, Prometheus + OpenTelemetry et absorption DDoS.
Il ne s'agit pas d'un adaptateur au sens Astro / SvelteKit. Phoenix est un framework côté serveur complet qui embarque sa propre couche HTTP via Cowboy (ou Bandit, si vous préférez) ; bext s'intègre par proxy inverse à Cowboy plutôt qu'en encapsulant le pipeline de rendu de Phoenix. Le démarreur ci-dessous est un échafaudage – un exemple fonctionnel de la forme, et non une application Phoenix exécutable. Vous amenez Phoenix ; bext le fait face.
Quand l’utiliser. Si votre équipe possède déjà un Phoenix application (avec ou sans LiveView) et vous souhaitez mettre bext en tête pour les soucis de périphérie (TLS, cache, WAF, métriques), ceci est l'intégration pour vous. Si vous souhaitez construire un nouveau non-BEAM Application SSR sur bext, utilisez PRISM ou l'un des JS adaptateurs de framework à la place.
Architecture#
┌─────────┐ ┌───────────────────────────┐ ┌─────────────┐
│ │ HTTPS │ bext │ HTTP │ Cowboy │
│ client │ ───────► │ TLS • WAF • cache • obs │ ───────► │ :4000 │
│ │ :443 │ :8080 │ 127.0.0.1│ + Phoenix │
└─────────┘ └───────────────────────────┘ └─────────────┘
Parcours d’une requête :
- Le client parle HTTPS (HTTP/2 ou HTTP/3 sur QUIC) à bext sur
:443. - bext termine TLS, exécute le WAF, vérifie le cache périphérique et émet de la télémétrie.
- En cas d'échec du cache, bext ouvre une connexion HTTP/1.1 keepalive vers
Cowboy sur
127.0.0.1:4000et transmet la demande. - Phoenix exécute le pipeline Plug (Routeur → Contrôleur → Vue).
- La réponse revient via bext – qui écrit le cache entrées, compresse (Brotli / zstd / gzip) et émet des métriques — au client.
Cowboy n'écoute jamais sur une interface publique. Liez-le à
127.0.0.1:4000 (comme dans config/dev.exs et config/prod.exs ) et laissez bext être le seul auditeur public.
Sécurité LiveView#
Phoenix LiveView établit un WebSocket lors du premier montage (à
/live/websocket par défaut). Pour que bext transmette correctement le trafic LiveView, le chemin /live/* doit :
- Ignorez le cache périphérique : LiveView pousse les différences par client et les réponses mises en cache désynchroniseraient chaque client connecté.
- Transportez les en-têtes de mise à niveau WebSocket – bext doit traitez la route comme étant compatible avec la mise à niveau afin que la prise de contact HTTP/1.1 → WS passe intacte.
Le bext.config.toml du démarreur est livré avec une règle d'itinéraire /live/* qui fait les deux. Gardez-le au-dessus de la règle fourre-tout /* :
[[route_rules]]
pattern = "/live/*"
proxy = "phoenix"
cache = false
websocket = true
[[route_rules]]
pattern = "/*"
proxy = "phoenix"
Si vous déployez plusieurs nœuds Phoenix derrière bext, activez les sessions persistantes sur la route LiveView (voir la section Upstreams de documents de proxy inverse ) — un socket LiveView est épinglé au nœud sur lequel mount/3 s'est exécuté et une deuxième connexion circulaire sur la même page ne parviendra pas à se reconnecter.
Cowboy contre bandit#
Phoenix 1.7 prend en charge deux serveurs HTTP :
| Serveur | Par défaut depuis | Pourquoi le choisir |
|---|---|---|
Cowboy ( plug_cowboy ) |
historique | Mature, testé au combat, la valeur par défaut chez les débutants plus âgés. Fonctionne bien derrière bext. |
Bandit ( bandit ) |
1.7 nouveaux projets | Pure-Elixir, plus rapide sur les petites requêtes, arbre de supervision plus simple. Fonctionne bien derrière bext. |
Tous deux écoutent sur HTTP/1.1 bext sur 127.0.0.1:4000. bext est le terminateur HTTP/2 et HTTP/3, quel que soit le serveur Phoenix que vous choisissez. Le démarreur utilise Cowboy pour une compatibilité étendue – passez à Bandit en remplaçant {:plug_cowboy, "~> 2.6"} par
{:bandit, "~> 1.2"} dans mix.exs et réglage
adapter: Bandit.PhoenixAdapter dans config/config.exs.
Fichiers statiques#
Phoenix sert ses actifs statiques compilés (noms hachés sous
priv/static/assets/ ) via Plug.Static dans le pipeline Endpoint. Le démarreur laisse cela intact et transmet / à Phoenix — de sorte que les demandes d'actifs passent par bext, sont mises en cache en périphérie lors de la première requête et sont servies depuis la périphérie lors des requêtes suivantes.
Pour servir priv/static/ directement depuis bext sans toucher Phoenix, ajoutez une règle au-dessus du fourre-tout :
[[route_rules]]
pattern = "/assets/*"
render = "static"
static_root = "priv/static"
headers = { "Cache-Control" = "public, max-age=31536000, immutable" }
Ceci est facultatif : le cache périphérique effectue la majeure partie du même travail gratuitement, et le passage direct n'est utile que si vous avez des pages riches en ressources avec de faibles taux d'accès au cache.
système#
Pour la production, exécutez Phoenix derrière une unité systemd afin que bext puisse le redémarrer proprement. Préférez une version Mix ( mix release ) à
mix phx.server — les versions démarrent plus rapidement, sont expédiées sans Mix ni Hex et constituent le modèle de production standard de BEAM.
[Unit]
Description=Phoenix app (Cowboy) (%i)
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/srv/app
Environment=MIX_ENV=prod
Environment=PHX_HOST=example.com
Environment=PORT=4000
# Release-based (preferred):
ExecStart=/srv/app/_build/prod/rel/hello/bin/hello start
# Or, Mix-based fallback:
# ExecStart=/usr/bin/env mix phx.server
ExecStop=/srv/app/_build/prod/rel/hello/bin/hello stop
Restart=on-failure
RestartSec=2
[Install]
WantedBy=multi-user.target
Une version vous offre également une prise en charge des mises à niveau à chaud, avec laquelle le cache périphérique de bext et le drainage gracieux des connexions se combinent bien : l'ancien nœud Phoenix continue de répondre aux demandes en cours pendant que le nouveau se réchauffe.
Faire confiance aux en-têtes transférés de bext#
bext définit X-Forwarded-For, X-Forwarded-Proto et
X-Forwarded-Host sur chaque demande en amont. Phoenix ne fait pas confiance à et à à ces en-têtes par défaut - configurez Plug.RewriteOn ou le
Bibliothèque remote_ip donc conn.remote_ip, conn.scheme et
conn.host reflète le client réel au lieu de la connexion de bouclage de bext.
Ajouter à config/prod.exs :
config :hello, HelloWeb.Endpoint,
http: [
ip: {127, 0, 0, 1},
port: 4000,
compress: false
]
# Plug.RewriteOn picks up X-Forwarded-* headers from bext.
# :x_forwarded_for is the most important — otherwise every
# request looks like it came from 127.0.0.1.
config :plug, :validate_header_keys_during_test, true
Et connectez Plug.RewriteOn à votre point de terminaison au-dessus de Plug.Static :
plug Plug.RewriteOn, [:x_forwarded_host, :x_forwarded_port, :x_forwarded_proto]
Est-ce que et non activent force_ssl dans Phoenix lorsque bext est le terminateur TLS — Phoenix verra une connexion HTTP à partir de bext et une boucle de redirection. bext gère la redirection HTTPS en périphérie.
Invalidation du cache#
Le cache périphérique de bext est adressable par balise. Invalidez depuis Phoenix via l'API de contrôle HTTP que le plugin de cache expose :
defmodule HelloWeb.CacheInvalidation do
def purge(tag) do
Req.post!("http://127.0.0.1:8080/__bext/cache/purge",
json: %{keys: [tag]}
)
end
end
# Anywhere in your app:
HelloWeb.CacheInvalidation.purge("post:#{post.id}")
Associez-le aux en-têtes de réponse Cache-Tag de Phoenix pour marquer quelles entrées de bord appartiennent à quelles balises.
Détection#
Le catalogue de bext détecte automatiquement les projets Phoenix lors
bext infra import et bext site autoconfigure via la règle à
crates/bext-import/catalog/frameworks.yaml:
- match:
any_of_files: ["mix.exs"]
mix:
any_of_packages: ["phoenix"]
extract:
framework: phoenix
starter: "@bext/starter-phoenix"
La correspondance est une analyse de sous-chaîne de mix.exs pour {:phoenix, – rapide et sans dépendance, aucune chaîne d'outils Elixir n'est requise. Si un projet correspond, bext infra import propose de générer le reverse-proxy
bext.config.toml du démarreur.
Lacunes connues#
- Chaînes au-delà de LiveView. Canaux Phoenix sur des systèmes non
/live/*les chemins ont besoin de leur propre règle de routage avecwebsocket = true. bext traite les itinéraires WebSocket comme une option d'adhésion. - Remplacement d’une interrogation longue. Si vous désactivez le transport WebSocket dans
phoenix_live_viewet revenez à l'interrogation longue, désactivez le cache périphérique sur ces routes (cache = false) — les réponses à l'interrogation longue mises en cache rompront la connexion. - Mix de versions et invalidation du cache. Mises à niveau de la version redémarrez la machine virtuelle BEAM ; le cache périphérique bext survit au redémarrage, donc purgez les balises pertinentes dans le cadre de votre script de déploiement ou les requêtes renverront les données obsolètes de l'ancienne version.
- bext n'exécute pas la distribution EPMD ou Erlang. Pour cluster Nœuds Phoenix, conservez la distribution sur une interface privée et utilisez bext uniquement comme périphérie HTTP.
Voir aussi#
- Proxy inverse : pools en amont et sondes d'intégrité
- Prise en charge de WebSocket et SSE
- Plugin de cache – invalidation des balises
- bext TLS automatique
Links#
- Cadre Phénix — documentation officielle pour Phoenix et LiveView