NEWS
Hannah — Open Source Smart-Home-Sprachassistentin
-
@Leonie Danke für Deine Rückmeldungen an mich in #43 die ich gut nachvollziehen kann!
Zum Satellite: Ich möchte keine Sonderwege anfangen und warte lieber bzw. beteilige mich gerne an dem von Dir vorgeschlagenen Weg.
Telegram: ... kriege ich dann hoffentlich erstmal hin. Geht evtl. wohl auch im Browser, also ohne native Mobile App und damit auch auf meinem Wandtablet bzw. allen browserfähigen Geräten im Haushalt - das wäre ja schonmal etwas universeller nutzbar?
iobroker.hannah Adapter: Ich habe im Beta Repo geschaut aber den noch nicht gefunden. Kann man schon abschätzen wann der dort kommen kann?
WebUI: Das habe ich schonmal per Docker installiert bekommen. Die WebUI wartet nun erstmal auf eine Core.
Docker-Container für die 4 Backendservices Core / Telegram / VoiceID / Proxy :
Meine "Standardumgebung" für allerlei Container ist derzeit mein Synology NAS. Ich weiß schon darüber kann man streiten... Und meine Synology hat keine GPU (bzw. nur einen durchgereichten USB-Coral für Frigate Container). Daneben existiert der Strix Halo "KI-Server", den ich eigentlich nur als HTTP-Server für KI-Workloads und nicht als erweiterten Anwendungs- oder Docker-Host verwenden wollte.Leonie: "Wenn du remote STT (faster-whisper-server) und Cloud-TTS (Azure/Polly) statt der lokalen Varianten nutzt, sollte es deutlich einfacher sein, weil dann auch Core nur noch HTTP-Backends anspricht."
Ich möchte alles lokal im Heimnetz betreiben und hatte gehofft, dass die Hannah-Backendservices eigentlich keine "größeren" GPU-Anforderungen haben weil alles lokal passiert (und meine CPU hoffentlich ausreicht) und dass ich das in einem Container unterbringen kann. Oder dass ich alle KI-Dienste wie ollama, faster-whisper und piper auch per HTTP einbinden könnte.
Nun habe ich heute mal eine Docker Compose gebaut, um den WebUI und einen "Backendservices" Container aufzubauen. Mein Ansatz war einfach alle 4 Backendservices in einem Docker-Container laufen zu lassen. Ehrlich gesagt würde ich gerne auch die WebUI noch im selben Container mitbetreiben wollen solange es keinen guten z.B. Grund (Performance, Releasezyklus etc.) für die Auslagerung gibt damit das Ganze zumindest zu Beginn kompakter wird und man später skalieren kann. Beim Bauen des Containers (oder nach dem Start) wollte ich die 4 Backend-Installscripte laden und ausführen. Aber mit dem ganzen Vorhaben bin ich grundsätzlich leider erstmal ziemlich stecken geblieben.
Erstes Problem war, dass die install.sh beim Download abgebrochen ist. Nach Debugging ergab sich eine Rückmeldung vom Repo 429 too many requests. Würde mich wundern, wenn ich in ein echtes Rate limit gelaufen wäre, aber vllt. war hier die Curl-Clientangabe aus dem Container leer oder verdächtig oder sowas. Jedenfalls hat es mit einem anderen vorgegebenen Header dann sofort geklappt:
curl -sf \ -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "${AUTH_HEADER[@]}" \ -o "$TMPFILE" \ "${UPDATE_SERVER_URL}/releases/${LATEST_VERSION}?channel=${CORE_CHANNEL}"Der Aufruf install.sh gab nur den Fehlercode 22 zurück. @Leonie Vielleicht kannst Du in dem Bereich die install-Scripte noch Client-durchgängiger oder ansonsten gesprächiger machen für Download-Fehler?
Nun zum Hauptproblem - dass mir erst klar wurde als der Download gelöst war ...
Ich habe auf meinem Synology NAS Host garkein systemd das ich in Containern nutzen könnte - und es ist mir auch nicht gelungen das irgendwie in Containern trotzdem hinzurkriegen. Könnte lösbar sein, aber so tief bin ich einfach nicht drin.
Aber dann passen auch dazu die install-Scripte nicht richtig, weil Build/Install und Run dort nicht getrennt ist.
Nun müsste ich mir also 4 eigene Installscripte schreiben und pflegen etc. aber das möchte ich natürlich vermeiden und irgendwie trotzdem eine Dockerinstallation hinbekommen.Daher will ich das erstmal hier zur Diskussion stellen: Ist es denkbar auch mit den Hannah-Backendservices in Container zu kommen? Vielleicht bin ich da verwöhnt oder verzogen, aber es geht damit halt so Richtung "Lego"

Freue mich auf Rückmeldungen!
Ich habe auf meinem Synology NAS Host garkein systemd das ich in Containern nutzen könnte - und es ist mir auch nicht gelungen das irgendwie in Containern trotzdem hinzurkriegen. Könnte lösbar sein, aber so tief bin ich einfach nicht drin.
container sind eigentlich isoliert. warum solltest du systemd des host betriebssystem nutzen? das ist nicht im sinne des containerkonzepts
Dein image betriebssystem (wenn man das richtige wählt) bringt doch sein eigenes systemd mit.erstelle dein dockerfile so, wie wenn du es auf einem rechner installierst.
das image ist ja nix anderes als das dateisystem für ein rechner, das bei der erstellung dynamisch zusammengebaut wird.
habe jetzt nicht im kopf was du mit systemd machen willst? aber ich vermute du willst die hannah teile als service registrieren. also genau so wie wenn du es auf einem rechner machen willst.
wenn nicht alles durch erstellen von dateien am richtigen ort erfolgen kann (bei der imageersellung läuft das containerbetriebssystem ja noch nicht) musst du ggfs startskripte erstellen, die das dann nach containerstart erledigen. docker bringt aber ein paar befehle mit
den iobroker buanet container kannst du mal anschauen, da werden diese ganzen methodiken eingesetzt
https://github.com/buanet/ioBroker.docker/blob/main/debian12/Dockerfile
https://github.com/buanet/ioBroker.docker/tree/main/debian12/scriptsfür startskript siehe im dockerfile unter entrypoint
-
Es tut mir leid - ich hab wohl einfach nach dem Repo umschalten nicht Refresh gedrückt. Ist mir glaub ich schonmal passiert... [[kann/sollte der Refresh nicht nach dem Speichern schon ausgelöst werden?]]
Ich bin auf ioBroker v7.8.23 und konnte den Hannah Adapter aus dem Beta Repo vollkommen reibungslos installieren.Korrekt, die Install-Scripte decken das nicht ab. Offensiv gefragt, warum sollten sie es auch?
Ja, ganz klar, das war auch keine Erwartung oder sowas, sondern wirklich nur meine Erkenntnis nach dem ganzen Rumprobieren. Hatte irgendwie gedacht ich könnte es aus den Bestandteilen zusammensetzen.
@OliverIO sagte:
habe jetzt nicht im kopf was du mit systemd machen willst? aber ich vermute du willst die hannah teile als service registrieren. also genau so wie wenn du es auf einem rechner machen willst.Genau, ich möchte quasi die bisher angedachte systemd-Struktur im Container nachbilden und die Backendservices als systemd Services laufen lassen. Ist mir aber eben nicht gelungen und wahrscheinlich macht das auch keinen Sinn, weil ich dann die Konzepte vermische.
Ganz eigene Start-Scripte möchte bzw. kann ich ehrlich gesagt nicht schreiben, ich glaube das übersteigt einfach meine Fähigkeiten und muss ja auch gepflegt werden.
-
theoretisch müsstest du die Install-Scripte beim Dockerbuild ausführen können. also im Dockerfile entsprechende RUN Deklarationen.
ich habe gerade mal deine installationsanweisungen in die ki geworfen.
ki empfiehlt verschiedene images zu bauen.hier mal copy/paste der antwort
aus sicherheitssicht gibt es ebenfalls noch einen hinweis zu UPDATE_SERVER_TOKEN weiter unten
xxx---xxx
Ja. Auf Basis der aktuellen Installer würde ich Hannah nicht als einen einzigen Container mit systemd betreiben, sondern jede Komponente als eigenen Container. Das passt deutlich besser zu Docker und bildet die vorhandene Architektur sauber ab.
Die offiziellen Services starten Core mit
python main.py -c /etc/hannah/config.yaml, Proxy mithannah-proxy --config ..., Telegram entsprechend mitmain.py --config ...und Voice-ID mitapp.py --config ....Empfohlene Verzeichnisstruktur
hannah-docker/ ├── docker-compose.yml ├── .env │ ├── core/ │ ├── Dockerfile │ └── config/ │ └── config.yaml │ ├── proxy/ │ ├── Dockerfile │ └── config/ │ └── config.yaml │ ├── telegram/ │ ├── Dockerfile │ └── config/ │ └── config.yaml │ ├── voiceid/ │ ├── Dockerfile │ ├── config/ │ │ └── config.yaml │ └── voice_profiles/ │ └── data/ └── core/Dabei würde ich AutoDeploy zunächst weglassen. Der vorhandene AutoDeploy-Service ist darauf ausgelegt, andere
systemd-Services auf dem Host zu verwalten. Das passt konzeptionell nicht gut zu Docker; Updates sollte dann Docker/Compose übernehmen.
1. Core
Da das Release vom Hannah-Update-Server kommt, bauen wir das Image ähnlich wie der Installer – nur ohne systemd.
core/Dockerfile:FROM python:3.11-slim ARG UPDATE_SERVER_URL=https://hannah-update.sgessinger.de ARG CORE_CHANNEL=core-stable ARG UPDATE_SERVER_TOKEN="" ENV PYTHONUNBUFFERED=1 ENV HOME=/opt/hannah/core RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ ca-certificates \ tar \ portaudio19-dev \ build-essential \ && rm -rf /var/lib/apt/lists/* WORKDIR /opt/hannah/core RUN set -eux; \ AUTH=""; \ if [ -n "$UPDATE_SERVER_TOKEN" ]; then \ AUTH="-H Authorization:\ Bearer\ $UPDATE_SERVER_TOKEN"; \ fi; \ LATEST_JSON="$(curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/latest?channel=${CORE_CHANNEL}")"; \ VERSION="$(printf '%s' "$LATEST_JSON" \ | python -c 'import json,sys; print(json.load(sys.stdin)["version"])')"; \ echo "Installing Hannah Core ${VERSION}"; \ curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/releases/${VERSION}?channel=${CORE_CHANNEL}" \ -o /tmp/hannah-core.tar.gz; \ tar -xzf /tmp/hannah-core.tar.gz -C /opt/hannah/core; \ rm /tmp/hannah-core.tar.gz RUN pip install --no-cache-dir --upgrade pip \ && pip install --no-cache-dir -r requirements.txt RUN useradd --system \ --home-dir /opt/hannah/core \ --shell /usr/sbin/nologin \ hannah \ && chown -R hannah:hannah /opt/hannah/core USER hannah EXPOSE 50051 EXPOSE 7775/udp CMD ["python", "main.py", "-c", "/etc/hannah/config.yaml"]Der Core-Installer verwendet aktuell den Channel
core-stableund installiert nach/opt/hannah/core; genau daran orientiert sich dieses Image.
2. Proxy
Beim Proxy ist etwas Besonderes zu beachten: Das Release unterscheidet zwischen
amd64undarm64. Das macht auch der Originalinstaller automatisch.proxy/Dockerfile:FROM debian:bookworm-slim ARG UPDATE_SERVER_URL=https://hannah-update.sgessinger.de ARG PROXY_CHANNEL=proxy-stable ARG UPDATE_SERVER_TOKEN="" ARG TARGETARCH RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ ca-certificates \ tar \ file \ python3 \ && rm -rf /var/lib/apt/lists/* RUN set -eux; \ case "${TARGETARCH}" in \ amd64) ARCH="amd64" ;; \ arm64) ARCH="arm64" ;; \ *) echo "Unsupported architecture: ${TARGETARCH}"; exit 1 ;; \ esac; \ CHANNEL="${PROXY_CHANNEL}-${ARCH}"; \ AUTH=""; \ if [ -n "$UPDATE_SERVER_TOKEN" ]; then \ AUTH="-H Authorization:\ Bearer\ $UPDATE_SERVER_TOKEN"; \ fi; \ LATEST_JSON="$(curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/latest?channel=${CHANNEL}")"; \ VERSION="$(printf '%s' "$LATEST_JSON" \ | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')"; \ echo "Installing Hannah Proxy ${VERSION} (${ARCH})"; \ curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/releases/${VERSION}?channel=${CHANNEL}" \ -o /tmp/hannah-proxy.tar.gz; \ mkdir /tmp/hannah-proxy; \ tar -xzf /tmp/hannah-proxy.tar.gz -C /tmp/hannah-proxy; \ install -m 755 /tmp/hannah-proxy/hannah-proxy /usr/local/bin/hannah-proxy; \ rm -rf /tmp/hannah-proxy /tmp/hannah-proxy.tar.gz RUN useradd --system \ --no-create-home \ --shell /usr/sbin/nologin \ hannah USER hannah EXPOSE 7775/udp CMD ["hannah-proxy", "--config", "/etc/hannah-proxy/config.yaml"]
3. Telegram
telegram/Dockerfile:FROM python:3.11-slim ARG UPDATE_SERVER_URL=https://hannah-update.sgessinger.de ARG TELEGRAM_CHANNEL=telegram-stable ARG UPDATE_SERVER_TOKEN="" ENV PYTHONUNBUFFERED=1 ENV HOME=/opt/hannah/telegram RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ ca-certificates \ tar \ && rm -rf /var/lib/apt/lists/* WORKDIR /opt/hannah/telegram RUN set -eux; \ AUTH=""; \ if [ -n "$UPDATE_SERVER_TOKEN" ]; then \ AUTH="-H Authorization:\ Bearer\ $UPDATE_SERVER_TOKEN"; \ fi; \ LATEST_JSON="$(curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/latest?channel=${TELEGRAM_CHANNEL}")"; \ VERSION="$(printf '%s' "$LATEST_JSON" \ | python -c 'import json,sys; print(json.load(sys.stdin)["version"])')"; \ echo "Installing Hannah Telegram ${VERSION}"; \ curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/releases/${VERSION}?channel=${TELEGRAM_CHANNEL}" \ -o /tmp/hannah-telegram.tar.gz; \ tar -xzf /tmp/hannah-telegram.tar.gz -C /opt/hannah/telegram; \ rm /tmp/hannah-telegram.tar.gz RUN pip install --no-cache-dir --upgrade pip \ && pip install --no-cache-dir -r requirements.txt RUN useradd --system \ --home-dir /opt/hannah/telegram \ --shell /usr/sbin/nologin \ hannah \ && chown -R hannah:hannah /opt/hannah/telegram USER hannah CMD ["python", "main.py", "--config", "/etc/hannah-telegram/config.yaml"]Das entspricht dem aktuellen systemd-Startkommando des Telegram-Bots.
4. Voice-ID
Voice-ID benötigt laut Installer PyTorch, Torchaudio und SpeechBrain. Außerdem nutzt die normale Installation
/mnt/hannah_memals 128-MB-RAM-Disk. In Compose können wir das viel eleganter übertmpfslösen.voiceid/Dockerfile:FROM python:3.11-slim ARG UPDATE_SERVER_URL=https://hannah-update.sgessinger.de ARG VOICEID_CHANNEL=voiceid-stable ARG UPDATE_SERVER_TOKEN="" ENV PYTHONUNBUFFERED=1 ENV HOME=/opt/hannah/voiceid RUN apt-get update \ && apt-get install -y --no-install-recommends \ curl \ ca-certificates \ tar \ libsndfile1 \ && rm -rf /var/lib/apt/lists/* WORKDIR /opt/hannah/voiceid RUN set -eux; \ AUTH=""; \ if [ -n "$UPDATE_SERVER_TOKEN" ]; then \ AUTH="-H Authorization:\ Bearer\ $UPDATE_SERVER_TOKEN"; \ fi; \ LATEST_JSON="$(curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/latest?channel=${VOICEID_CHANNEL}")"; \ VERSION="$(printf '%s' "$LATEST_JSON" \ | python -c 'import json,sys; print(json.load(sys.stdin)["version"])')"; \ echo "Installing Hannah Voice-ID ${VERSION}"; \ curl -fsSL $AUTH \ "${UPDATE_SERVER_URL}/releases/${VERSION}?channel=${VOICEID_CHANNEL}" \ -o /tmp/hannah-voiceid.tar.gz; \ tar -xzf /tmp/hannah-voiceid.tar.gz -C /opt/hannah/voiceid; \ rm /tmp/hannah-voiceid.tar.gz RUN pip install --no-cache-dir --upgrade pip RUN pip install --no-cache-dir \ fastapi \ uvicorn \ python-multipart \ pyyaml \ torch \ torchaudio \ --index-url https://download.pytorch.org/whl/cpu RUN pip install --no-cache-dir speechbrain RUN useradd --system \ --home-dir /opt/hannah/voiceid \ --shell /usr/sbin/nologin \ hannah \ && mkdir -p /mnt/hannah_mem /opt/hannah/voiceid/voice_profiles \ && chown -R hannah:hannah \ /mnt/hannah_mem \ /opt/hannah/voiceid USER hannah EXPOSE 8080 CMD ["python", "app.py", "--config", "/etc/hannah-voiceid/config.yaml"]
5. docker-compose.yml
Hier kommt alles zusammen:
services: hannah-core: build: context: ./core args: UPDATE_SERVER_URL: ${UPDATE_SERVER_URL:-https://hannah-update.sgessinger.de} UPDATE_SERVER_TOKEN: ${UPDATE_SERVER_TOKEN} CORE_CHANNEL: ${CORE_CHANNEL:-core-stable} container_name: hannah-core restart: unless-stopped volumes: - ./core/config/config.yaml:/etc/hannah/config.yaml:ro - ./data/core:/opt/hannah/core/.tts_cache ports: - "50051:50051" # Nur aktivieren, wenn Satelliten DIREKT mit Core sprechen: # - "7775:7775/udp" networks: - hannah hannah-proxy: build: context: ./proxy args: UPDATE_SERVER_URL: ${UPDATE_SERVER_URL:-https://hannah-update.sgessinger.de} UPDATE_SERVER_TOKEN: ${UPDATE_SERVER_TOKEN} PROXY_CHANNEL: ${PROXY_CHANNEL:-proxy-stable} container_name: hannah-proxy restart: unless-stopped depends_on: - hannah-core volumes: - ./proxy/config/config.yaml:/etc/hannah-proxy/config.yaml:ro ports: - "7775:7775/udp" networks: - hannah hannah-telegram: build: context: ./telegram args: UPDATE_SERVER_URL: ${UPDATE_SERVER_URL:-https://hannah-update.sgessinger.de} UPDATE_SERVER_TOKEN: ${UPDATE_SERVER_TOKEN} TELEGRAM_CHANNEL: ${TELEGRAM_CHANNEL:-telegram-stable} container_name: hannah-telegram restart: unless-stopped depends_on: - hannah-core volumes: - ./telegram/config/config.yaml:/etc/hannah-telegram/config.yaml:ro networks: - hannah hannah-voiceid: build: context: ./voiceid args: UPDATE_SERVER_URL: ${UPDATE_SERVER_URL:-https://hannah-update.sgessinger.de} UPDATE_SERVER_TOKEN: ${UPDATE_SERVER_TOKEN} VOICEID_CHANNEL: ${VOICEID_CHANNEL:-voiceid-stable} container_name: hannah-voiceid restart: unless-stopped volumes: - ./voiceid/config/config.yaml:/etc/hannah-voiceid/config.yaml:ro - ./voiceid/voice_profiles:/opt/hannah/voiceid/voice_profiles tmpfs: - /mnt/hannah_mem:size=128m,mode=1777 expose: - "8080" networks: - hannah networks: hannah: driver: bridgeGanz wichtig: interne Hostnamen
In deinen Configs darfst du bei Docker für die Kommunikation zwischen Containern nicht mehr
127.0.0.1verwenden.Für
proxy/config/config.yamlalso beispielsweise:proxy_id: hannah-proxy hannah: address: "hannah-core:50051" udp: listen_addr: ":7775" # Hier muss die IP des Docker-HOSTS hinein, # die deine Satelliten erreichen können. advertise_host: "192.168.8.15" voice_id: enabled: true base_url: "http://hannah-voiceid:8080" timeout_sec: 3.0 min_confidence: 0.45Das ist besonders wichtig beim
advertise_host: Hier darf nichthannah-proxystehen. Die Satelliten befinden sich außerhalb des Docker-Netzes und müssen deshalb die LAN-IP deines Docker-Hosts bekommen.Für Telegram:
telegram: token: "DEIN_BOT_TOKEN" allowed_users: - 123456789 hannah: address: "hannah-core:50051"
.envIm Hauptverzeichnis:
UPDATE_SERVER_URL=https://hannah-update.sgessinger.de UPDATE_SERVER_TOKEN=DEIN_UPDATE_SERVER_TOKEN CORE_CHANNEL=core-stable PROXY_CHANNEL=proxy-stable TELEGRAM_CHANNEL=telegram-stable VOICEID_CHANNEL=voiceid-stableDann:
docker compose build docker compose up -dLogs:
docker compose logs -f hannah-coreOder alle:
docker compose logs -fStatus:
docker compose psEin Punkt, den ich noch ändern würde
Das Beispiel oben funktioniert, hat aber bei
UPDATE_SERVER_TOKENeinen Docker-spezifischen Schönheitsfehler: Ein Token alsARGkann unter Umständen in Build-Metadaten landen.Für ein dauerhaftes Produktionssetup würde ich deshalb Docker BuildKit Secrets verwenden:
RUN --mount=type=secret,id=update_token \ UPDATE_SERVER_TOKEN="$(cat /run/secrets/update_token)" \ ...und dann in Compose:
build: secrets: - update_tokenDas ist deutlich sauberer als ein Token über
ARG.WebUI
Die WebUI würde ich ebenfalls als eigenen Container integrieren. Da sie laut Projekt ohnehin explizit Docker unterstützt, würde ich dafür möglichst das dort vorgesehene Image/Dockerfile verwenden und sie dann einfach in dasselbe
hannah-Netz hängen.Ich würde also am Ende ungefähr diese Architektur fahren:
┌───────────────────┐ Satelliten ── UDP 7775 ─▶│ hannah-proxy │ └───────┬───────────┘ │ gRPC ▼ ┌───────────────────┐ │ hannah-core │ │ :50051 │ └─────┬────────┬─────┘ │ │ gRPC │ │ MQTT / ioBroker │ │ ┌────────────────┘ └───────────▶ LAN │ ┌───────▼──────────┐ │ hannah-telegram │ └──────────────────┘ ┌──────────────────┐ │ hannah-voiceid │◀──── HTTP ─── hannah-proxy │ :8080 │ └──────────────────┘ ┌──────────────────┐ │ hannah-webui │ └──────────────────┘Diese Variante würde ich gegenüber einem riesigen Hannah-All-in-One-Dockerfile klar bevorzugen. Sie trennt Core, Proxy, Voice-ID und Telegram, ermöglicht unabhängige Neustarts/Updates und ersetzt die bisherigen systemd-Aufgaben durch Docker Compose. Die originale Hannah-Dokumentation bestätigt auch die Rollen von Core, Proxy, Telegram und Voice-ID sowie die Ports 50051, 7775/UDP und 8080. (GitHub)
Ein weiterer Vorteil: Der Core aktiviert laut Hannah-Architektur seinen eigenen UDP-Server wieder, wenn der Proxy wegfällt. Wenn du in Docker konsequent den Proxy verwendest, würde ich deshalb nur Proxy
7775/udpnach außen publishen und beim Core den Port nicht auf den Host mappen. (GitHub) -
Klar, wenn dann eh ein Image pro Komponente. Dafür ist Docker gedacht. Ich habe auch mal eben ein Image für Core gebaut: Dockerfile
Das erwartet die Sourcefiles in src/
Starten kann man es dann so:
PS D:\hannah-test\core> docker run -it --rm -v "D:\hannah-test\core\activity_audio:/app/activity_audio" -v "D:\hannah-test\core\audio_dumps:/app/audio_dumps" -v "D:\hannah-test\core\config.yaml:/etc/hannah/config.yaml:ro" --name hannah-core hannah-core:latest
15:41:50 [INFO] hannah.main: Hannah Core dev=======================================================
First-run: admin account created
Username : admin
Password : Q0PmWjbR4AOerEjL9cfW8g
Please change the password after first login!Analog würde ich es für die anderen Komponeten auch machen.
-
Bei deinem Install-Befehl fehlt am Ende das "| bash", nur dann wird die Datei auch ausgeführt.
for all: Ich bin gerade an einer CI-Pipeline dran die die Images baut und dann aber auf quay.io hochlädt.
Sorry Leonie,ich hoffe ich Nerve nicht.
So hab ich es gemacht.$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/core/deploy/install.sh | sudo bash
[sudo: authenticate] Password:
[INFO] Fetching latest core release from https://hannah-update.sgessinger.de (channel: core-stable) ...
[INFO] Latest version: v0.75.0
iob@iob:~$ systemctl status hannah
Unit hannah.service could not be found.
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/proxy/deploy/install.sh | sudo bash
[INFO] Fetching latest proxy release from https://hannah-update.sgessinger.de (channel: proxy-stable-amd64) ...
[INFO] Latest version: v0.75.0 (amd64)
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/telegram/deploy/install.sh | sudo bash
[INFO] Fetching latest telegram release from https://hannah-update.sgessinger.de (channel: telegram-stable) ...
[INFO] Latest version: v0.75.0
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/voiceid/deploy/install.sh | sudo bash
[INFO] Fetching latest voiceid release from https://hannah-update.sgessinger.de (channel: voiceid-stable) ...
[INFO] Latest version: v0.75.0
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/autodeploy/deploy/install.sh | sudo bash
[INFO] Fetching latest autodeploy release from https://hannah-update.sgessinger.de (channel: autodeploy-stable) ...
[INFO] Latest version: v0.64.1
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah-webui/refs/heads/main/deploy/install.sh | sudo bash
[INFO] Fetching latest webui release from https://hannah-update.sgessinger.de (channel: webui-stable) ...
[INFO] Latest version: v2.3.2
iob@iob:~$ systemctl status hannah
Unit hannah.service could not be found. -
Sorry Leonie,ich hoffe ich Nerve nicht.
So hab ich es gemacht.$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/core/deploy/install.sh | sudo bash
[sudo: authenticate] Password:
[INFO] Fetching latest core release from https://hannah-update.sgessinger.de (channel: core-stable) ...
[INFO] Latest version: v0.75.0
iob@iob:~$ systemctl status hannah
Unit hannah.service could not be found.
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/proxy/deploy/install.sh | sudo bash
[INFO] Fetching latest proxy release from https://hannah-update.sgessinger.de (channel: proxy-stable-amd64) ...
[INFO] Latest version: v0.75.0 (amd64)
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/telegram/deploy/install.sh | sudo bash
[INFO] Fetching latest telegram release from https://hannah-update.sgessinger.de (channel: telegram-stable) ...
[INFO] Latest version: v0.75.0
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/voiceid/deploy/install.sh | sudo bash
[INFO] Fetching latest voiceid release from https://hannah-update.sgessinger.de (channel: voiceid-stable) ...
[INFO] Latest version: v0.75.0
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/autodeploy/deploy/install.sh | sudo bash
[INFO] Fetching latest autodeploy release from https://hannah-update.sgessinger.de (channel: autodeploy-stable) ...
[INFO] Latest version: v0.64.1
iob@iob:~$ curl -fsSL https://raw.githubusercontent.com/NurPech/hannah-webui/refs/heads/main/deploy/install.sh | sudo bash
[INFO] Fetching latest webui release from https://hannah-update.sgessinger.de (channel: webui-stable) ...
[INFO] Latest version: v2.3.2
iob@iob:~$ systemctl status hannah
Unit hannah.service could not be found. -
Erstmal Danke für Eure Rückmeldungen - ihr seid echt spitze!
Nun auch von mir ein Update:
Ich habe dank der Infos von @Walter.O. und nach den nötigen Anpassungen an mein Setup nun auch fast alles mal (bis auf den Proxy) bei mir auf der Synology Container Manager ans laufen bekommen - denke ich.Was geklappt hat:
- die einzelnen Container für WebUi+Core+Telegram+voiceID laufen und die Logs sehen gut aus (bis auf 404 wegen fehlender static files)
- der iobroker.hannah-Adapter und dieVerknüpfung und Kommunikation mit Hannah tut
- die Verknüpfung mit meinem lokalen lemonade-ai server fürs LM uns damit das eingeben eines TextCommand an den Datenpunkt und die Rückgabe der LLM-Antwort - yayy!
Was mir noch nicht gelingt ist:
- Meinen Telegram-Account zu verbinden. nachdem ich den Token in Telegram config und den WebUI Container hinterlegt habe wird im WebUI Telegram als konfiguriert angezeigt - es kommt aber im WebUI nach Click auf das Telegram-Icon eine neue Seite mit der Rückmeldung "Bot domain invalid". Zur "lokalen" Domain bei Telegram bzw. zur Domainverknüpfung mit /setdomain finde ich kaum Infos. Eine extern erreichbare Domain habe ich nicht vor. Der Telegram Chatbot antwortet also hartnäckig dass er mich nicht kennt und ich verknüpfen soll.
- in der WebUI das CSS/Bilder aus dem Ordner static zu laden (sieht natürlich grausig aus, aber funktionieren tuts ja :-) )
- rauszufinden wie ich die core-Datenbank so mounte, dass sie mir auf das core-Verzeichnis des Hosts gelegt wird
Aber wenn Du @Leonie jetzt eventuell bald "offizielle" Dockerfiles bereitstellt, dann teste ich auch gerne diese natürlich umgehend!
Viele Grüße und nochmal vielen vielen Dank!
-
Ihr Verrückten :D
Ich habe nun die letzten Stunden damit verbracht Container Images zu bauen. Habe die Services dafür verändert, meine Pipelines überarbeitet, aber hier ist nun das Composefile mit allem drin:
Gestartet werden kann der ganze Stack bspw. so:
docker compose --profile full up -d
Am Besten tauscht ihr dann auch entsprechende Secrets aus, alles in dem File ist von meiner Seite aus Demo, aber voll getestet.Für VoiceID habe ich eine cpu-only Version bereitgestellt. Eine Version mit GPU-Unterstützung kann ich aktuell nicht bauen, zumindest nicht automatisiert.
Mitgestartet wird auch ein MySQL-Server, der für den Activity Log genutzt wird. Warum ein MySQL-Server? Weil Hannah bei mir komplett auf einem Raspberry Pi läuft und ich mit der Datenbank für den Activty Log, die naturgemäß eine Menge Schreiboperationen aufweisen kann, die SD-Karte nicht belasten will.
Außerdem wird ein Mosquitto, als MQTT-Broker gestartet. Ich denke der ein oder andere von euch wird bereits einen Broker einsetzen, für alle anderen, ist hier die Vorlage.Ich habe euch auch gleich einen Service dazu gepackt, den ich noch nicht vorgestelt habe: hannah-timer. Das ist ein Timerbackend für Core. Der hält alle Timer die Core stellen mag persistent. Egal ob man Wecker stellt, ob man sich an irgendwas erinnern lassen möchte oder einfach nur einer Eieruhr stellt, dieser Service sorgt für die Integrität.
Warum ein eigener Service? In der Entwicklung hat sich gezeigt das Core bei mir öfter neustarten muss, auch bspw. aufgrund von Updates. Timer ist so stabil, das er bereits seit Monaten bei mir ohne Downtime laufen kann. Außerdem kann so die ganze Timer-Logik aus dem Core draußen bleiben. Timer informiert Core aktiv, wenn ein Timer abgelaufen ist und stellt ihm wieder die Informationen bereit, die Core braucht um Aktionen zu ergreifen.Eventuell bekommen in Zukunft noch weitere Services Unterstützung fürs Environment. Ich verstehe schon, das es sich doof anfühlt bspw. für den Proxy eine Configdatei mit 6 Zeilen zu schreiben, während timer bspw. Environment-Variablen hat. Faktisch unterstützen die meisten Services es nicht, da sind dann Configs notwendig.
Und natürlich werden die Images jetzt nicht bei mir gehostet, das heißt, die sollten zu jeder Zeit abrufbar sein :D
Liebe Grüße
Leonie -
Erstmal Danke für Eure Rückmeldungen - ihr seid echt spitze!
Nun auch von mir ein Update:
Ich habe dank der Infos von @Walter.O. und nach den nötigen Anpassungen an mein Setup nun auch fast alles mal (bis auf den Proxy) bei mir auf der Synology Container Manager ans laufen bekommen - denke ich.Was geklappt hat:
- die einzelnen Container für WebUi+Core+Telegram+voiceID laufen und die Logs sehen gut aus (bis auf 404 wegen fehlender static files)
- der iobroker.hannah-Adapter und dieVerknüpfung und Kommunikation mit Hannah tut
- die Verknüpfung mit meinem lokalen lemonade-ai server fürs LM uns damit das eingeben eines TextCommand an den Datenpunkt und die Rückgabe der LLM-Antwort - yayy!
Was mir noch nicht gelingt ist:
- Meinen Telegram-Account zu verbinden. nachdem ich den Token in Telegram config und den WebUI Container hinterlegt habe wird im WebUI Telegram als konfiguriert angezeigt - es kommt aber im WebUI nach Click auf das Telegram-Icon eine neue Seite mit der Rückmeldung "Bot domain invalid". Zur "lokalen" Domain bei Telegram bzw. zur Domainverknüpfung mit /setdomain finde ich kaum Infos. Eine extern erreichbare Domain habe ich nicht vor. Der Telegram Chatbot antwortet also hartnäckig dass er mich nicht kennt und ich verknüpfen soll.
- in der WebUI das CSS/Bilder aus dem Ordner static zu laden (sieht natürlich grausig aus, aber funktionieren tuts ja :-) )
- rauszufinden wie ich die core-Datenbank so mounte, dass sie mir auf das core-Verzeichnis des Hosts gelegt wird
Aber wenn Du @Leonie jetzt eventuell bald "offizielle" Dockerfiles bereitstellt, dann teste ich auch gerne diese natürlich umgehend!
Viele Grüße und nochmal vielen vielen Dank!
Meinen Telegram Account zu verbinden - es kommt "Bot domain invalid" und meine "lokale" Domain bei Telegram mit /setdomain zu verknüpfen macht doch irgendwie keinen Sinn? Zur Domainregistrierung finde ich kaum Infos.
Ich ziehe das nochmal nach.
Leider habe ich selbst keinen Einfluss auf das was Telegram verlangt. Hannah nutzt ein "Login with Telegram" in der WebUI für die Verknüpfung. Dafür benötigt der BotFather eine Domain, die Domain unter der die WebUI erreichbar ist.
Leider funktionieren da keine IP-Adressen und keine lokalen Domains. Telegram erfordert eine öffentliche überprüfbare Domain. Nicht falsch verstehen, die WebUI muss nur eine öffentliche Domain nutzen, nicht aus der Öffentlichkeit erreichbar sein.
Ja, ist nicht ideal, aber den Ablauf gibt leider Telegram vor.
Ich selbst habe glücklicherweise eine eigene Domain. Unter der kann ich meine WebUI aufrufen und Telegram ist glücklich. Damit ich die aber aufrufen kann, muss ich zu Hause sein. Aus dem Internet geht es nicht.
An der Stelle mag ich schonmal sagen, das eine DynDNS-Adresse bspw. von MyFritz! schon ausreichend ist, damit der BotFather zu Frieden ist.Liebe Grüße
Leonie -
Wow🤩 Freue mich riesig drauf das Compose einzurichten und melde mich wieder.
DANKE @Leonie !
Ich hoffe dass das den Anwenderkreis am Ende auch nochmal so deutlich erweitert wie ich mir das vorstelle👍Okay, und eine Domain habe ich grundsätzlich schon auch, ich probiere es damit nochmal.
-
Meinen Telegram Account zu verbinden - es kommt "Bot domain invalid" und meine "lokale" Domain bei Telegram mit /setdomain zu verknüpfen macht doch irgendwie keinen Sinn? Zur Domainregistrierung finde ich kaum Infos.
Ich ziehe das nochmal nach.
Leider habe ich selbst keinen Einfluss auf das was Telegram verlangt. Hannah nutzt ein "Login with Telegram" in der WebUI für die Verknüpfung. Dafür benötigt der BotFather eine Domain, die Domain unter der die WebUI erreichbar ist.
Leider funktionieren da keine IP-Adressen und keine lokalen Domains. Telegram erfordert eine öffentliche überprüfbare Domain. Nicht falsch verstehen, die WebUI muss nur eine öffentliche Domain nutzen, nicht aus der Öffentlichkeit erreichbar sein.
Ja, ist nicht ideal, aber den Ablauf gibt leider Telegram vor.
Ich selbst habe glücklicherweise eine eigene Domain. Unter der kann ich meine WebUI aufrufen und Telegram ist glücklich. Damit ich die aber aufrufen kann, muss ich zu Hause sein. Aus dem Internet geht es nicht.
An der Stelle mag ich schonmal sagen, das eine DynDNS-Adresse bspw. von MyFritz! schon ausreichend ist, damit der BotFather zu Frieden ist.Liebe Grüße
LeonieAn der Stelle mag ich schonmal sagen, das eine DynDNS-Adresse bspw. von MyFritz! schon ausreichend ist, damit der BotFather zu Frieden ist.
wer einen port nach außen öffnet, sollte unbedingt einen
reverse proxy einsetzen um die Angriffsfläche zu verkleinern.
Weiterhin das noch mit fail2ban absichern, was aber ein wenig Beobachtung und Konfiguration erfordertbeides ist als dockercontainer verfügbar.
einen container mit dem reverse proxy ist sehr einfach
durch ein paar zusätzliche Anweisungen im docker compose welcher dann im internet auf anfragen horchen soll.
https://hub.docker.com/r/jwilder/nginx-proxy
https://hub.docker.com/r/linuxserver/fail2bankleine werbung in eigener Sache: Wer fail2ban mit einer webgui überwachen möchte kann sich diesen Container anschauen, leider ist die kommandozeile von fail2ban etwas grausam:
https://hub.docker.com/r/oweitman/fail2bancontrol
und zur Überwachung im iobroker:
https://github.com/oweitman/ioBroker.fail2bancontrol -
An der Stelle mag ich schonmal sagen, das eine DynDNS-Adresse bspw. von MyFritz! schon ausreichend ist, damit der BotFather zu Frieden ist.
wer einen port nach außen öffnet, sollte unbedingt einen
reverse proxy einsetzen um die Angriffsfläche zu verkleinern.
Weiterhin das noch mit fail2ban absichern, was aber ein wenig Beobachtung und Konfiguration erfordertbeides ist als dockercontainer verfügbar.
einen container mit dem reverse proxy ist sehr einfach
durch ein paar zusätzliche Anweisungen im docker compose welcher dann im internet auf anfragen horchen soll.
https://hub.docker.com/r/jwilder/nginx-proxy
https://hub.docker.com/r/linuxserver/fail2bankleine werbung in eigener Sache: Wer fail2ban mit einer webgui überwachen möchte kann sich diesen Container anschauen, leider ist die kommandozeile von fail2ban etwas grausam:
https://hub.docker.com/r/oweitman/fail2bancontrol
und zur Überwachung im iobroker:
https://github.com/oweitman/ioBroker.fail2bancontrolwer einen port nach außen öffnet
Das muss es auch nicht. Davon habe ich nichts gesagt. Die Adresse muss existieren und hausintern erreichbar sein. Mehr nicht.
Ich habe nochmal alles überprüft und habe hier eine bessere Anqleitung/Erklärung:
Telegram-Konto mit Hannah verknüpfen — Setup & Voraussetzungen
Über die WebUI (
/me) kann jeder Nutzer sein eigenes Telegram-Konto mit seinem Hannah-Account verknüpfen (z.B. für Benachrichtigungen). Damit der Button dafür überhaupt erscheint, muss der Betreiber der Hannah-Instanz vorher einmalig etwas einrichten.Was man braucht
- Einen Telegram-Bot (Token + Username)
- Eine Domain, unter der die WebUI erreichbar ist
- HTTPS auf der WebUI (Zertifikat darf selfsigned sein)
- Bot-Daten in der WebUI-Konfiguration eingetragen
Schritt für Schritt
1. Bot bei BotFather anlegen
In Telegram mit @BotFather chatten,
/newbotausführen. Man bekommt danach:- einen Bot-Token (z.B.
123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) - einen Bot-Usernamen (z.B.
MeinHannahBot)
2. Domain beim Bot freischalten
Ebenfalls bei BotFather:
/setdomainausführen und die Domain eintragen, unter der die WebUI erreichbar ist (z.B.hannah.mein-zuhause.duckdns.org).Wichtig: Ohne diesen Schritt lehnt Telegram den Login-Versuch direkt ab, noch bevor er bei der WebUI ankommt.
3. Bot-Daten in der WebUI eintragen
In
config.yaml:```yaml
telegram_bot_token: "123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
telegram_bot_username: "MeinHannahBot"
```Oder bei Docker-Deployment als Umgebungsvariablen:
```
HANNAH_WEBUI_TELEGRAM_BOT_TOKEN=123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
HANNAH_WEBUI_TELEGRAM_BOT_USERNAME=MeinHannahBot
```Fehlt eines von beiden, zeigt
/menur den Hinweis "Telegram-Verknüpfung ist auf diesem Server nicht konfiguriert." — kein Fehler, einfach kein Button.Häufige Fragen zur Domain
Reicht eine DynDNS-Domain (DuckDNS, No-IP, …)?
Ja. Telegram vergleicht die Domain nur als Text (das, was bei/setdomainhinterlegt wurde, gegen das, was die WebUI beim Login-Versuch mitschickt) — es wird nicht per DNS aufgelöst oder angepingt. Dass sich die IP dahinter ständig ändert, spielt also keine Rolle.Muss das TLS-Zertifikat "echt" sein (Let's Encrypt o.ä.)?
Nein, ein selfsigned Zertifikat reicht. Grund: Telegrams Server verbinden sich nie direkt mit der WebUI. Der komplette Rücksprung läuft über den Browser des jeweiligen Nutzers:- Browser →
oauth.telegram.org(Nutzer bestätigt dort den Login) - Telegram leitet den Browser zurück zur WebUI, mit den signierten Login-Daten im Gepäck
- Ein kleines Skript auf der WebUI-Seite nimmt diese Daten entgegen und schickt sie an die WebUI
Der Browser ist es also, der die TLS-Verbindung zur WebUI aufbaut — nicht Telegram. Ein selfsigned Zertifikat funktioniert, solange der jeweilige Nutzer es akzeptiert (Klick durch die Warnung, oder eigene CA im Trust-Store).
Muss die WebUI öffentlich aus dem Internet erreichbar sein? Braucht es Portfreigabe?
Nein. Aus demselben Grund wie oben: Da nur der Browser des Nutzers die WebUI kontaktiert (nie Telegram selbst), reicht es, wenn der Browser die WebUI erreichen kann — z.B. im Heimnetz oder per VPN. Keine Portfreigabe, keine öffentliche Erreichbarkeit nötig.Aber Achtung:
Die Domain, über die man auf die WebUI zugreift, muss exakt die sein, die bei/setdomainhinterlegt wurde. Wer mal über die DynDNS-Domain und mal über eine lokale IP/einen anderen Hostnamen auf die WebUI geht, bekommt den Login-Button nur bei der registrierten Domain zu sehen bzw. der Login schlägt sonst fehl. Ich muss allerdings auch sagen, dass das nur für die Verknüpfung selbst relevant ist. Ist der Account einmal verbunden, braucht man das Widget nie wieder, bzw. erst wieder, wenn man die Verbindung trennen möchte.Der Ablauf beim eigentlichen Verknüpfen (zur Info)
- Nutzer klickt auf
/meden Telegram-Button → Redirect zu Telegram - Nutzer bestätigt dort den Login
- Telegram schickt die signierten Daten zurück — technisch als URL-Fragment (
#...), das kommt beim Server gar nicht an - Ein JS-Snippet auf der Seite liest das Fragment im Browser aus und leitet es als normalen Request an die WebUI weiter
- Die WebUI prüft die Signatur (mit dem Bot-Token) und dass die Anfrage nicht älter als 5 Minuten ist
- Passt alles → Konto ist verknüpft
Typische Stolperfallen
Problem Ursache Login-Button erscheint gar nicht telegram_bot_tokenodertelegram_bot_usernamefehlt in der ConfigTelegram bricht schon vor der WebUI ab Domain bei /setdomainfalsch/vergessen, oder stimmt nicht mit der tatsächlich aufgerufenen Domain überein"ungültige oder abgelaufene Signatur" Bot-Token in der Config falsch/vertippt, oder Nutzer hat länger als 5 Minuten gebraucht, um den Login bei Telegram zu bestätigen -
wer einen port nach außen öffnet
Das muss es auch nicht. Davon habe ich nichts gesagt. Die Adresse muss existieren und hausintern erreichbar sein. Mehr nicht.
Ich habe nochmal alles überprüft und habe hier eine bessere Anqleitung/Erklärung:
Telegram-Konto mit Hannah verknüpfen — Setup & Voraussetzungen
Über die WebUI (
/me) kann jeder Nutzer sein eigenes Telegram-Konto mit seinem Hannah-Account verknüpfen (z.B. für Benachrichtigungen). Damit der Button dafür überhaupt erscheint, muss der Betreiber der Hannah-Instanz vorher einmalig etwas einrichten.Was man braucht
- Einen Telegram-Bot (Token + Username)
- Eine Domain, unter der die WebUI erreichbar ist
- HTTPS auf der WebUI (Zertifikat darf selfsigned sein)
- Bot-Daten in der WebUI-Konfiguration eingetragen
Schritt für Schritt
1. Bot bei BotFather anlegen
In Telegram mit @BotFather chatten,
/newbotausführen. Man bekommt danach:- einen Bot-Token (z.B.
123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) - einen Bot-Usernamen (z.B.
MeinHannahBot)
2. Domain beim Bot freischalten
Ebenfalls bei BotFather:
/setdomainausführen und die Domain eintragen, unter der die WebUI erreichbar ist (z.B.hannah.mein-zuhause.duckdns.org).Wichtig: Ohne diesen Schritt lehnt Telegram den Login-Versuch direkt ab, noch bevor er bei der WebUI ankommt.
3. Bot-Daten in der WebUI eintragen
In
config.yaml:```yaml
telegram_bot_token: "123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
telegram_bot_username: "MeinHannahBot"
```Oder bei Docker-Deployment als Umgebungsvariablen:
```
HANNAH_WEBUI_TELEGRAM_BOT_TOKEN=123456789:AAExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
HANNAH_WEBUI_TELEGRAM_BOT_USERNAME=MeinHannahBot
```Fehlt eines von beiden, zeigt
/menur den Hinweis "Telegram-Verknüpfung ist auf diesem Server nicht konfiguriert." — kein Fehler, einfach kein Button.Häufige Fragen zur Domain
Reicht eine DynDNS-Domain (DuckDNS, No-IP, …)?
Ja. Telegram vergleicht die Domain nur als Text (das, was bei/setdomainhinterlegt wurde, gegen das, was die WebUI beim Login-Versuch mitschickt) — es wird nicht per DNS aufgelöst oder angepingt. Dass sich die IP dahinter ständig ändert, spielt also keine Rolle.Muss das TLS-Zertifikat "echt" sein (Let's Encrypt o.ä.)?
Nein, ein selfsigned Zertifikat reicht. Grund: Telegrams Server verbinden sich nie direkt mit der WebUI. Der komplette Rücksprung läuft über den Browser des jeweiligen Nutzers:- Browser →
oauth.telegram.org(Nutzer bestätigt dort den Login) - Telegram leitet den Browser zurück zur WebUI, mit den signierten Login-Daten im Gepäck
- Ein kleines Skript auf der WebUI-Seite nimmt diese Daten entgegen und schickt sie an die WebUI
Der Browser ist es also, der die TLS-Verbindung zur WebUI aufbaut — nicht Telegram. Ein selfsigned Zertifikat funktioniert, solange der jeweilige Nutzer es akzeptiert (Klick durch die Warnung, oder eigene CA im Trust-Store).
Muss die WebUI öffentlich aus dem Internet erreichbar sein? Braucht es Portfreigabe?
Nein. Aus demselben Grund wie oben: Da nur der Browser des Nutzers die WebUI kontaktiert (nie Telegram selbst), reicht es, wenn der Browser die WebUI erreichen kann — z.B. im Heimnetz oder per VPN. Keine Portfreigabe, keine öffentliche Erreichbarkeit nötig.Aber Achtung:
Die Domain, über die man auf die WebUI zugreift, muss exakt die sein, die bei/setdomainhinterlegt wurde. Wer mal über die DynDNS-Domain und mal über eine lokale IP/einen anderen Hostnamen auf die WebUI geht, bekommt den Login-Button nur bei der registrierten Domain zu sehen bzw. der Login schlägt sonst fehl. Ich muss allerdings auch sagen, dass das nur für die Verknüpfung selbst relevant ist. Ist der Account einmal verbunden, braucht man das Widget nie wieder, bzw. erst wieder, wenn man die Verbindung trennen möchte.Der Ablauf beim eigentlichen Verknüpfen (zur Info)
- Nutzer klickt auf
/meden Telegram-Button → Redirect zu Telegram - Nutzer bestätigt dort den Login
- Telegram schickt die signierten Daten zurück — technisch als URL-Fragment (
#...), das kommt beim Server gar nicht an - Ein JS-Snippet auf der Seite liest das Fragment im Browser aus und leitet es als normalen Request an die WebUI weiter
- Die WebUI prüft die Signatur (mit dem Bot-Token) und dass die Anfrage nicht älter als 5 Minuten ist
- Passt alles → Konto ist verknüpft
Typische Stolperfallen
Problem Ursache Login-Button erscheint gar nicht telegram_bot_tokenodertelegram_bot_usernamefehlt in der ConfigTelegram bricht schon vor der WebUI ab Domain bei /setdomainfalsch/vergessen, oder stimmt nicht mit der tatsächlich aufgerufenen Domain überein"ungültige oder abgelaufene Signatur" Bot-Token in der Config falsch/vertippt, oder Nutzer hat länger als 5 Minuten gebraucht, um den Login bei Telegram zu bestätigen -
@leonie
Denkst du noch an mich?
Habe es gerade mal auf meinem Linux PC versucht,
das irritiert mich jetzt aber. Der core ist da ja noch garnicht draufgewesen.curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/core/deploy/install.sh | sudo bash
[sudo: authenticate] Passwort:
[INFO] Fetching latest core release from https://hannah-update.sgessinger.de (channel: core-stable) ...
[INFO] Latest version: v0.75.7
walter@walter-pc:~$ systemctl status hannah
Unit hannah.service could not be found. -
Guten Morgen,
@walter.o. Dir vielen dank für die Infos und erste Fassung der Dockerfiles - das hatte mir ermöglicht direkt schonmal einen Durchstich zu machen von Spracheingabe Telegram bis funktionierender ioBroker-Statusänderung und Sprachrückgabe :)
@Leonie vielen Dank für die CI Pipeline und das Compose.
Ich find das klasse, besonders auch zB dass die diversen configs des Stacks jetzt nebeneinander liegen.
Es funktioniert damit schon einiges aber noch läuft die core nicht.Folgende kleine Änderungen habe ich gemacht, damit es für mein Setup läuft:
a) Auskommentieren der Zeilen mit "profiles" - die blockieren wohl irgendwas im Synology Container Manager (Fehlermeldung beim compose-build dann "service mysql not found" o.ä.), scheinen auch optional zu sein
b) mosquitto broker auskommentiert, habe ich in iobroker schon
c) den volumes-Block unten gelöscht und stattdessen bei den Container-Definitionen die Unterordner (core_data/timer_data...) jeweils auf von mir erstellte Unterordner von /volume1/docker/hannah (in dem Verzeichnis in dem die compose liegt)Was läuft:
- mysql
- webUI - jetzt mit static assets

- voiceid
- telegram
- proxy
Was läuft nicht (im sinne von container bleibt oben/terminiert nicht):
- hannah timer bringt fehler und terminiert regelmäßig (wartet der auf core?)
{"time":"2026-08-30T08:45:33.408807593Z","level":"INFO","msg":"starting hannah-timer","version":"dev","hannah_addr":"hannah-core:5051","db":"/app/data/timers.db"} {"time":"2026-08-30T08:45:33.409175976Z","level":"ERROR","msg":"opening store","err":"running migrations: unable to open database file (14)"}- die core, Log:
07:54:54 [INFO] hannah.main: Hannah Core dev Traceback (most recent call last): File "/app/main.py", line 2257, i <module> main() ~~~~^^ File "/app/main.py", line 101, in main init_db() ~~~~~~~^^ File "/app/hannah/utils/db.py", line 216, in init_db db = get_db() File "/app/hannah/utils/db.py", line 201, in get_db db = Database.sqlite(DB_PATH) File "/usr/local/lib/python3.14/site-packages/pyorm/database.py", line 22, in sqlite return cls(dialect.connect(database=database, **kwargs), dialect) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.14/site-packages/pyorm/dialects/sqlite.py", line 21, in connect connection = sqlite3.connect(check_same_thread=False, **kwargs) sqlite3.OperationalError: unable to open database fileBin nicht sicher wie das gedacht ist - neben der mysql (wenn ich es richtig verstehe ist die nur für Activities) muss ja die WebUI/Core ihre Settings etc. irgendwo speichern. Wenn ich es richtig verstehe ist das eine kleine sqlite.db (hannah.db?)
Gefunden hab ich in der core-config.yaml "nur" eine Angabe für hannah_users.db ?user_registry: db_path: "hannah_users.db" # SQLite-Datei (relativ zum Arbeitsverzeichnis) sync_interval: 60 # Sekunden zwischen ioBroker-AbfragenIst da trotz des Namens alles drin? Oder gibts mehrere db.files? Im Code habe ich auch eine hanna.db gefunden und weitere (zb rooms/memory.db)
Auch müsste diese Datenbank ja noch aus dem Container raus und vom volume her auf den Host ausgelagert werden, so dass man auf dem Host alles wichtige außerhalb von Containern hat, backup machen kann etc.
Aufgefallen ist mir noch dass innerhalb des Ordners mysql_data ein Ordner hannah_db angelegt wurde, ist aber leer.
./core_data ist auch leer (gemountet in den Container nach /app/data)Ich hoffe das sind nur noch Kleinigkeiten. Viele Grüße!
-
@leonie
Denkst du noch an mich?
Habe es gerade mal auf meinem Linux PC versucht,
das irritiert mich jetzt aber. Der core ist da ja noch garnicht draufgewesen.curl -fsSL https://raw.githubusercontent.com/NurPech/hannah/master/core/deploy/install.sh | sudo bash
[sudo: authenticate] Passwort:
[INFO] Fetching latest core release from https://hannah-update.sgessinger.de (channel: core-stable) ...
[INFO] Latest version: v0.75.7
walter@walter-pc:~$ systemctl status hannah
Unit hannah.service could not be found.Hi,
Denkst du noch an mich?
Ja, aber ich habe auch ein Privatleben :)
Bin nicht sicher wie das gedacht ist
Beide Fehler kommen zu 100% von deiner Änderung mit den Volumes. Ja, der Volumeblock ist optional, schließlich beschreibt der names Docker Volumes die von compose verwaltet werden. Weil du aber lieber Bind mounts nutzten willst, musst du die Dateirechte entsprechend anpassen.
"nur" eine Angabe für hannah_users.db
Der Configwert existiert bereits seit langer Zeit nicht mehr und ist in der aktuellen config.example.yaml entfernt. In meiner Container-Version wird die Datenbank nach /app/data gespeichert, weil da das Volume eingehangen wird, ist die Datenbank dann peristent. Die dedizierte hannah_users.db wird nicht verwendet.
Die memory.db ist der Langzeitspeicher für das LLM. Sozusagen die low-budget-Variante einer VectorDB. Konfigurieren kannst du die bspw. so:
llm: db: "/app/data/memory.db"innerhalb des Ordners mysql_data ein Ordner hannah_db angelegt
Das ist auch ein Fehler von dir ;) bzw. eine Eigenheit von Docker. Um dir mehr dazu zu sagen, müsstest du mir dein Compose File geben.
Evaluierung von PCPway
PCBway scheint ein guter Partner dafür zu sein
nötigen Dateien für eine Produktion
Hier habe ich einen Interessenskonflikt. Ja, die ESPs funktionieren, aber nicht fehlerfrei. Es gibt Bugs bei denen ich aktuell nicht weiß ob sie in er Firmware oder der Hardware liegen. Ich kann das Projekt dort anlegen, dann könnt ihr es bestellen, aber zu 100% glücklich bin ich noch nicht und das widerstrebt meinem Perfektionismus.
Liebe Grüße
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden