Aller au contenu principal

Déploiement léger (SQLite)

L'arrière de l'Aivory est automatiquement sélectionné en fonction des variables environnementales lors du démarrage: DATABASE_URLpostgres:// Pour commencer, utilisez PostgreSQL, sinon, par exemple. .db Utilisation de SQLite intégré ; REDIS_URL La mise en place d’un cache ou d’une cohorte dans le processus ; QDRANT_URL Le vide est désactivé pour la récupération vectorielle, le RAG revient pour injecter l'intégralité du texte. La production et le développement du binaire sont les mêmes, les pilotes SQLite ont été compilés dans l'image miroir.

Cela signifie que vous pouvez Un stade de production complet De 5 services coupés à 1 : courir uniquement app Le conteneur, les données tombent dans un fichier SQLite. Cette page explique à qui ce déploiement convient, comment composer, quelles sont les limites et comment migrer facilement vers Postgres par la suite.

Quand choisir le mode SQLite ?

scèneRecommandé
Utilisation personnelle / évaluation expérimentaleTélécharger un conteneur par minute.
Petites équipes (jusqu'à une dizaine de personnes), déploiement individuelC’est généralement suffisant.
Petit VPS à ressources limitées (1 niveau de noyau 1 GB)Sculpture, la totalité du parcours ne bouge pas
Plusieurs copies / niveaux d'extension sont nécessairesIl faut Postgres, SQLite est l'écrivain unique
Intensité d’écriture (nombre de conversations parallèles, base de connaissances fréquente)Recommandé par Postgres
Des outils externes sont nécessaires pour lire et écrire directement une base de donnéesRecommandé par Postgres

Choisir SQLite n’est pas une vente au marteau : le format de sauvegarde est neutre pour le moteur, puis la bibliothèque peut être déplacée à Postgres à tout moment (voir ci-dessous)。

Le plus petit document composé

Seule réserve app Un service : enlever postgresredisqdrant Les trois services et leurs depends_on Donne moi DATABASE_URL Modifier la trajectoire du fichier SQLite et ** Pas établi ** REDIS_URLQDRANT_URL

name: aivory

services:
app:
image: ghcr.io/${IMAGE_OWNER:-hjxwz123}/aivory-app:${IMAGE_TAG:-latest}
restart: unless-stopped
ports:
- "80:8787"
environment:
AIVORY_ENV: production
# SQLite:非 postgres:// 的值即选中内嵌 SQLite。
# 两个 pragma 分别开启 WAL 日志模式和 5 秒写锁等待。
DATABASE_URL: "/app/data/aivory.db?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)"
# 不设置 REDIS_URL:使用进程内缓存/队列
# 不设置 QDRANT_URL:禁用向量检索,RAG 走全文注入回退
JWT_SECRET: ${JWT_SECRET:?set JWT_SECRET in .env}
# 试用时可置 true,启用内置演示模型,无需任何真实 API key
ENABLE_MOCK_PROVIDER: ${ENABLE_MOCK_PROVIDER:-false}
volumes:
# 一个目录装下所有持久化数据:aivory.db + uploads/ + artifacts/ + backups/
- ${DATA_DIR:-./data}:/app/data

complémentaire .env Il suffit de remplir une ligne :

# openssl rand -hex 32
JWT_SECRET=<至少 32 字符的强随机值>

Démarrage et vérification :

docker compose up -d
curl -fsS http://localhost/api/health

Le système n'a pas d'utilisateur lors du démarrage, le premier compte enregistré après l'ouverture du site devient automatiquement un administrateur. Première mise en service

Pourquoi les fichiers de base de données sont placés sous /app/data

Le catalogue de téléchargement, le catalogue de produits et le catalogue de sauvegarde intégrés dans le miroir sont /app/data En bas (UPLOAD_DIR=/app/data/uploadsARTIFACT_DIR=/app/data/artifactsBACKUP_DIR=/app/data/backups Mettez également les fichiers SQLite. /app/data Un lien est couvert. ** tout ** Données persistantes :

./data/ # 宿主机目录(DATA_DIR)
├── aivory.db # SQLite 主库
├── aivory.db-wal # WAL 日志(运行期存在,属于数据库的一部分)
├── aivory.db-shm # WAL 共享内存文件
├── uploads/ # 用户上传的文件
├── artifacts/ # 生成的产物
└── backups/ # 管理后台导出的备份归档
Les fichiers de base de données doivent être placés dans le volet.

Si DATABASE_URL Appuyez sur le chemin à l'intérieur du conteneur en dehors du volume, et une fois le conteneur reconstruit, l'ensemble de la base de données disparaît. DATABASE_URL La valeur par défaut est ./data/aivory.db?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000) (Référentiel de processus de travail, à l'intérieur du conteneur /app/data/ En dessous, c’est précisément dans le point d’enchaînement ; l’écriture explicite de la voie absolue est destinée à éliminer les différences.

Signification des deux paramètres pragmatiques

ParamètresRôle
_pragma=journal_mode(WAL)WALModèle de journal d'écriture précédent: la lecture et l'écriture ne sont pas contradictoires, plusieurs lecteurs peuvent écrire simultanément avec un seul auteur
_pragma=busy_timeout(5000)5000 msAttendez jusqu'à 5 secondes pour signaler une erreur au lieu d'échouer immédiatement.

Ces deux paramètres sont la configuration par défaut du serveur et ne sont pas recommandés pour être supprimés.

Réduire les coûts de Redis et Qdrant

Les composants enlevés.Les comportements alternatifsImpact réel
postgresIntroduction à SQLiteLimitation des entrées uniques (voir la section ci-dessous) ; aucune différence de fonctionnalité
redisRéglages et coordonnées au cours du processusLa fonctionnalité est disponible en cas unique; les capacités de récupération de flux telles que la dépendance à Redis ne sont pas activées; le cache et la limite de flux sont nulles avec le redémarrage du processus
qdrantL'intégralité du RAG est reprisebase de connaissances est toujours disponible, mais ne fait pas de recherche de ressemblance vectorielle, mais injecte l'intégralité du document dans la gamme dans le contexte; le volume du document consomme plus de jetons, la précision de la recherche diminue
Les composants peuvent être conservés au besoin.

Les choix sont indépendants : il est tout à fait possible de remplacer Postgres par SQLite. redisqdrant Services (réservation correspondante REDIS_URL / QDRANT_URL / QDRANT_API_KEY variables environnementales et depends_on Si la base de connaissances est un scénario d'utilisation lourde, il est recommandé de conserver au moins Qdrant.

Qu’est-ce que le bac à sable ?

bac à sable n'a rien à voir avec la sélection de la base de données. Lorsque la fonction d'exécution du code est nécessaire, mettez l'intégralité de la pile sandbox Le service se déplace dans vos fichiers compose et vous app Deux variables environnementales :

environment:
# ...上面的变量保持不变...
SANDBOX_BASE_URL: "http://sandbox:8000"
SANDBOX_API_KEY: ${SANDBOX_API_KEY:-aivory-bundled-sandbox}

Voir la définition complète et les précautions de sécurité du service bac à sable (déplacement du socket Docker, non-publier des ports, etc.) Déploiement du code bac à sable Aucune exécution de code n'est nécessaire et le reste des fonctions n'est pas affecté.

Restrictions pour les écrivains

SQLite est une base de données embarquée à un seul fichier qui permet à plusieurs lecteurs de ** Un écrivain ** En parallèle, cela entraîne plusieurs contraintes dures :

    • Il n’y en a qu’un app Exemple** Ouvrez ce fichier de base de données. Ne pas étendre le service à plusieurs copies, ne pas laisser deux conteneurs accrocher le même répertoire de données, et ne pas utiliser d’autres outils pour écrire le fichier pendant l’exécution de l’application.
  • La base de données doit être ** Systèmes de documents locaux ** Ne le prenez pas ! DATA_DIR Placé sur NFS ou sur d’autres systèmes de fichiers réseau, le verrou sémantique du fichier n’est pas fiable et peut entraîner des dommages à la base de données.
  • Il y a un plafond d’écriture. busy_timeout(5000) Cela signifie que les demandes d'écriture ultérieures sont rangées jusqu'à 5 secondes lorsque l'écriture est au sommet ; une accumulation de pression d'écriture continue se traduit par des demandes qui ralentissent, voire dépassent le temps.

JWT_SECRET est également obligatoire sous SQLite

Ne pensez pas que le déploiement léger vous épargnera ce problème. Pour déterminer si vous effectuez une évaluation de sécurité au niveau du déploiement, regardez : AIVORY_ENV Une valeur non-développable DATABASE_URL Pour Postgres, le compose le plus petit est défini ci-dessus. AIVORY_ENV: production Si la base de données est SQLite, JWT_SECRET Il doit également être défini et au moins 32 caractères, sinon l'application refusera de démarrer.

Ne pas contourner les examens en supprimant AIVORY_ENV

Pas d’environnement de développement JWT_SECRET L’application génère automatiquement une clé temporaire. ** Chaque fois que vous redémarrez toutes les sessions de connexion, elles sont invalides. ** Et c'est un comportement de préparation pour le développement natif, pas une option de déploiement. Toute instance de service offert à l'extérieur doit être définie de manière explicite AIVORY_ENV: production et de force aléatoire JWT_SECRET

Réservation

Un avantage majeur du modèle SQLite est que les sauvegardes sont minimes : toutes les données persistantes sont DATA_DIR dans un catalogue.

  • ** Exportation de la console d'administration ** Le ZIP de sauvegarde intégrale généré par les pages de sauvegarde et de migration est neutre du moteur (manifest + un fichier JSONL + optionnel par table) et n'est pas affecté par le problème de copie des fichiers de base de données en cours d'exécution et peut être importé directement dans le déploiement Postgres.
  • ** Froid prêt **: d’abord docker compose stop Une copie complète. DATA_DIR Catégorie : Attention aivory.db-walaivory.db-shm faisant partie de la base de données, ** pas ** Utiliser uniquement dans l’application aivory.db Dans les fichiers individuels, l'écriture non fusionnée dans le WAL est perdue, et les fichiers copiés peuvent également ne pas être cohérents.

La taille maximale de l’importation est MAX_BACKUP_BYTES Contrôle (par défaut 20 GiB).

Migration avec Postgres

Le format de sauvegarde est neutre pour le moteur : les sauvegardes SQLite peuvent être importées dans les déploiements Postgres, et inversement, les séries et les clés extérieures sont traitées automatiquement par le processus d'importation. Les processus typiques de « croissance de l'entreprise » passent de SQLite à la pile complète :

  1. ** Exportation d’exemples anciens **: Pour générer des sauvegardes complètes dans la console d'administration Backup & Migration (sélectionnez des fichiers et des vecteurs, le cas échéant), téléchargez ZIP.
  2. ** Créer de nouveaux exemples **: selon Déploiement de production de Docker Compose Démarrer la pile complète. Après le premier démarrage, utiliser ** La même boîte aux lettres que l'ancien administrateur d'instances ** Enregistrez le premier compte (il deviendra administrateur).
  3. ** Introduction **: Importer ZIP sur la page Backup & Migration de la nouvelle instance et entrer le mot de confirmation REPLACE L'importation est un remplacement de la bibliothèque entière: en une seule transaction, tous les tableaux sont vide et rechargés, les fichiers et les vecteurs sont restaurés, la session actuelle est terminée et vous devez vous connecter à nouveau avec le mot de passe du compte dans la sauvegarde.
  4. ** Traitement vectoriel **: Si l'ancienne instance n'a pas de Qdrant (pas de déploiement minimal sur cette page), aucune donnée vectorielle n'est enregistrée dans la sauvegarde. La nouvelle instance peut reconstituer des vecteurs à partir du texte chunk existant dans la fonctionnalité maintenance des vecteurs de la console d'administration, sans avoir besoin d'un fichier d'origine, mais nécessitant des appels d'API embarqués.
Pourquoi les boîtes aux lettres doivent être cohérentes

Une fois l'importation terminée, il existe un mécanisme de préemption : en plus de la boîte aux lettres d'administrateur pour l'exécution de l'opération d'importation, les autres comptes d'administrateur portés dans la sauvegarde sont abaissés en utilisateurs ordinaires.

Le processus d’inversion (la migration de Postgres vers SQLite, par exemple la réduction d’un petit déploiement vers un seul conteneur) est exactement le même, mais le fichier compose le plus petit de la page de coût de la nouvelle instance.

Voir les options d'exportation complètes, les tâches d'exportation asynchrone, les détails de configuration d'exportation et d'importation Sauvegarde et migration

Prochaine étape