Add fuelish API; protect the host against memory exhaustion

- 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
This commit is contained in:
ml
2026-10-04 13:54:09 +02:00
parent 974486bc53
commit 82d944a0a8
15 changed files with 246 additions and 25 deletions
+48 -3
View File
@@ -550,9 +550,9 @@ A summary of a long page takes several minutes on the CPU-only model.
### 9.5 Ollama — local LLM server
The `ollama` role runs Ollama (CPU only). It is reachable only on the internal
Docker network `ollama_internal` at `http://ollama:11434`; there is no public
route.
The `ollama` role runs Ollama (CPU only). It is shared by n8n and fuelish and
reachable only on the internal Docker network `ollama_internal` at
`http://ollama:11434`; there is no public route.
Settings in `ansible/group_vars/all/vars.yml`:
@@ -736,3 +736,48 @@ curl -s "https://api.telegram.org/bot<TOKEN>/getWebhookInfo"
```
`getWebhookInfo` shows the registered URL and the last delivery error.
## 10. Fuelish — receipt OCR API
`https://fuelish.ladkau.de` serves the job API of the fuelish Android app
(`POST /jobs`, `GET /jobs/{id}`, `GET /health`). Every `/jobs` request needs
the header `X-API-Key: <fuelish_api_key>`.
### 10.1 Publish an image version
In the fuelish project (`registry.env` with the registry credentials):
```bash
echo 0.1.1 > tooling-container/VERSION # new version number
./build-image.sh && ./upload-image.sh # pushes cr.ladkau.de/fuelish/tools:<version> and :latest
```
Set `fuelish_version` in `ansible/group_vars/all/vars.yml` to the same number
and deploy:
```bash
ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags fuelish --ask-vault-pass
```
The image must be built from fuelish commit `7a91a37` or later; older images do
not check the API key.
### 10.2 Check the deployment
```bash
curl -s https://fuelish.ladkau.de/health # {"status":"ok"}
curl -s -o /dev/null -w "%{http_code}\n" -X POST https://fuelish.ladkau.de/jobs # without key: 401 or 403
ssh -i keys/notroot_cloud_ladkau_de deploy@217.154.207.148 "sudo docker exec ollama ollama list" # fuelish_model is present (the API pulls it if missing)
```
### 10.3 Android app
In the app's Settings tab enter `https://fuelish.ladkau.de` as server URL and
`fuelish_api_key` as API key.
`fuelish_model` defaults to `ollama_model`, the model used by n8n, so both share
one loaded model. The API sends the request options from `fuelish_num_ctx` and
`fuelish_num_thread` (16384 and 4, the same as the n8n Ollama nodes), so
alternating requests from both apps do not restart the Ollama runner. Keep these
values equal to `ollama_context_length` and the `numThread` of the n8n Ollama
nodes. Images before fuelish version 0.1.1 ignore the two settings.
+14 -9
View File
@@ -82,6 +82,7 @@ Let's Encrypt certificates on first start and DNS must resolve at that point.
| vault.ladkau.de | A → server IP |
| dl.ladkau.de | A → server IP |
| agent.ladkau.de | A → server IP |
| fuelish.ladkau.de | A → server IP |
### 4. Create the vault and populate secrets
@@ -122,15 +123,18 @@ registry_users:
- username: alice
password: "your-password"
# n8n — AI chat and scheduled digests at agent.ladkau.de
# Fuelish — receipt OCR API at fuelish.ladkau.de
fuelish_api_key: "" # generate: openssl rand -hex 32 — same value in the Android app settings
# n8n — AI chat, Telegram bot and scheduled digests at agent.ladkau.de
n8n_users: # basic auth in front of n8n
- username: admin
password: "your-password"
n8n_encryption_key: "" # generate: openssl rand -hex 32 — never change after first deploy
searxng_secret_key: "" # generate: openssl rand -hex 32
searxng_secret_key: "" # generate: openssl rand -hex 32 — SearXNG, the internal search backend of the n8n chat
smtp_user: "" # full Strato mailbox address
smtp_password: ""
gemini_api_key: "" # Google AI Studio API key, see runbook-configuration.md section 9.8
gemini_api_key: "" # Google AI Studio API key, see runbook-configuration.md section 9.8
telegram_bot_token: "" # from @BotFather, see runbook-configuration.md section 9.8
telegram_user_id: "" # your numeric Telegram user id
@@ -222,11 +226,11 @@ This runs all roles in order:
| # | Role | What it does |
|----|---------------|--------------|
| 1 | `base` | OS hardening, deploy user, SSH config, ufw firewall, fail2ban |
| 1 | `base` | OS hardening, deploy user, SSH config, ufw firewall, fail2ban, swap file |
| 2 | `docker` | Docker Engine + Compose plugin, shared Traefik network |
| 3 | `traefik` | Reverse proxy, automatic TLS via Let's Encrypt |
| 4 | `gitea` | Self-hosted Git with PostgreSQL |
| 5 | `act_runner` | Three Gitea Actions runners with Docker executor |
| 5 | `act_runner` | Three Gitea Actions runners with Docker executor; job containers capped at `act_runner_job_memory` |
| 6 | `nextcloud` | File storage with PostgreSQL, Redis, cron sidecar |
| 7 | `sso` | Keycloak single sign-on with PostgreSQL |
| 8 | `mail` | Roundcube webmail client with PostgreSQL |
@@ -235,10 +239,11 @@ This runs all roles in order:
| 11 | `vaultwarden` | Vaultwarden password vault at vault.ladkau.de |
| 12 | `dl` | Public download server at dl.ladkau.de — nginx HTTPS + SFTP upload |
| 13 | `ollama` | Local LLM server (Ollama, CPU) on the internal `ollama_internal` network — pulls `ollama_model` on first run |
| 14 | `browserless` | Headless Chromium for rendering JavaScript-heavy pages — internal network only |
| 15 | `searxng` | Metasearch engine for the chat web_search tool — internal network only |
| 16 | `n8n` | n8n at agent.ladkau.de — AI chat (`/chat`), scheduled digests, basic auth; imports the workflows in the repo |
| 17 | `dashboard` | Public status dashboard at cloud.ladkau.de — service health and server stats |
| 14 | `fuelish` | Receipt OCR job API for the Android app at fuelish.ladkau.de — image from the private registry, API-key auth |
| 15 | `browserless` | Headless Chromium for rendering JavaScript-heavy pages — internal network only |
| 16 | `searxng` | Metasearch engine for the chat web_search tool — internal network only |
| 17 | `n8n` | n8n at agent.ladkau.de — AI chat (`/chat`), scheduled digests, basic auth; imports the workflows in the repo |
| 18 | `dashboard` | Public status dashboard at cloud.ladkau.de — service health and server stats |
> **Note:** The `act_runner` role requires `gitea_runner_registration_token` in the
> vault, which can only be obtained after Gitea is running and an admin account has