Documentation

Configuration

A1KnowHow loads settings from config.yaml. Non-secret values are plain YAML; secrets use file: paths so credentials are not passed through container environment variables.

Quick start

cp example.config.yaml config.yaml
mkdir -p secrets
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32 > secrets/encryption_key
chmod 600 secrets/encryption_key
# edit config.yaml; add more files under secrets/ for other file: paths
# start Ollama and Docling-serve (see Dependencies) before serve
./pocketrag --config config.yaml serve

CLI flags:

Flag / envPurpose
--configPath to main YAML (default: config.yaml)
--secretsOptional overlay YAML merged before load
RG_CONFIG_FILEConfig file path only (e.g. Docker); not for secrets

Full migration from the old .env layout: env-to-yaml guide.

Value forms

FormUse
Plain stringURLs, names, model IDs
file:/path/to/secretProduction secrets (recommended)
env:VAR_NAMELocal dev only; warned on secret fields

Toggles use YAML booleans (true / false), for example smtp.enabled and features.auto_send_verification_email.

Dynamic maps variables and secrets use string keys and string values only; secret values support the same file: and env: indirection as structured fields.

Required settings

version: 1
server:
  listen_address: "0.0.0.0:8383"   # use 127.0.0.1:8383 for local dev
  encryption_key: "file:./secrets/encryption_key"
vector:
  type: sqlite-vec
  dimensions: 768                 # must match embedding model

Generate a 32-character encryption key file:

openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32 > secrets/encryption_key

Reference by section

Copy example.config.yaml as a starting point and customize for your environment.

Example configuration

version: 1

server:
  listen_address: "0.0.0.0:8383"
  encryption_key: "file:./secrets/encryption_key"

app:
  name: "A1KnowHow"
  url: "http://localhost:8383"
  sender_name: "A1KnowHow Support"
  sender_address: "[email protected]"

database:
  auto_migrate: true

logging:
  level: info
  color: false
  pocketbase_forward: false
  stderr_output: false
  log_auth_id: false
  log_ip: false
  max_days: 3

smtp:
  enabled: false
  # host: "smtp.example.com"
  # port: 587
  # username: "your-email"
  # password: "file:./secrets/smtp_password"
  # auth_method: "PLAIN"
  # tls: true

s3:
  enabled: false
  # bucket: "your-bucket-name"
  # region: "us-east-1"
  # access_key: "file:./secrets/s3_access_key"
  # secret: "file:./secrets/s3_secret"

vector:
  type: sqlite-vec
  dimensions: 768

llm:
  provider: ollama
  url: "http://localhost:11434"
  model: "qwen3:4b"
  chat_title_generator_model: "qwen3:0.6b"
  embedding_model: "embeddinggemma:latest"

search:
  rag_context_limit: 3

# Docling-serve must be installed and running (see Dependencies)
importer:
  provider: docling
  url: "http://localhost:5001"

workflow:
  step_runner_polling_interval_seconds: 5

features:
  auto_send_verification_email: false

rate_limits:
  enabled: false

backups:
  cron: "0 0 * * *"
  cron_max_keep: 1

admin:
  email: "[email protected]"
  password: "file:./secrets/admin_password"

# Optional: dynamic key/value maps (see below)
variables:
  SEED_TEST_USER_NAME: "testuser"
secrets:
  SEED_TEST_USER_PASSWORD: "file:./secrets/seed_test_user_password_hash"

server

KeyDescription
listen_addressHTTP bind address (PocketBase serve --http)
encryption_keyPocketBase encryption key (file: recommended)

app

KeyDefault
nameA1KnowHow
urlhttp://localhost:8383
sender_nameA1KnowHow
sender_address[email protected]

database

KeyDefault
auto_migratetrue

logging

KeyDefault
levelinfo (trace, debug, warn, error, fatal, panic, disabled)
colorfalse
pocketbase_forwardfalse
log_auth_idfalse
log_ipfalse
max_days3

vector

KeyNotes
typesqlite-vec
dimensionsRequired; must match embedding model
host, portNot used
api_keyNot used

llm

KeyDefault (Ollama)
providerollama
urlhttp://localhost:11434
modelqwen3:4b
embedding_modelembeddinggemma:latest
timeout300 (seconds; HTTP client timeout per LLM API call)
api_keyNot used with Ollama

Timeouts: llm.timeout limits a single chat/completions HTTP request when no parent context deadline is set (e.g. UI chat). Workflow agent steps set a separate deadline via the step timeout field in workflow YAML (1–3600 seconds), or 1800 seconds by default when unset; that value is passed on context.Context and is not overridden by the cached LLM HTTP client. For slow models or tool-heavy workflows, raise both as needed—for example llm.timeout: 600 and timeout: 1800 on the agent step.

importer

Document import uses Docling-serve to extract text from uploaded files (PDF, Word, and similar formats). With the default provider: docling, install and run Docling-serve as a separate service, then set importer.url to its base URL. See Dependencies for installation, port choice, and health checks.

On startup, A1KnowHow checks that importer.url (and any fallback_urls) are reachable. If Docling-serve is not running or the URL is wrong, serve fails before the app accepts traffic.

KeyDefault
providerdocling
urlhttp://localhost:5001 (Docker Compose: http://docling:8000)
fallback_urls
timeout_seconds300

importer.url must match the port Docling-serve actually listens on (5001 in example.config.yaml; 8000 in the Docker compose sample).

smtp, s3

Enable with enabled: true. Passwords and API keys should use file: paths.

features

KeyDefault
auto_send_verification_emailfalse

Google sign-in (auth.oauth)

SaaS and Enterprise only. See Google OAuth setup for Google Cloud Console steps, redirect URIs, and production checklist.

auth:
  oauth:
    enabled: true
    providers:
      google:
        enabled: true
        client_id: "env:GOOGLE_OAUTH_CLIENT_ID"       # local dev
        client_secret: "file:./secrets/google_oauth_secret"  # production

Redirect URI must be exactly {app.url}/oauth/callback (e.g. http://127.0.0.1:8383/oauth/callback locally). Client secret is applied at server bootstrap; changes require editing config.yaml and restarting — not the PocketBase admin UI.

trusted_proxy, rate_limits, backups

See example YAML above for backup cron and rate-limit toggles.

variables and secrets (dynamic maps)

Top-level maps for arbitrary string values when a fixed config section does not fit (for example one-off seed data, compose-only overrides, or values that change often).

SectionPurposeValue forms
variablesNon-sensitive stringsPlain YAML strings
secretsSensitive stringsfile: (recommended) or env:

Prefer structured sections (llm, smtp, server, and so on) for well-known settings. Use variables / secrets only as an escape hatch.

Example:

variables:
  SEED_TEST_USER_NAME: "testuser"
  SEED_TEST_WORKSPACE_NAME: "Demo Workspace"

secrets:
  SEED_TEST_USER_PASSWORD: "file:./secrets/seed_test_user_password_hash"

Keys are arbitrary names you choose. Values in secrets are resolved at config load time (same file: / env: rules as other secret fields).

Database seeding

Run seed data with the app config loaded (--config). Use --seed-config for an optional seed YAML file or directory (not --config):

./pocketrag --config config.yaml seed
./pocketrag --config config.yaml seed --seed-config path/to/seed.yaml

In seed YAML files, reference config secrets with:

password: "__::secrets::SEED_TEST_USER_PASSWORD::__"

The name after secrets:: must match a key in config.yaml secrets:. No manual export or cat is required.

Seed YAML also supports __::env::VAR_NAME::__ for process environment variables when you cannot use config (for example a one-shot seed container with only env injection). See seed README for full token syntax.

Docker

Mount config and secrets; do not put secrets in environment::

volumes:
  - ./config.yaml:/app/config/config.yaml:ro
  - ./secrets:/run/secrets/pocketrag:ro

Use service names in URLs, for example llm.url: "http://ollama:11434" and importer.url: "http://docling:8000".

See Docker Setup.

Optional secrets overlay

--secrets config.overlay.yaml merges an overlay before file: / env: resolution (non-secret overrides and extra paths).

For encrypted config at rest, use SOPS and decrypt to a mount path before serve—prefer file mounts over injecting decrypted values into the process environment.

Security

  1. Do not commit config.yaml with inline secrets or unencrypted secret files
  2. Restrict permissions: chmod 600 on secret files
  3. Use orchestrator secret mounts (Docker secrets, Kubernetes secrets) mapped to file:/run/secrets/...
  4. Prefer file: over env: for any credential in production

Troubleshooting

  • Missing encryption key file: startup fails with a clear file: path in the error
  • Invalid vector.dimensions: must be set and positive before indexing
  • Docling unreachable at startup: install and start Docling-serve (see Dependencies); confirm importer.url matches the service port and host
  • Service connection errors: check llm.url, importer.url, and Docker network names
  • Config not applied: restart after editing YAML; confirm --config path
  • Seed fails on secret: ensure secrets: contains the key used in __::secrets::NAME::__ and the file: path exists before running pocketrag seed

Next steps