82d944a0a8
- fuelish role: receipt OCR API at fuelish.ladkau.de, API-key auth, shared Ollama model and request options - base: 4 GB swap file; act_runner: job containers capped at 4 GB without swap - docs and vault/service checks updated
205 lines
8.5 KiB
YAML
205 lines
8.5 KiB
YAML
---
|
|
# Domains
|
|
domain_base: ladkau.de
|
|
domain_cloud: "cloud.{{ domain_base }}"
|
|
domain_gitea: "gitea.{{ domain_base }}"
|
|
domain_nextcloud: "nextcloud.{{ domain_base }}"
|
|
domain_sso: "sso.{{ domain_base }}"
|
|
domain_mail: "mail.{{ domain_base }}"
|
|
domain_registry: "cr.{{ domain_base }}"
|
|
domain_k8s: "k8s.{{ domain_base }}"
|
|
domain_vault: "vault.{{ domain_base }}"
|
|
domain_dl: "dl.{{ domain_base }}"
|
|
|
|
# Let's Encrypt
|
|
acme_email: matthias.ladkau@gmail.com
|
|
|
|
# Non-root deploy user created by the base role
|
|
deploy_user: deploy
|
|
|
|
# System timezone
|
|
timezone: Europe/Berlin
|
|
|
|
# Docker network shared by all services and Traefik
|
|
traefik_network: traefik_public
|
|
|
|
# Traefik
|
|
traefik_version: v3.6
|
|
traefik_data_dir: /opt/traefik
|
|
# Dashboard basic-auth users — plaintext passwords, Ansible generates bcrypt hashes at deploy time
|
|
# traefik_dashboard_users:
|
|
# - username: admin
|
|
# password: "your-password"
|
|
traefik_dashboard_users: []
|
|
|
|
# Gitea
|
|
gitea_version: "1" # major-only tag — always pulls latest 1.x patch
|
|
gitea_db_version: "16" # PostgreSQL major version
|
|
gitea_data_dir: /opt/gitea
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# gitea_db_password: ""
|
|
# gitea_secret_key: "" # generate: openssl rand -hex 32
|
|
# gitea_internal_token: "" # generate: openssl rand -hex 32
|
|
|
|
# SSO (Keycloak)
|
|
keycloak_version: "26.2"
|
|
keycloak_db_version: "16"
|
|
sso_data_dir: /opt/sso
|
|
keycloak_admin_user: admin
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# keycloak_db_password: ""
|
|
# keycloak_admin_password: ""
|
|
|
|
# Nextcloud
|
|
nextcloud_version: "31-apache" # apache variant includes a working web server
|
|
nextcloud_db_version: "16"
|
|
nextcloud_data_dir: /opt/nextcloud
|
|
nextcloud_admin_user: admin
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# nextcloud_db_password: ""
|
|
# nextcloud_admin_password: ""
|
|
|
|
# Mail (Roundcube + Dovecot IMAP + Fetchmail)
|
|
roundcube_version: "1.6.x-apache"
|
|
roundcube_db_version: "16"
|
|
mail_data_dir: /opt/mail
|
|
# Dovecot IMAP server — Roundcube always connects to the local Dovecot container
|
|
dovecot_version: "2.3"
|
|
# SMTP — outgoing mail server for Roundcube (leave empty if not configured)
|
|
roundcube_smtp_host: ""
|
|
roundcube_smtp_port: "587"
|
|
# Fetchmail — polls external POP3 accounts and delivers to local Dovecot via LMTP
|
|
# poll_minutes is per-account (default: 10 minutes)
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# roundcube_db_password: ""
|
|
# roundcube_des_key: "" # generate: openssl rand -hex 12 (must be exactly 24 chars)
|
|
#
|
|
# Dovecot users — list of {username, password} pairs (plaintext, vault is encrypted)
|
|
# dovecot_users:
|
|
# - username: alice
|
|
# password: "plaintext-password"
|
|
#
|
|
# Fetchmail accounts — list of external POP3 sources to poll
|
|
# fetchmail_accounts:
|
|
# - server: pop.gmail.com
|
|
# username: user@gmail.com
|
|
# password: app-password
|
|
# local_user: alice
|
|
# protocol: pop3 # default: pop3
|
|
# ssl: true # default: true
|
|
# keep: true # default: true — set false to delete from source after fetch
|
|
|
|
# Gitea Actions runners (act_runner with Docker executor)
|
|
act_runner_version: "latest"
|
|
act_runner_data_dir: /opt/act_runner
|
|
act_runner_count: 3
|
|
# Swap file created by the base role (the VPS has no swap partition)
|
|
base_swap_size: "4G"
|
|
base_swappiness: 10 # use swap only under real memory pressure
|
|
|
|
# Memory cap per CI job container (swap disabled inside the job): a build that needs more is killed
|
|
# instead of exhausting the host
|
|
act_runner_job_memory: "4g"
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# gitea_runner_registration_token: "" # Gitea admin → Site Administration → Runners → Create runner token
|
|
|
|
# Container registry (Docker Registry v2 + web UI)
|
|
registry_data_dir: /opt/registry
|
|
registry_ui_version: "main"
|
|
# Registry users — plaintext passwords, Ansible generates bcrypt hashes at deploy time
|
|
# registry_users:
|
|
# - username: alice
|
|
# password: "your-password"
|
|
|
|
# k8s (placeholder)
|
|
k8s_data_dir: /opt/k8s
|
|
|
|
# Vaultwarden (self-hosted Bitwarden-compatible password vault)
|
|
vaultwarden_version: "1.37.1"
|
|
vaultwarden_data_dir: /opt/vaultwarden
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# vaultwarden_admin_token: "" # generate: openssl rand -hex 32
|
|
# vaultwarden_sso_client_secret: "" # added after Keycloak is configured — see runbook-configuration.md step 2.6
|
|
|
|
# Download server (nginx HTTPS + SFTP)
|
|
dl_data_dir: /opt/dl
|
|
dl_upload_user: uploader
|
|
dl_sftp_port: 2223
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# dl_sftp_authorized_keys: |
|
|
# ssh-ed25519 AAAA... gitea-actions
|
|
|
|
# Status dashboard (public — cloud.ladkau.de root)
|
|
dashboard_data_dir: /opt/dashboard
|
|
|
|
# Ollama — local LLM server, internal network only (no public route)
|
|
ollama_version: "0.35.1"
|
|
ollama_data_dir: /opt/ollama
|
|
ollama_model: "qwen3:4b-instruct-2507-q4_K_M" # non-thinking variant: the thinking model needs minutes per answer on this CPU
|
|
ollama_context_length: 16384
|
|
ollama_mem_limit: 4608m
|
|
ollama_keep_alive: "1h" # unload the model after this idle time to free RAM
|
|
|
|
# Fuelish — receipt OCR job API for the Android app (fuelish.ladkau.de)
|
|
# The image is pushed to the private registry with upload-image.sh in the fuelish project;
|
|
# after pushing a new version, set fuelish_version and deploy with --tags fuelish.
|
|
domain_fuelish: "fuelish.{{ domain_base }}"
|
|
fuelish_image: "{{ domain_registry }}/fuelish/tools"
|
|
fuelish_version: "0.1.1" # needs X-API-Key support (fuelish commit 7a91a37 or later) and OLLAMA_NUM_CTX / OLLAMA_NUM_THREAD (version 0.1.1 or later)
|
|
fuelish_data_dir: /opt/fuelish
|
|
fuelish_model: "{{ ollama_model }}" # same model as n8n, so the shared Ollama keeps a single model loaded
|
|
fuelish_mem_limit: 768m
|
|
# Request options of the API; they equal the numCtx / numThread of the n8n Ollama nodes (16384 / 4)
|
|
fuelish_num_ctx: "{{ ollama_context_length }}"
|
|
fuelish_num_thread: 4
|
|
# Registry account used to pull the image: the first registry_users entry unless overridden in the vault
|
|
fuelish_registry_user: "{{ registry_users[0].username }}"
|
|
fuelish_registry_password: "{{ registry_users[0].password }}"
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# fuelish_api_key: "" # generate: openssl rand -hex 32 — the same value goes into the Android app settings
|
|
|
|
# n8n — workflow automation, AI chat and scheduled digests (agent.ladkau.de)
|
|
domain_n8n: "agent.{{ domain_base }}"
|
|
n8n_version: "2.41.6"
|
|
n8n_data_dir: /opt/n8n
|
|
n8n_timezone: "Europe/Berlin"
|
|
n8n_mem_limit: 768m
|
|
# Fixed webhook id of the chat workflow: the chat page is served at
|
|
# https://agent.<domain>/webhook/<id>/chat and https://agent.<domain>/chat redirects there.
|
|
# Must match "webhookId" in roles/n8n/files/workflows/chat.json.
|
|
n8n_chat_webhook_id: "3f2b6c1e-8a4d-4e57-9b0a-6d1c2e7f5a10"
|
|
# Fixed webhook id of the Telegram trigger; must match "webhookId" in roles/n8n/files/workflows/telegram-chat.json.
|
|
n8n_telegram_webhook_id: "7c1d4e92-5b3a-4f08-a6e1-2d9b8c0f3a47"
|
|
# Source addresses allowed to call the Telegram webhook (Telegram's webhook servers, see
|
|
# core.telegram.org/bots/webhooks). Set to [] to disable the address filter.
|
|
telegram_webhook_source_ranges:
|
|
- 149.154.160.0/20
|
|
- 91.108.4.0/22
|
|
n8n_users: [] # override in vault with [{username: ..., password: ...}] — basic auth in front of n8n
|
|
|
|
# Outgoing mail for n8n (Strato SMTP)
|
|
smtp_host: "smtp.strato.de"
|
|
smtp_port: 465
|
|
smtp_secure: true # true = implicit TLS (port 465); false = STARTTLS (port 587)
|
|
# Secrets — store values in ansible/group_vars/all/vault.yml (Ansible Vault)
|
|
# n8n_encryption_key: "" # generate: openssl rand -hex 32
|
|
# searxng_secret_key: "" # generate: openssl rand -hex 32 (SearXNG, the internal search backend)
|
|
# gemini_api_key: "" # Google AI Studio API key (default model of the Telegram chat)
|
|
# telegram_bot_token: "" # from @BotFather
|
|
# telegram_user_id: "" # your numeric Telegram user id (the only user the bot answers)
|
|
# smtp_user: "" # full Strato mailbox address
|
|
# smtp_password: ""
|
|
# n8n_users:
|
|
# - username: admin
|
|
# password: "your-password"
|
|
|
|
# n8n backend: Browserless — headless Chromium for the fetch_page tool (internal only)
|
|
browserless_version: "v2.57.0"
|
|
browserless_data_dir: /opt/browserless
|
|
browserless_mem_limit: 1g
|
|
|
|
# n8n backend: SearXNG — metasearch for the web_search tool (internal only)
|
|
searxng_version: "2026.10.2-19ffbcd30"
|
|
searxng_data_dir: /opt/searxng
|
|
searxng_mem_limit: 384m
|