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 / env | Purpose |
|---|---|
--config | Path to main YAML (default: config.yaml) |
--secrets | Optional overlay YAML merged before load |
RG_CONFIG_FILE | Config file path only (e.g. Docker); not for secrets |
Full migration from the old .env layout: env-to-yaml guide.
Value forms
| Form | Use |
|---|---|
| Plain string | URLs, names, model IDs |
file:/path/to/secret | Production secrets (recommended) |
env:VAR_NAME | Local 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
| Key | Description |
|---|---|
listen_address | HTTP bind address (PocketBase serve --http) |
encryption_key | PocketBase encryption key (file: recommended) |
app
| Key | Default |
|---|---|
name | A1KnowHow |
url | http://localhost:8383 |
sender_name | A1KnowHow |
sender_address | [email protected] |
database
| Key | Default |
|---|---|
auto_migrate | true |
logging
| Key | Default |
|---|---|
level | info (trace, debug, warn, error, fatal, panic, disabled) |
color | false |
pocketbase_forward | false |
log_auth_id | false |
log_ip | false |
max_days | 3 |
vector
| Key | Notes |
|---|---|
type | sqlite-vec |
dimensions | Required; must match embedding model |
host, port | Not used |
api_key | Not used |
llm
| Key | Default (Ollama) |
|---|---|
provider | ollama |
url | http://localhost:11434 |
model | qwen3:4b |
embedding_model | embeddinggemma:latest |
timeout | 300 (seconds; HTTP client timeout per LLM API call) |
api_key | Not 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.
| Key | Default |
|---|---|
provider | docling |
url | http://localhost:5001 (Docker Compose: http://docling:8000) |
fallback_urls | — |
timeout_seconds | 300 |
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
| Key | Default |
|---|---|
auto_send_verification_email | false |
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).
| Section | Purpose | Value forms |
|---|---|---|
variables | Non-sensitive strings | Plain YAML strings |
secrets | Sensitive strings | file: (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
- Do not commit
config.yamlwith inline secrets or unencrypted secret files - Restrict permissions:
chmod 600on secret files - Use orchestrator secret mounts (Docker secrets, Kubernetes secrets) mapped to
file:/run/secrets/... - Prefer
file:overenv: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.urlmatches 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
--configpath - Seed fails on secret: ensure
secrets:contains the key used in__::secrets::NAME::__and thefile:path exists before runningpocketrag seed
Next steps
- Dependencies — Qdrant, Docling, Ollama
- Docker Setup
- Features — using A1KnowHow after install