תהליכי AI עם מסד וקטורים: n8n ו-Qdrant

‏n8n עם ה-PostgreSQL שלו ומסד הווקטורים Qdrant על שרת אחד, מאחורי Caddy. תהליכים שומרים ומחפשים embeddings ב-Qdrant בלי שירות וקטורים מתארח.

נבדק 14 באוקטובר 2026

למה האפליקציות האלה יחד

צוות שמאטמט ב-n8n תשובות מתוך המסמכים שלו (retrieval-augmented generation) ורוצה את הווקטורים על השרת שלו, ליד התהליכים שכותבים וקוראים אותם.

דפי האפליקציות מפרסים את n8n ואת Qdrant בנפרד. יחד, ה-credential של Qdrant ב-n8n צריך כתובת שהוא יכול להגיע אליה ואת מפתח ה-API ש-Qdrant דורש: דרך הרשת ש-Caddy חולק עם שתיהן, ‏n8n פונה ל-Qdrant לפי שם השירות, כך שהווקטורים לא עוברים באינטרנט. הדף מעריך את שתיהן על שרת אחד ונותן את הכתובת, המפתח ומה ששתיהן חולקות.

האפליקציות בסטאק

אפליקציההתפקיד בסטאקרמת עומסתמיכת Compose
n8nמריץ את התהליכים, עם PostgreSQL לנתונים שלו.קלנבדק בהרצה
Qdrantשומר את ה-embeddings ועונה על חיפושי דמיון.קלנתמך

איך האפליקציות מתחברות

n8n אל Qdrant: http://qdrant:6333
צומת Qdrant Vector Store של n8n פונה ל-REST API של Qdrant דרך רשת ה-edge של Caddy, לפי שם השירות, עם מפתח ה-API מ-QDRANT_API_KEY.

משאבים לשרת כולו

מחושב במנוע של ה-Stack Sizer לאפליקציות ולרמות העומס האלה: מה שהאפליקציות צריכות, בסיס המערכת ומרווח הביטחון. אותו קלט ב-Stack Sizer נותן את אותם מספרים.

רכיבvCPURAM ‏(GiB)דיסק (GiB)
n8n1.751.8758.5
Qdrant0.50.50.8
בסיס המערכת0.11.258.7
מרווח ביטחון0.470.7252.7
סה"כ מומלץ2.824.3520.7

‏Caddy לא כלול בחישוב המשאבים של ה-Stack Sizer וה-Deployment Spec.

לפתוח את האפליקציות האלה ב-Stack Sizer

קבצים מה-Compose Generator

docker-compose.yml
# Generated by the ANAROQ Compose Generator: https://anaroq.com/tools/compose-generator
# Engine @anaroq/compose 1.0.0, catalog 2026.10.10, exposure caddy.
# Apps: n8n 1.1.0, qdrant 1.0.0 (supported, not run-tested).
# No secrets in this file: copy .env.example to .env and fill it in before `docker compose up -d`.

services:
  n8n:
    image: "docker.n8n.io/n8nio/n8n:2.42.6"
    restart: "unless-stopped"
    environment:
      DB_TYPE: "postgresdb"
      DB_POSTGRESDB_HOST: "n8n-postgres"
      DB_POSTGRESDB_PORT: "5432"
      DB_POSTGRESDB_DATABASE: "n8n"
      DB_POSTGRESDB_USER: "n8n"
      DB_POSTGRESDB_PASSWORD: "${N8N_DB_PASSWORD:?set N8N_DB_PASSWORD in .env}"
      N8N_ENCRYPTION_KEY: "${N8N_ENCRYPTION_KEY:?set N8N_ENCRYPTION_KEY in .env}"
      N8N_RUNNERS_MODE: "external"
      N8N_RUNNERS_AUTH_TOKEN: "${N8N_RUNNERS_AUTH_TOKEN:?set N8N_RUNNERS_AUTH_TOKEN in .env}"
      N8N_RUNNERS_BROKER_LISTEN_ADDRESS: "0.0.0.0"
      N8N_HOST: "${N8N_DOMAIN:?set N8N_DOMAIN in .env}"
      N8N_PROTOCOL: "https"
      N8N_PROXY_HOPS: "1"
      N8N_WEBHOOK_URL: "https://${N8N_DOMAIN:?set N8N_DOMAIN in .env}/"
    volumes:
      - "n8n-data:/home/node/.n8n"
    networks:
      - "n8n-internal"
      - "edge"
    depends_on:
      n8n-postgres:
        condition: "service_healthy"
  n8n-runner:
    image: "n8nio/runners:2.42.6"
    restart: "unless-stopped"
    environment:
      N8N_RUNNERS_AUTH_TOKEN: "${N8N_RUNNERS_AUTH_TOKEN:?set N8N_RUNNERS_AUTH_TOKEN in .env}"
      N8N_RUNNERS_TASK_BROKER_URI: "http://n8n:5679"
    networks:
      - "n8n-internal"
    depends_on:
      n8n:
        condition: "service_started"
  n8n-postgres:
    image: "postgres:18.6"
    restart: "unless-stopped"
    environment:
      POSTGRES_USER: "n8n"
      POSTGRES_PASSWORD: "${N8N_DB_PASSWORD:?set N8N_DB_PASSWORD in .env}"
      POSTGRES_DB: "n8n"
    volumes:
      - "n8n-postgres-data:/var/lib/postgresql"
    networks:
      - "n8n-internal"
    healthcheck:
      test:
        - "CMD-SHELL"
        - "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"
      interval: "10s"
      timeout: "5s"
      retries: 5
      start_period: "30s"
  qdrant:
    image: "qdrant/qdrant:v1.19.2-unprivileged"
    restart: "unless-stopped"
    environment:
      QDRANT__SERVICE__API_KEY: "${QDRANT_API_KEY:?set QDRANT_API_KEY in .env}"
    volumes:
      - "qdrant-storage:/qdrant/storage"
      - "qdrant-snapshots:/qdrant/snapshots"
    networks:
      - "qdrant-internal"
      - "edge"
    healthcheck:
      test:
        - "CMD"
        - "bash"
        - "-c"
        - "exec 3<>/dev/tcp/127.0.0.1/6333 && printf 'GET /readyz HTTP/1.0\\r\\n\\r\\n' >&3 && grep -q ' 200 ' <&3"
      interval: "10s"
      timeout: "5s"
      retries: 6
      start_period: "30s"
  caddy:
    image: "caddy:2.11.7-alpine"
    restart: "unless-stopped"
    environment:
      N8N_DOMAIN: "${N8N_DOMAIN:?set N8N_DOMAIN in .env}"
      QDRANT_DOMAIN: "${QDRANT_DOMAIN:?set QDRANT_DOMAIN in .env}"
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - "./Caddyfile:/etc/caddy/Caddyfile:ro"
      - "caddy-data:/data"
      - "caddy-config:/config"
    networks:
      - "edge"
networks:
  n8n-internal: {}
  qdrant-internal: {}
  edge: {}
volumes:
  n8n-data: {}
  n8n-postgres-data: {}
  qdrant-storage: {}
  qdrant-snapshots: {}
  caddy-data: {}
  caddy-config: {}
.env.example
# Generated by the ANAROQ Compose Generator: https://anaroq.com/tools/compose-generator
# Engine @anaroq/compose 1.0.0, catalog 2026.10.10, exposure caddy.
# Copy this file to .env and fill in every value. Never commit .env.
# ANAROQ does not create passwords or keys: generate them on your own machine.

# --- n8n ---
# Password of the n8n PostgreSQL user (POSTGRES_PASSWORD).
# Secret, required. For example: openssl rand -hex 24
N8N_DB_PASSWORD=
# Key n8n uses to encrypt stored credentials. Keep it with your backups: without it a restored database cannot decrypt them.
# Secret, required. For example: openssl rand -hex 32
N8N_ENCRYPTION_KEY=
# Shared token between n8n and its task runners.
# Secret, required. For example: openssl rand -hex 32
N8N_RUNNERS_AUTH_TOKEN=
# Public host name of n8n behind the reverse proxy, for example n8n.example.com.
# Required.
N8N_DOMAIN=

# --- qdrant ---
# Admin API key (QDRANT__SERVICE__API_KEY). Every REST and gRPC request must send it in the api-key header; the health endpoints stay open.
# Secret, required. For example: openssl rand -hex 32
QDRANT_API_KEY=
# Public host name of the Qdrant REST API and Web UI behind the reverse proxy, for example vectors.example.com.
# Required.
QDRANT_DOMAIN=
Caddyfile
# Generated by the ANAROQ Compose Generator: https://anaroq.com/tools/compose-generator
# Engine @anaroq/compose 1.0.0, catalog 2026.10.10, exposure caddy.
# Each site address comes from .env through the Caddy container's environment.

{$N8N_DOMAIN} {
	reverse_proxy n8n:5678
}

{$QDRANT_DOMAIN} {
	reverse_proxy qdrant:6333
}

נוצרו במנוע של ה-Compose Generator לאפליקציות האלה מאחורי Caddy. אין סודות בקבצים: העתיקו את ‎.env.example ל-‎.env ומלאו אותו.

תוצאת ה-Compose Analyzer

שגיאה0
גבוהה0
בינונית0
נמוכה14
מידע0

14 ממצאים: 0 שגיאה, 0 גבוהה, 0 בינונית, 14 נמוכה, 0 מידע.

נמוכה14

  1. נמוכהAQ-HLTH-002שורה 8, עמודה 5services.n8n

    ל-n8n אין healthcheck.

    תיקון: הוסיפו healthcheck, כדי ש-Compose ואתם תדעו מתי השירות מוכן.

  2. נמוכהAQ-HLTH-005שורה 8, עמודה 5services.n8n

    ‏n8n לא מגביל את גודל הלוגים שלו (logging.options.max-size).

    תיקון: הגבילו את גודל הלוגים כדי שלא ימלאו את הדיסק.

  3. נמוכהAQ-SEC-005שורה 11, עמודה 7services.n8n.environment

    ‏n8n מעביר סודות דרך environment ‏(DB_POSTGRESDB_PASSWORD, N8N_ENCRYPTION_KEY, N8N_RUNNERS_AUTH_TOKEN).

    תיקון: כשה-image תומך בזה, השתמשו ב-secrets: או במשתנה _FILE במקום.

  4. נמוכהAQ-HLTH-002שורה 34, עמודה 5services.n8n-runner

    ל-n8n-runner אין healthcheck.

    תיקון: הוסיפו healthcheck, כדי ש-Compose ואתם תדעו מתי השירות מוכן.

  5. נמוכהAQ-HLTH-005שורה 34, עמודה 5services.n8n-runner

    ‏n8n-runner לא מגביל את גודל הלוגים שלו (logging.options.max-size).

    תיקון: הגבילו את גודל הלוגים כדי שלא ימלאו את הדיסק.

  6. נמוכהAQ-SEC-005שורה 37, עמודה 7services.n8n-runner.environment

    ‏n8n-runner מעביר סודות דרך environment ‏(N8N_RUNNERS_AUTH_TOKEN).

    תיקון: כשה-image תומך בזה, השתמשו ב-secrets: או במשתנה _FILE במקום.

  7. נמוכהAQ-HLTH-005שורה 45, עמודה 5services.n8n-postgres

    ‏n8n-postgres לא מגביל את גודל הלוגים שלו (logging.options.max-size).

    תיקון: הגבילו את גודל הלוגים כדי שלא ימלאו את הדיסק.

  8. נמוכהAQ-SEC-005שורה 48, עמודה 7services.n8n-postgres.environment

    ‏n8n-postgres מעביר סודות דרך environment ‏(POSTGRES_PASSWORD).

    תיקון: כשה-image תומך בזה, השתמשו ב-secrets: או במשתנה _FILE במקום.

  9. נמוכהAQ-HLTH-005שורה 64, עמודה 5services.qdrant

    ‏qdrant לא מגביל את גודל הלוגים שלו (logging.options.max-size).

    תיקון: הגבילו את גודל הלוגים כדי שלא ימלאו את הדיסק.

  10. נמוכהAQ-SEC-005שורה 67, עמודה 7services.qdrant.environment

    ‏qdrant מעביר סודות דרך environment ‏(QDRANT__SERVICE__API_KEY).

    תיקון: כשה-image תומך בזה, השתמשו ב-secrets: או במשתנה _FILE במקום.

  11. נמוכהAQ-HLTH-002שורה 85, עמודה 5services.caddy

    ל-caddy אין healthcheck.

    תיקון: הוסיפו healthcheck, כדי ש-Compose ואתם תדעו מתי השירות מוכן.

  12. נמוכהAQ-HLTH-005שורה 85, עמודה 5services.caddy

    ‏caddy לא מגביל את גודל הלוגים שלו (logging.options.max-size).

    תיקון: הגבילו את גודל הלוגים כדי שלא ימלאו את הדיסק.

  13. נמוכהAQ-PORT-005שורה 91, עמודה 9services.caddy.ports.0

    הקובץ מפרסם 3 מיפויי פורטים. ‏Docker מפרסם פורטים בלי לעבור דרך כללי ufw.

    תיקון: סננו אותם בשרשרת DOCKER-USER או בחומת האש של הספק, או אל תפרסמו אותם.

  14. נמוכהAQ-VOL-005שורה 95, עמודה 9services.caddy.volumes.0

    ‏caddy מחבר את הנתיב היחסי ./Caddyfile.

    תיקון: זה עובד, אבל הנתונים נמצאים בתיקייה שממנה מריצים את Compose: גבו אותה.

ה-Compose Analyzer ‏(ruleset 1.0.0) בדק את docker-compose.yml: 0 שגיאה, 0 גבוה, 0 בינוני ו-14 נמוך. מתכון מתפרסם רק בלי ממצאי שגיאה וגבוה.

להמשיך בכלים

הקישור פותח את ה-Compose Generator עם האפליקציות, האפשרויות והחשיפה האלה, ועם ה-Deployment Spec של הערכת המשאבים הזו, כך ש-cloud-init וה-Runbook מתחילים מאותו מצב.

לפתוח במסע

Runbook

לפני ההפעלה הראשונה

  1. העתיקו את .env.example ל-.env ליד docker-compose.yml ומלאו כל ערך. ‏Compose נעצר עם שגיאה כל עוד ערך חובה חסר.
  2. צרו את N8N_DB_PASSWORD במחשב שלכם, למשל עם openssl rand -hex 24. ‏ANAROQ אף פעם לא יוצר סיסמאות או מפתחות.
  3. צרו את N8N_ENCRYPTION_KEY במחשב שלכם, למשל עם openssl rand -hex 32. ‏ANAROQ אף פעם לא יוצר סיסמאות או מפתחות.
  4. צרו את N8N_RUNNERS_AUTH_TOKEN במחשב שלכם, למשל עם openssl rand -hex 32. ‏ANAROQ אף פעם לא יוצר סיסמאות או מפתחות.
  5. צרו את QDRANT_API_KEY במחשב שלכם, למשל עם openssl rand -hex 32. ‏ANAROQ אף פעם לא יוצר סיסמאות או מפתחות.
  6. השאירו את Caddyfile ליד docker-compose.yml; קונטיינר Caddy מחבר אותו לקריאה בלבד.
  7. פורטים 80 ו-443 (TCP, ו-443/UDP ל-HTTP/3) חייבים להיות נגישים מהאינטרנט כדי ש-HTTPS האוטומטי של Caddy יעבוד.
  8. לפני ההפעלה, כוונו את רשומות A/AAAA של הדומיין שב-N8N_DOMAIN ‏(n8n) לשרת הזה; ‏Caddy מבקש את התעודה שלו בהפעלה הראשונה.
  9. לפני ההפעלה, כוונו את רשומות A/AAAA של הדומיין שב-QDRANT_DOMAIN ‏(qdrant) לשרת הזה; ‏Caddy מבקש את התעודה שלו בהפעלה הראשונה.
  10. גבו את N8N_ENCRYPTION_KEY יחד עם מסד הנתונים: בלעדיו אי אפשר לפענח את ה-credentials.
  11. הפעילו את ה-stack עם docker compose up -d ועקבו אחריו עם docker compose ps.

אחרי ההפעלה הראשונה

  1. ליצור את ה-credential של Qdrant

    ב-n8n, הוסיפו credential מסוג Qdrant API עם הכתובת שלמטה, וכ-API Key את הערך של QDRANT_API_KEY מ-.env.

    http://qdrant:6333
  2. להשתמש בו בתהליך

    הוסיפו צומת Qdrant Vector Store עם ה-credential הזה ושם collection; הכניסו מסמכים קודם, ואחר כך שלפו מאותו collection עם אותו מודל embeddings.

  3. לבדוק את ה-collection

    פתחו את לוח הבקרה של Qdrant בשם המארח שלו וב-‎/dashboard, התחברו עם מפתח ה-API, ובדקו שה-collection מכיל נקודות.

מה האפליקציות חולקות

  • גם Qdrant מקבל שם מארח ציבורי דרך Caddy, בשביל לוח הבקרה שלו. כל בקשה דורשת את מפתח ה-API, לכן התייחסו ל-QDRANT_API_KEY כמו לסיסמה; ‏n8n עצמו לא צריך ש-Qdrant יהיה ציבורי.
  • ה-embeddings מגיעים ממודל ש-n8n קורא לו (מתארח או משלכם); הגודל שלו קובע את ממד הווקטור, ו-collection ב-Qdrant שומר את הממד שאיתו נוצר.
  • גבו את ה-PostgreSQL של n8n יחד עם מפתח ההצפנה שלו, ואת האחסון של Qdrant עם snapshot: ה-credential שמחזיק את המפתח של Qdrant מוצפן עם N8N_ENCRYPTION_KEY.

חלופות

  • ‏n8n לבד יכול לשמור קבוצות וקטורים קטנות בזיכרון; הן נמחקות באתחול, כך שזה מתאים לבדיקות, לא למאגר ידע. n8n
  • ‏Qdrant זמין גם כשירות מנוהל של היצרנים שלו; זה חוסך container אבל משאיר את הווקטורים אצל ספק. Qdrant

בסיס

קטלוג
2026.10.10
מדיניות הערכת משאבים
2026.10.0
מנוע Compose
@anaroq/compose 1.0.0
ruleset של ה-Analyzer
1.0.0

מקורות

איך נבנים הפרופילים, הערכות המשאבים וקבצי ה-Compose מתואר במתודולוגיה. לקריאת המתודולוגיה

כל האפליקציות ל-self-hosting