Aller au contenu principal

Déploiement de production de Docker Compose

Cette page décrit en profondeur le document compose de production d'Aivory deploy/docker-compose.prod.yml: Responsabilité de chaque service avec des contrôles de santé, des volumes de données et des stratégies de sauvegarde, des images miroirs pré-construites et des changements locaux, une planification des ressources, des commandes d'exploitation quotidiennes, des processus de mise à niveau et un tableau de suivi des pannes courantes. Si vous voulez simplement tirer le service le plus rapidement possible, consultez d'abord Déploiement rapide Cette page suppose que vous avez terminé le déploiement initial.

Vue générale de la structure

Le stack est composé de 5 services, tous suspendus sur un réseau de pont privé. internal Au-dessus : Seul app Publication du port hôte** (par défaut) 80:8787 Le reste des services (y compris Qdrant et bac à sable) n'expose aucun port à l'extérieur et n'est accessible qu'au sein d'un réseau privé.

serviceMiroirPort de l'hôteLe devoir
appghcr.io/<IMAGE_OWNER>/aivory-app80 (peut être modifié)L’installation d’un spa à l’intérieur du bâtiment et /api Derrière
postgrespostgres:16-alpineStockage relationnel : utilisateur, conversation, base de connaissances, usage, etc.
redisredis:7-alpineCache, compteur de flux limité, pub/sub de sortie de flux inter-processeurs
qdrantqdrant/qdrant:v1.12.4Recherche de RAG
sandboxghcr.io/<IMAGE_OWNER>/aivory-sandbox-sidecarLe code intégré exécute le contrôle bac à sable, accessible uniquement en interne
L’architecture des noms de domaine, zéro source

app Les processus Go dans le conteneur servent simultanément les fichiers statiques SPA et /api Il n'y a donc pas d'interdépendance naturelle à l'avant et à l'arrière, donc il n'y a pas de problème transfrontalier. ** Pas besoin ** Configuration PUBLIC_ORIGINALLOWED_ORIGINS Ou n'importe quelle variable liée au nom de domaine : l'agent transmet la demande au conteneur, le nom de domaine qui entre dans le conteneur peut être utilisé et le nom de domaine multi-domaine peut être indiqué en même temps sans problème. Lors du déploiement du réseau public, il suffit de mettre une couche de TLS en avant (voir Proxy inverse et HTTPS)。

Détails du service

App : Appliquer le conteneur principal

  • Surveillance dans le conteneur 8787 (AIVORY_LISTEN: ":8787" En même temps, le spa et /api Le catalogue SPA a été intégré lors de la création de l'image miroir (STATIC_DIR Pointez vers le produit de construction dans l'image miroir) sans besoin d'une couche nginx/web séparée.
  • La carte de port est écrite morte dans le document compose : "80:8787" Lorsque l'hôte 80 est occupé, modifiez directement le numéro à gauche (par exemple "8080:8787" Aucune variable environnementale n’est nécessaire.
  • Début de la dépendance : postgresredis Il est nécessaire d'effectuer un examen médical (condition: service_healthy), qdrant Il n’y a qu’à commencer (condition: service_started Il n’y a pas de définition de Health Check.
  • ** app Pas dépendant sandbox **: le bac à sable est une dépendance souple à la demande, qui n'est utilisée que par l'exécution de code. Si vous le faites comme une dépendance de démarrage, l'image bac à sable ne peut pas être tirée ou est malsaine, alors compose a l'intention de ne pas déclarer cette dépendance.
  • L’examen médical est effectué à l’aide d’un miroir (Dockerfile.app Définition moyenne : utilisé tous les 15 s wget Détection http://127.0.0.1:8787/api/health Le délai d'expiration est de 3s, le délai de démarrage est de 20s, et l'échec est jugé malsain 5 fois de suite.
  • Catalogue des données : ${DATA_DIR:-./data} Coller à l’intérieur du conteneur. /app/data Stockez les fichiers téléchargés, les produits générés, les archives de sauvegarde (et les fichiers SQLite, le cas échéant) pour les coller à un répertoire d'hôte au lieu d'un volume Docker, afin que ces fichiers soient directement visibles et sauvegardables sur l'hôte.

Composer pour app Variables environnementales clés injectées (voir la liste complète) Variables environnementales clés):

VariableValeur de composition.Expliquer
AIVORY_ENVproductionDéclencher des tests de sécurité au niveau du déploiement (tels que JWT_SECRET obligatoire )
DATABASE_URLpostgres://<user>:<password>@postgres:5432/<db>?sslmode=disable.env Les variables de Postgres sont partagées.
REDIS_URLredis://:<REDIS_PASSWORD>@redis:6379/0Activer le cache Redis, la cohérence et la récupération de flux
QDRANT_URLDéfinitivement http://qdrant:6333Appuyez sur Qdrant à l'intérieur de la pile; peut être couvert en tant que cluster externe
QDRANT_API_KEYDéfinitivement aivory-internal-qdrantIl faut avec qdrant La clé du service (voir ci-dessous)
JWT_SECRETdoit être en .env mise en placeComposer en cas d'erreur Rejet de démarrage
SANDBOX_BASE_URLhttp://sandbox:8000Accès à Internet intégré bac à sable
SANDBOX_API_KEYDéfinitivement aivory-bundled-sandboxValeur par défaut interne partagée avec le service bac à sable
ENABLE_MOCK_PROVIDERDéfinitivement falsetrue Activer le modèle de démonstration intégré sans la clé API réelle
La clé API de modèle n'est pas dans .env

Key API pour fournisseurs tels que Anthropic / OpenAI ** Pas de variables environnementales ** Ils sont stockés dans la table channels de la base de données, puis déployés dans la console d'administration. Canal et modèle Ajouter la page.

Postgres : Base de données relationnelle

  • Miroir postgres:16-alpine Les données se trouvent dans le nom. pgdata Dans le conteneur /var/lib/postgresql/data)。
  • POSTGRES_PASSWORD Utilisation : Composer ${POSTGRES_PASSWORD:?...} La syntaxe n'est pas configurée pour signaler des erreurs directes.Le nom d'utilisateur et le nom de bibliothèque sont par défaut aivory
  • Examen médical : une fois tous les 10 secondes pg_isready Testez au maximum 10 fois. app Il ne s’arrêtera que lorsqu’il sera en bonne santé.
  • Le schéma de base de données est app Création et migration automatiques au démarrage, sans exécution manuelle de SQL.
Le miroir officiel de Postgres n'applique le mot de passe que lors de la première initialisation

POSTGRES_PASSWORD uniquement en pgdata Le volume est vide et entre en vigueur lors de la première initialisation de la base de données. .env de cette valeur. ** pas ** La mise à jour du mot de passe réel dans la base de données n’entraîne que app L'authentification n'a pas réussi à connecter l'ancienne bibliothèque avec un nouveau mot de passe. ALTER USER Exécuter ou supprimer (environnements qui ne peuvent être jetés que des données) pgdata Réinitialisation du volume.

Redis : cache et nouvelles

  • Miroir redis:7-alpine et de --appendonly yes --requirepass <REDIS_PASSWORD> Démarrage : Activer la permanence AOF et obliger l'authentification par mot de passe. REDIS_PASSWORD De même que .env obligatoire de remplir.
  • Prenez en charge le cache, les compteurs de flux limités et les signaux pub/sub qui arrêtent de générer à travers le processus ; une fois Redis configuré, l'application autorise également la récupération de la cohorte et du flux Redis.
  • Les données figurent dans le nom. redisdata Dans le conteneur /data)。
  • Contrôle de santé : toutes les 10 secondes redis-cli -a "$REDIS_PASSWORD" ping Vérifier le retour. PONG 5 s, répétez 10 fois.

qdrant : base de données vectorielle

  • Miroir qdrant/qdrant:v1.12.4 Les données se trouvent dans le nom. qdrantdata Dans le conteneur /qdrant/storage)。
  • Qdrant demande une clé API pour chaque requête (QDRANT__SERVICE__API_KEYà l’étage qdrantapp Lire le même .env Variable QDRANT_API_KEY Les deux parties partagent les valeurs aivory-internal-qdrant Parce que Qdrant ne publie pas de port hébergeur et n'est accessible qu'au sein d'un réseau privé, cette valeur partagée par défaut est acceptable ; il est toujours recommandé de .env Il est couvert par une valeur aléatoire forte.
  • Il n'y a pas de certificat de santé, donc app Juste attendre pour elle. service_started L'indisponibilité temporaire de Qdrant ne provoque pas d'interruption de fonctionnalité : lorsque la récupération vectorielle échoue, le RAG retourne à l'intégralité du texte injecté.
  • La collection est nommée d'après la dimension d'embedding aivory_c<维度> (par exemple, le modèle 1536 aivory_c1536)。

Sandbox : Exécution de code avec le contrôle bac à sable

Le bac à sable, un docker compose up Il s’agit d’une clé de sécurité complète, qui ne nécessite aucun élément séparé ni configuration supplémentaire.Voir le modèle de sécurité complet et les instructions de configuration. Déploiement du code bac à sable Il ne s’agit ici que de la composition :

  • Le service est un contrôle sidecar: par l'hébergeur suspendu /var/run/docker.sock Un conteneur limité dérivé par session est dérivé d'un conteneur limité sur le processus de surveillance d'hôte Docker, un miroir du temps de la session pour ghcr.io/<IMAGE_OWNER>/aivory-sandbox (à partir du moment de l’ouverture) SANDBOX_PULL_ON_START: "1" Le premier appel peut être utilisé.
  • ** Ne publiez aucun port hébergeur **: uniquement app par le biais de réseaux privés. http://sandbox:8000 Visitez-le en enchaînant docker.sockÉquivalent à l'autorisation de root de l'hôte, "Ne pas exposer les ports" est la clé de la maîtrise de cet aspect du risque, ne l'ajoutez pas ports La cartographie .
  • Le contrôle du conteneur en lui-même a un plafond de ressources: mem_limit: 1gpids_limit: 512 Les ressources des conteneurs de session sont contrôlées par des variables environnementales :
VariableValeur par défautSignification
SANDBOX_NETWORKnoneLe conteneur de session n'a pas de réseau ; il est modifié uniquement lorsque le code interne de bac à sable nécessite une connexion bridge
SANDBOX_MEMORY2gLimite de mémoire pour les conteneurs de session individuels
SANDBOX_CPUS1Conteneur de session unique CPU quota
SANDBOX_MAX_SESSIONS16Limitation du nombre de conteneurs
SANDBOX_EXEC_TIMEOUT_CAP_MS600000Lorsque la durée maximale d'exécution est fixée à 10 minutes, les réglages d'exécution de la console d'administration sont limités à cette valeur.
SANDBOX_IDLE_TTL_CAP_SECONDS86400Limite dur de la fenêtre de récupération libre (24 heures) avec la même configuration de la console d'administration
SANDBOX_WORKSPACE_SIZE512mCapacité de la zone de travail
SANDBOX_READ_ONLY_ROOTFS1Le système de fichiers racine des conteneurs de session ne peut lire que
  • Persistance de l’espace de travail : lorsque la session est récupérée, /workspace Il sera enregistré dans le nom de l'archive. sandbox-archives (Contrôlé par la touche conversation ID), la même conversation récupère automatiquement lorsque le code est exécuté à nouveau. L'archivage local n'est pas configuré, mais ** Uniquement machine ** Le déploiement de plusieurs copies doit être remplacé par le stockage d'objets de classe S3/OSS.
  • Vérification de la santé: toutes les 30 secondes avec Python urllib Détection dans les conteneurs http://localhost:8000/healthz (Il n'y a pas d'autres outils de détection en dehors de Python dans le miroir), plus de 10s, réessayez 3 fois, start_period120s Ce délai de réduction couvre le temps nécessaire pour tirer l'image du temps d'exécution de la session lors d'un démarrage froid, et le service de tirage ne commence pas à accepter les demandes avant l'achèvement.

Permanence et sauvegarde des données

Où sont les données ?

Télécharger / pendreRoute des conteneursContenuConséquences perdues
pgdata (nom du volume)/var/lib/postgresql/dataToutes les données relationnelles : utilisateur, conversation, base de connaissances, configurationcatastrophique, il faut le protéger.
qdrantdata (nom du volume)/qdrant/storageLe vecteur RAGPeut être reconstruit à partir du texte chunk dans une base de données, mais à consommer à nouveau les appels API embarqués
redisdata (nom du volume)/dataCalculateur de flux limité (AOF)Une récupération naturelle après le redémarrage.
sandbox-archives (nom du volume)/var/lib/aivory/sandbox-archivesLe bac à sable de la conversationPerdre le fichier bac à sable de conversation, sans affecter la conversation elle-même
DATA_DIR (Le catalogue de l'hôte est lié, par défaut ./data)/app/dataDocumentation, documentation et archivage (backups/ Catalogue des enfants)Les utilisateurs téléchargés et les produits perdus doivent être sauvegardés
Ne pas exécuter le docker compose down -v

-v Ils seront supprimés avec le nom. pgdataqdrantdata Toutes les données sont désactivées et ne peuvent pas être récupérées quotidiennement. docker compose -f docker-compose.prod.yml down- Pas de -v) ou stop

Stratégie de sauvegarde

Deux itinéraires sont proposés en parallèle :

  1. ** Backup au niveau de l’application (priorité) ** La page de sauvegarde et de migration de la console d'administration peut générer de manière asynchrone des ZIP de migration complète, avec une sauvegarde logique de base de données neutre du moteur (un JSONL par tableau), des fichiers optionnels uploads/artifacts et des données vectorielles Qdrant optionnelles. BACKUP_DIR Contenu dans le conteneur /app/data/backups correspondant à l’hôte. DATA_DIR/backups En outre, il est possible de le sauvegarder à un autre endroit. Cette sauvegarde peut être récupérée à l'intermédiaire d'un moteur (par exemple, à partir d'un déploiement SQLite). Sauvegarde et migration
  2. ** Préparation au froid des infrastructures ** Après l’arrêt de l’intégralité de la pile, appuyez sur tous les volumes et DATA_DIR Photographier / copier le catalogue. ** Il faut le sauvegarder ensemble. ** Cela permet d’assurer la cohérence entre les lignes de base de données, les vecteurs et les fichiers disque.

La taille maximale de l’importation est MAX_BACKUP_BYTES Contrôle par défaut de 20 GiB; la quantité totale d'archives contenant des vecteurs peut être grande et augmentée si nécessaire.

Pré-construction de miroirs et construction locale

appsandbox Les deux services sont disponibles simultanément. image:build: Le comportement de composition est le suivant : un miroir est présent (ou peut être tiré) en priorité avec un miroir, plus --build Les paramètres sont construits localement.Le même fichier compose sert donc à deux processus et la topologie n'a pas besoin d'être écrite deux fois.

** Méthode 1: Tirer des miroirs pré-construits (recommandés pour la production) **

cd deploy
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d

** Méthode 2: Construire localement à partir du code source (pour un développement secondaire ou une architecture non couverte par des miroirs officiels) **

cd deploy
docker compose -f docker-compose.prod.yml up -d --build

La source du miroir .env Contrôle des deux variables :

VariableValeur par défautExpliquer
IMAGE_REGISTRYghcr.io镜像仓库地址;GitHub 访问受限时可整体切换到 ghcr 镜像代理或自建/私有仓库,见下方「受限网络部署」
IMAGE_OWNERhjxwz123ghcr.io, l’espace de nom ; le fork change de nom d’utilisateur en nom d’utilisateur.
IMAGE_TAGlatestÉtiquettes miroir; l'environnement de production suggère d'être fixé à des étiquettes de version spécifiques, la mise à niveau et le retour sont plus contrôlés

Lors de la construction locale, app Ce qui suit est le catalogue des entrepôts : Dockerfile.app Il s'agit d'une construction en trois étapes, d'abord avec Node 20 pour construire Vite SPA (exécuté sur l'architecture native de la machine à construire, le produit est un fichier statique indépendant de l'architecture), puis avec l'API de compilation Go 1.24 pour le binaire (CGO est nécessaire, car le binaire intègre le pilote SQLite en tant que développement/retour arrière), et finalement pour entrer dans debian:bookworm-slim Miroir en fonctionnement.

受限网络部署(无法访问 GitHub)

服务器连不上 GitHub / ghcr.io 时,部署不受阻——按下面三步走。

第一步:拿到部署文件(不需要 git clone)

部署只需要两个文件:compose 文件和 .env。compose 文件可直接从本文档站下载(文档站部署在 Cloudflare,不依赖 GitHub):

mkdir -p aivory/deploy && cd aivory/deploy
curl -LO https://aivory-docs.pages.dev/deploy/docker-compose.prod.yml
# 然后在同目录创建 .env(至少包含 POSTGRES_PASSWORD、REDIS_PASSWORD、JWT_SECRET)

第二步:解决 ghcr.io 镜像拉取

三个应用镜像(aivory-appaivory-sandbox-sidecar、会话运行时 aivory-sandbox)默认来自 ghcr.io。任选其一:

**方式 A:切换镜像代理(最省事) **——.env 里加一行,三个镜像整体换源:

# 任何兼容 ghcr 的代理/镜像站或你的私有仓库地址
IMAGE_REGISTRY=ghcr.nju.edu.cn

**方式 B:离线搬运(完全不通外网的内网) **——在任意能访问 ghcr.io 的机器上导出,再传到服务器导入:

# 有网机器
docker pull ghcr.io/hjxwz123/aivory-app:latest
docker pull ghcr.io/hjxwz123/aivory-sandbox-sidecar:latest
docker pull ghcr.io/hjxwz123/aivory-sandbox:latest
docker save ghcr.io/hjxwz123/aivory-app:latest ghcr.io/hjxwz123/aivory-sandbox-sidecar:latest ghcr.io/hjxwz123/aivory-sandbox:latest | gzip > aivory-images.tar.gz

# 目标服务器
docker load < aivory-images.tar.gz

离线导入后 bac à sable sidecar 不需要再拉运行时镜像,可在 .envSANDBOX_PULL_ON_START=0 跳过启动时的拉取尝试。

方式 C:推到自己的私有仓库 (阿里云 ACR、Harbor 等)——docker tag 后推上去, .envIMAGE_REGISTRY=registry.cn-xxx.aliyuncs.comIMAGE_OWNER=<你的命名空间>

第三步:基础镜像加速(可选)

postgres / redis / qdrant 来自 Docker Hub,访问慢时给 Docker 守护进程配加速器(/etc/docker/daemon.json):

{ "registry-mirrors": ["https://docker.m.daocloud.io"] }

改完 sudo systemctl restart docker,然后正常 docker compose -f docker-compose.prod.yml up -d 即可。

Recommandations de ressources

scèneCPUmémoireExpliquer
Minimum disponible (teste, nombre d'utilisateurs par chiffre)2 Nucléaire4 GBLa pile entière peut courir, mais bac à sable doit être serré en parallèle
Utilisation des équipes régulières4 Nucléaire8 GBCouverture des conversations quotidiennes + RAG + exécution de code parallèle
Exécution de code / Deep Research4 NucléairePlus de 16 GBAppuyez sur bac à sable.

Estimation des coûts de mémoire pour bac à sable: plafond pour chaque conteneur de session SANDBOX_MEMORY (par défaut 2g) en même temps que le plafond SANDBOX_MAX_SESSIONS (par défaut 16), dans des cas extrêmes, seulement le bac à sable peut consommer 32 GB. .env Réduisez ces deux valeurs (par exemple SANDBOX_MAX_SESSIONS=4 Le coffre-fort est un coffre-fort de 1 GB (mem_limit)。

sur le disque, pgdataqdrantdataDATA_DIR Au fur et à mesure que l'utilisation augmente, il est recommandé de le placer sur un SSD et de réserver la surveillance; les vecteurs Qdrant et les fichiers téléchargés sont généralement les deux blocs qui croissent le plus rapidement.

Vérifier le journal

cd deploy

# 跟踪 app 日志(最常用)
docker compose -f docker-compose.prod.yml logs -f app

# 只看最近 200 行
docker compose -f docker-compose.prod.yml logs --tail=200 app

# 看最近一小时所有服务的日志
docker compose -f docker-compose.prod.yml logs --since=1h

# 单看沙箱(排查代码执行问题时)
docker compose -f docker-compose.prod.yml logs -f sandbox

# 查看某个容器健康检查的探测输出
docker inspect --format='{{json .State.Health}}' aivory-app-1 | jq

Commandes d'exécution courantes

cd deploy

# 查看各服务状态(重点看 STATUS 列的 healthy / unhealthy)
docker compose -f docker-compose.prod.yml ps

# 重启单个服务
docker compose -f docker-compose.prod.yml restart app

# 进入 Postgres 交互式命令行
docker compose -f docker-compose.prod.yml exec postgres psql -U aivory -d aivory

# 验证 Redis 连通性(密码从容器自身的环境变量读取)
docker compose -f docker-compose.prod.yml exec redis sh -c 'redis-cli -a "$REDIS_PASSWORD" ping'

# 打开 app 容器 shell
docker compose -f docker-compose.prod.yml exec app sh

# 从宿主机探测健康端点
curl -fsS http://localhost/api/health

# 查看各命名卷占用的磁盘
docker system df -v | grep aivory

psql Plusieurs examens d’auto-inspection fréquents :

\dt -- 表清单
SELECT count(*) FROM users; -- 用户数
\q -- 退出

Le processus d’augmentation

La structure des bases de données est app La migration automatique au démarrage, la mise à niveau elle-même est "Retracter l'image + reconstruire le conteneur", mais ** Veuillez le sauvegarder avant la mise à niveau. **:

cd deploy

# 1. 备份:在管理后台 Backup & Migration 导出全量备份,
# 并确认归档已生成在 ./data/backups/ 下(拷贝一份到异地更稳妥)

# 2. 拉取新镜像(IMAGE_TAG 固定了版本的话,先在 .env 里改成目标版本)
docker compose -f docker-compose.prod.yml pull

# 3. 滚动重建(只重建镜像有变化的容器)
docker compose -f docker-compose.prod.yml up -d

# 4. 验证
docker compose -f docker-compose.prod.yml ps
curl -fsS http://localhost/api/health
docker compose -f docker-compose.prod.yml logs --tail=100 app
Étiquette de version fixe

IMAGE_TAG=latest Cela signifie que chaque fois pull Il est possible d'obtenir une nouvelle version, le temps de mise à niveau est incontrôlable. IMAGE_TAG Fixez-le à une étiquette de version spécifique, modifiez explicitement la valeur lors de la mise à niveau; IMAGE_TAG Retourner à l’ancienne version up -d Oui (la migration vers l'avant de la structure de la base de données, vérifiez la disponibilité des sauvegardes avant de faire un tour en arrière).

Vérification des défaillances fréquentes

SymptômesCauses possiblesTraitement
docker compose up Signaler directement l’erreur set JWT_SECRET in .env (ou erreur similaire à POSTGRES_PASSWORD / REDIS_PASSWORD).env Il n’y a pas de variable de composition, de composition. :? Interception d’examencp .env.example .env remplir les éléments suivants ; openssl rand -hex 32 Générer JWT_SECRET
app Démarrage et sortie, rappel du journal sur le problème JWT_SECRETAIVORY_ENV=productionJWT_SECRET Vous devez avoir au moins 32 caractères, la valeur de positionnement ou l'excès de courte sera refusé pour démarreren échange openssl rand -hex 32 Après l’exportation up -d
app Redémarrage répété, l'authentification de la base de données log/la connexion échouePOSTGRES_PASSWORD Les caractéristiques spécifiques (@ : / # % & a) une URL de connexion épinglée est endommagée; ou $ La variable compose a été ingurgitée ; ou le mot de passe a été modifié. pgdata Dans le vieux code.Tous les codes sont utilisés openssl rand -hex 24 (Six-six progrès, sans caractères spéciaux); le mot de passe de la bibliothèque initialisée doit être dans psql ALTER USER
sandbox Afficher unhealthy (surtout le premier démarrage)Démarrer à froid pour tirer un miroir de la session. aivory-sandbox Le réseau est plus lent que 120 s. start_periodlogs -f sandbox Confirmer si le tirage est toujours en cours; préalablement docker pull ghcr.io/hjxwz123/aivory-sandbox:latest; app Non affecté, seul l'exécution du code est temporairement indisponible
app Qdrant 401 / non autoriséappQDRANT_API_KEY Incohérence avec la clé du côté Qdrant (généralement survenant dans un cluster Qdrant externe ou en modifiant uniquement une clé du côté)Les deux côtés sont placés sur la même valeur ; les deux côtés lisent la même valeur à l'intérieur de la pile. .env Variable et terminé. up -d Reconstruire peut-être
Le port 80 est occupé. app Ne pas venirL'hôte 80 a d'autres servicesModifier le document composé"80:8787" Porte de gauche
La conversation est normale, mais le code exécute une erreur.Le bac à sable est une dépendance douce. app Ce n’est pas parce qu’il est suspendu.vérifier sandboxétat de santé, /var/run/docker.sock existent et sont disponibles.
L'effet de recherche RAG s'est soudainement détérioré (dégradé en injection intégrale)Qdrant est indisponible ou vide, l'application retourne automatiquement l'intégralitévérifier qdrantétat des conteneurs et app Retour automatique à la récupération du vecteur.

Prochaine étape