Aller au contenu principal

Proxy inverse et HTTPS

Avec Aivory app Le conteneur est 8787 L’accès au spa à l’avant et /api L'arrière-plan ne parle que d'HTTP. L'environnement de production suggère d'y placer une couche de proxy inverse responsable de la résiliation du TLS. Cette page fournit les deux configurations complètes de Nginx et Caddy qui peuvent être collées directement et explique pourquoi chacune d'entre elles est ainsi écrite.

Pourquoi n’est-il pas nécessaire de configurer CORS

Le front end et l'API sont gérés par le même processus, le même port, les deux sont toujours à la même source sous la perspective du navigateur. PUBLIC_ORIGIN Il n'est pas nécessaire de configurer la liste blanche CORS par nom de domaine. ALLOWED_ORIGINS Il suffit de vous débarrasser de l’apogée. ** différentes sources ** Le déploiement n’a de sens que sous la forme du déploiement, le déploiement de conteneur unique n’est pas possible.

Avant de commencer: ajuster la cartographie des ports

Déploiement rapide Le document composé est défini app L’appareil est équipé d’un port 80 ("80:8787" Lorsque vous ajoutez Nginx/Caddy sur la même machine, 80/443 doit être app Remplacement de l'écoute de l'appareil :

# deploy/docker-compose.prod.yml 中 app 服务的 ports 段
ports:
- "127.0.0.1:8787:8787"

Modifier l’exécution docker compose -f docker-compose.prod.yml up -d Reconstruire app Ensuite, le conteneur est remis à l'unité. http://127.0.0.1:8787

Inspection de santé

A la racine des chemins GET / Le retour 200 représente la survie et peut être utilisé directement comme voie de détection d'inspection de la santé pour l'équilibre de la génération ou de la charge dans le cloud.

Prémisse clé : sortie de flux SSE

Les réponses d’AI d’Aivory sont diffusées via le flux SSE (Server-Sent Events). ** Pas de WebSocket ** Donc pas besoin de quoi que ce soit. Upgrade Configuration pertinente. Le serveur envoie un ping toutes les 15 secondes pour empêcher l'agent intermédiaire de se déconnecter en raison de son manque de temps. L'opposant doit faire deux choses:

  1. ** Fermer le buffer de réponse ** Si l'agent buffer réagit, le jeton va économiser en un gros morceau, puis le navigateur, l'effet de la machine à écrire disparaît immédiatement, se traduisant par "les cartes sont longues puis toute la partie est sortie".
  2. ** La lecture en excès de temps ** Une réponse à Deep Research ou à une longue chaîne d’outils peut durer plusieurs dizaines de minutes, ce qui donne suffisamment de temps de lecture.

Les deux configurations suivantes contiennent déjà ces traitements.

Étiquette : Nginx

Configuration complète

Conservé pour /etc/nginx/sites-available/aivory.conf et remplacer chat.example.com Pour votre nom de domaine :

# HTTP:仅用于 certbot 验证与跳转 HTTPS
server {
listen 80;
listen [::]:80;
server_name chat.example.com;

# certbot webroot 验证路径(用 --nginx 插件时可省略)
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}

location / {
return 301 https://$host$request_uri;
}
}

# HTTPS 主站
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # nginx < 1.25.1 请删除此行,改为在上面两行 listen 末尾追加 http2
server_name chat.example.com;

ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem;

# 普通上传默认上限 50MB(MAX_UPLOAD_BYTES),此处留出余量。
# 管理员备份导入可达 20GiB,见下文「大请求体」一节。
client_max_body_size 100m;

location / {
proxy_pass http://127.0.0.1:8787;

# --- SSE 流式输出三件套 ---
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_http_version 1.1;
proxy_set_header Connection "";

# --- 真实客户端 IP 与协议 ---
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Activer et recharger :

sudo ln -s /etc/nginx/sites-available/aivory.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Explication par élément

InstructionsRôle
proxy_pass http://127.0.0.1:8787Transmettre àapp Conteneur, Spa et /api Le même endroit, il n’y a pas besoin de séparation.
proxy_buffering offÉteignez le buffer de réponse et chaque événement de SSE est immédiatement transmis au navigateur, sinon l'effet de la machine à écrire disparaît.
proxy_read_timeout 3600sL'excès de temps de lecture est allongé jusqu'à 1 heure. Une fréquence cardiaque de 15 secondes sur le service peut couvrir la plupart des scènes libres, c'est le fond supplémentaire pour éviter que les réponses trop longues soient écrasées par l'agent
proxy_http_version 1.1amont utilise HTTP/1.1, prend en charge les connexions longues et est une condition préalable pour le streaming
proxy_set_header Connection ""nettoyage Connection tête, maintenir le keepalive avec amont, pour éviter d'être dégradé à une connexion courte
client_max_body_size 100mLimite de la requête.Nginx n'est par défaut que de 1 MB, et la conférence non réglée entraîne un retour direct des fichiers téléchargés à 413
proxy_set_header Host $hostTransmettre les noms de domaine originaux. Tout nom de domaine peut être utilisé dans une architecture de conteneur unique, à condition que l'hôte soit correctement transféré (toutes les transgénérations sont par défaut)
X-Real-IP / X-Forwarded-ForLe transfert de l'IP client réel, directement lié au flux limité, voir la section ci-dessous
X-Forwarded-Proto $schemeL’extérieur est HTTPS.

Demander un certificat avec certbot

# Debian / Ubuntu
sudo apt install certbot python3-certbot-nginx

# 自动修改 Nginx 配置并签发证书
sudo certbot --nginx -d chat.example.com

# 验证自动续期
sudo certbot renew --dry-run

--nginx Le plugin complète automatiquement la vérification et l'écriture du nom de domaine. ssl_certificate Parcourez et définissez des tâches à temps de renouvellement. Si vous souhaitez contrôler vos profils entièrement manuellement, passez au mode webroot :

sudo mkdir -p /var/www/certbot
sudo certbot certonly --webroot -w /var/www/certbot -d chat.example.com

Le certificat est délivré avec succès. /etc/letsencrypt/live/chat.example.com/ correspondant à la configuration ci-dessus.

Chapitre 2 : Caddy

Caddy applique automatiquement et renouvelle le certificat Let's Encrypt, HTTP saute automatiquement HTTPS, Caddyfile Il suffit de trois lignes :

chat.example.com {
reverse_proxy 127.0.0.1:8787
}
sudo systemctl reload caddy
À propos de flush_interval

Caddy V2 détectéContent-Type: text/event-stream Les buffets de réponse sont automatiquement désactivés, de sorte que les trois lignes ci-dessus sont généralement ouvertes. Si votre version est plus ancienne ou que d'autres couches intermédiaires sont superposées, vous pouvez l'éteindre explicitement:

chat.example.com {
reverse_proxy 127.0.0.1:8787 {
flush_interval -1
}
}

flush_interval -1 Chaque byte reçu est immédiatement imprimé au client, ce qui équivaut à Nginx. proxy_buffering off

Caddy ne limite pas la taille de la requête par défaut. X-Forwarded-For Par conséquent, le téléchargement de fichiers, l'importation de sauvegarde et l'IP réelle ne nécessitent pas de configuration supplémentaire.

Grande demande : téléchargement et import de sauvegarde

Aivory a deux catégories de grandes requêtes. client_max_body_size Traiter séparément :

scèneLimites de serviceRespecter les variables environnementalesRecommandé
Envoi de documents/dossiers ordinairesPar défaut 50 MBMAX_UPLOAD_BYTESclient_max_body_size 100m Il est couvert
Administrateur de sauvegarde d'importation20 Gb par défautMAX_BACKUP_BYTESVoir les deux méthodes ci-dessous.

L’administrateur en arrière-plan Importation de sauvegarde L’archivage peut aller jusqu’à 20 Gb. 100m Deux pratiques :

  1. ** Les contraintes temporaires **: Le client_max_body_size Remplacer 21gnginx -s reload Une fois l'importation terminée, les modifications sont effectuées.Scenes de grands documents suggèrent d'ajouter simultanément proxy_request_buffering off Permet à Nginx d’envoyer le fichier de côté et d’éviter d’envoyer tout l’archive sur le disque local.
  2. ** Connexion Internet (recommandée) ** Accès direct sur le serveur local ou en interne http://127.0.0.1:8787 Exécuter l'importation et contourner complètement les limites de volume et de dépassement de temps.

Le plafond du service lui-même MAX_UPLOAD_BYTES / MAX_BACKUP_BYTES Contrôle et détails. Variables environnementales avancées

Véritable IP et limites de flux

Aivory compte les limites de flux en fonction de l'IP de maintenance du client (le compteur est stocké dans Redis).

  • ** Seulement si la connexion directe est un réseau interne ou une adresse de retour. ** (C’est-à-dire que la demande vient de la réaction de votre déploiement) X-Forwarded-For / X-Real-IP et prendre X-Forwarded-For 中** L'article non interne en haut à droite ** Une véritable IP.
  • Lorsque l’adresse du site est en ligne, ces adresses ** Tout ignoré** TCP par end-to-end, c’est pourquoi les pirates de réseaux publics sont faussés X-Forwarded-For Impossible de faire semblant d’utiliser les IP d’autrui.

La signification de cette règle pour le fonctionnement :

Il faut ajouter correctement X-Forwarded-For

Si l’opposition n’est pas établie proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for Toutes les demandes que vous voyez à l'arrière-plan proviennent de votre propre adresse IP. Les utilisateurs du site partagent le même nombre de limites de flux : un seul déclenche une limite de flux et tous les utilisateurs sont limités. La configuration Nginx ci-dessus contient la bonne écriture et le comportement par défaut de Caddy est correct.

** Scènes Cloudflare ** Les voies de circulation deviennent 访客 -> Cloudflare -> 源站 Nginx -> app Le nœud de source de Nginx est le nœud de Cloudflare. Il faut un module real_ip avec Nginx, basé sur Cloudflare. CF-Connecting-IP Récupérez d’abord l’IP du visiteur réel, puis entrez dans le lien de redirection ci-dessus :

# 在 http 或 server 块中声明信任的 Cloudflare 回源网段(节选,完整列表见 Cloudflare 官方发布)
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
# ...其余 Cloudflare 网段...
real_ip_header CF-Connecting-IP;

ainsi $remote_addr Le véritable IP du visiteur. $proxy_add_x_forwarded_for Les valeurs ajoutées sont également correctes. La liste complète des sections de réseau est maintenue et configurée progressivement Accès Cloudflare

Peut-on utiliser HTTPS ?

Il est possible, mais pas recommandé.Aivory reste entièrement disponible dans un contexte non sécurisé (HTTP pur) : les algorithmes de signature de requête dans l'application sont intégrés avec une mise en œuvre de retour JS pur et ne dépendent pas de l'interface de cryptage du navigateur ouverte uniquement sous HTTPS.

Il est fortement recommandé d’activer HTTPS.

HTTP signifie que les identifiants de connexion et le contenu de la conversation sont tous nus sur la chaîne, tout nœud intermédiaire peut être écouté ou manipulé.

Questions fréquemment posées

phénomèneCauseTraitement
Il n'y a pas de réponses, c'est le cas après l'arrivée de Katie.Réagir avec le buzz.Nginx confirméproxy_buffering off Vérifiez s’il y a d’autres couches de buffer au milieu (comme certains CDN).
Réponse interrompue au milieu.La lecture est trop courte.Confirméproxy_read_timeout 3600s Si vous passez par le CDN, synchronisez le temps libre du CDN.
Téléchargement des documents 413Le plafond de la demande est trop petit.Améliorer client_max_body_size
L'importation de sauvegarde échoueL’archivage dépasse les limitesAugmentation temporaire 21g Connexion directe au port 8787
Tous les utilisateurs sont limités en même tempsX-Forwarded-For Ajout incorrectComplétez comme ci-dessus proxy_set_header Deux lignes
Cloudflare permet de calculer l’IP par nœud CFL’adresse IP n’est pas rétablie.Configuration du module real_ip +CF-Connecting-IP voir Accès Cloudflare