Remove the Clay role (Claude Code web UI) and its Anthropic API key.
New roles:
- ollama: local CPU LLM (qwen3:4b-instruct), internal network only
- browserless: headless Chromium for JavaScript-heavy pages
- searxng: metasearch backend for the chat web_search tool
- n8n at agent.ladkau.de: web chat (/chat), scheduled workflows,
Telegram bot; workflows and credentials are imported from the repo
Telegram bot: Gemini 3.8 -> Gemini 3.5 -> local Qwen fallback chain,
/qwen to force the local model, /stocks and a weekday schedule
(07:30, 13:00, 17:40) for the MTE.DE / PTX.F stock report.
Also: dashboard and check-services entries for the chat, vault checks
for the new secrets (n8n, SearXNG, Gemini, Telegram, SMTP), updated
CLAUDE.md, runbooks and README.
- Deploy Clay (claude Code web UI) at agent.ladkau.de behind basic auth;
Traefik proxies to clay's HTTPS port 2633 with insecureSkipVerify
- Document MCP server persistence: binaries need to be baked into the
Dockerfile, config in /opt/clay/data survives rebuilds
- Document scheduled agent workflows via Gitea Actions on.schedule with
email reporting via Gmail SMTP
- Fix registry UI: split /v2/ (registry) and / (UI) into separate Traefik
routers; add registry_internal network
- Add weekly registry GC cron job (/usr/local/bin/registry-gc)
- Remove rate-limit middleware from Gitea router (act_runner polling
exceeded 60 req/min limit)
- Set Traefik websecure readTimeout: 0 to fix large layer upload 499s
- Add local Dovecot IMAP server exposed via Traefik IMAPS on port 993;
Roundcube now connects to it internally instead of requiring manual server entry
- Add Fetchmail integration for pulling from external POP3 accounts with
configurable per-account poll interval
- Fix Gitea SSO registration: DISABLE_REGISTRATION=false + ALLOW_ONLY_EXTERNAL_REGISTRATION
allows Keycloak-authenticated users to get accounts while blocking public sign-up;
disable legacy OpenID 2.0 sign-in
- Fix Keycloak post-logout redirect for Nextcloud (valid post logout redirect URI)
- Replace all pre-hashed credentials (Traefik dashboard, registry, Dovecot) with
plaintext passwords in vault; Ansible generates deterministic bcrypt/SHA-512 hashes
at deploy time — no more manual htpasswd commands
- Rewrite check-vault.sh with Python/PyYAML to properly validate both scalar and
list-type secrets
- Update provisioning and configuration runbooks throughout
- Traefik rate-limits all routes (60 req/min standard, 300 for Nextcloud)
and writes access logs to /var/log/traefik/access.log
- Fail2ban watches Traefik access logs and bans IPs after 10 x 403/404
within 60 s for 24 h
- Nextcloud html directory created as www-data (UID 33) so Apache can
process .htaccess and serve requests correctly
- scripts/check-services.sh verifies all seven endpoints return the
expected HTTP status after provisioning