Files
HoneyOS/beispiele/mehrere-apps/docker-compose.yml
T
marcandClaude Opus 5 9da6503837 docs: durchgaengig HoneyBar statt Leiste
Der Dienst im Beispiel heisst jetzt einsetzer — er ist nicht die HoneyBar,
er setzt sie ein. Zusammensetzungen wie Menueleiste, Taskleiste und
Statusleiste bleiben, die meinen etwas anderes.

Dazu in IDEAS notiert, dass HoneyBar und Menueleiste zwei getrennte Stilsaetze
sind und schon einmal auseinandergelaufen ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 16:57:01 +02:00

154 lines
6.9 KiB
YAML

# ─────────────────────────────────────────────────────────────────────────────
# HoneyOS und ein Einsetzer für beliebig viele fremde Dienste.
#
# außen ──► Pangolin ──► honeyos (der Schreibtisch)
# Pangolin ──► einsetzer ──► bentopdf:8080 (App mit HoneyBar)
# │ ──► uptime-kuma:3001
# └──► honeyos:8080 (HoneyBar + zwei Abfragen)
#
# Die fremden Dienste brauchen kein `ports:` mehr — erreichbar sind sie über
# ihren Namen im Netz `honeybar`, und nach außen führt nur der Einsetzer.
#
# Eine neue App hinzufügen heißt: zwei Zeilen in den Tabellen `$ziel` und
# `$appid`, dann `docker compose up -d --force-recreate einsetzer`.
#
# cp ../../.env.example .env && ausfüllen (HONEYOS_APPS_KEY setzen!)
# mkdir -p daten && sudo chown 1000:1000 daten
# docker compose up -d
#
# Danach in Pangolin: honeyos.… → honeyos:8080, jede App → einsetzer:80.
# Und in HoneyOS jede App eintragen — die `ID` dort muss dem `$appid` hier
# entsprechen, sonst weiß die HoneyBar nicht, in welcher App man gerade ist.
# ─────────────────────────────────────────────────────────────────────────────
services:
honeyos:
image: gitea.honeyy.duckdns.org/docker/honeyos:latest
container_name: honeyos
restart: unless-stopped
user: "1000:1000"
ports:
- "${HONEYOS_PORT:-8088}:8080"
volumes:
- ${HONEYOS_DATA_DIR:-./daten}:/data
environment:
- HONEYOS_PUBLIC_URL=${HONEYOS_PUBLIC_URL:-}
- HONEYOS_SESSION_SECRET=${HONEYOS_SESSION_SECRET:-}
- HONEYOS_OIDC_ISSUER=${HONEYOS_OIDC_ISSUER:-}
- HONEYOS_OIDC_CLIENT_ID=${HONEYOS_OIDC_CLIENT_ID:-}
- HONEYOS_OIDC_CLIENT_SECRET=${HONEYOS_OIDC_CLIENT_SECRET:-}
- HONEYOS_OIDC_REDIRECT_URL=${HONEYOS_OIDC_REDIRECT_URL:-}
- HONEYOS_BUTTON_LABEL=${HONEYOS_BUTTON_LABEL:-Anmelden}
- HONEYOS_ALLOWED_USERS=${HONEYOS_ALLOWED_USERS:-}
- HONEYOS_PROXY_AUTH=${HONEYOS_PROXY_AUTH:-}
- HONEYOS_USER_HEADER=${HONEYOS_USER_HEADER:-}
- HONEYOS_APPS_KEY=${HONEYOS_APPS_KEY:-}
networks: [honeybar]
einsetzer:
image: nginx:alpine
container_name: honeybar-einsetzer
restart: unless-stopped
ports:
- "${LEISTE_PORT:-8185}:80"
configs:
- source: einsetzer
target: /etc/nginx/conf.d/default.conf
networks: [honeybar]
# Kein depends_on: Der Einsetzer reicht nur durch. Ist HoneyOS aus, fehlt
# die HoneyBar — die Apps laufen weiter.
configs:
einsetzer:
# `$$` ist hier ein einfaches `$` für nginx. Ein einzelnes `$` setzt
# dagegen Compose ein — genau das ist bei ${HONEYOS_APPS_KEY} gewollt: der
# Schlüssel steht damit nur in der nginx-Konfiguration, nie in der Seite.
content: |
# ── Welcher Dienst steckt hinter welchem Namen ────────────────────────
# Links die Adresse, unter der du die App aufrufst; rechts Behältername
# und Port im Docker-Netz.
map $$host $$ziel {
default "";
pdf.honeyos.duckdns.org "bentopdf:8080";
status.honeyos.duckdns.org "uptime-kuma:3001";
}
# ── Und welche App das für HoneyOS ist ────────────────────────────────
# Muss der `ID` in der App-Liste entsprechen. Daran erkennt die HoneyBar,
# wo man gerade ist, und hebt den Eintrag hervor — wie in Aether.
map $$host $$appid {
default "";
pdf.honeyos.duckdns.org "bentopdf";
status.honeyos.duckdns.org "status";
}
map $$http_upgrade $$connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name _;
resolver 127.0.0.11 valid=30s ipv6=off;
# Unbekannter Name: nicht raten. Sonst wird aus einem Tippfehler in
# Pangolin eine stille Weiterleitung irgendwohin.
if ($$ziel = "") { return 404; }
# Uploads nicht hier begrenzen — nginx nimmt sonst bei 1 MB nichts
# mehr an, und jede App mit Dateiupload waere hinter dem Einsetzer
# kaputt. Wieviel erlaubt ist, entscheidet die App dahinter.
client_max_body_size 0;
# ── Die HoneyBar, durchgereicht über DIESE Adresse ──────────────────
# Dadurch ist sie für den Browser eigener Ursprung: Die CSP der App
# bleibt unangetastet, CORS und COEP entfallen.
location /honeybar/ {
proxy_pass http://honeyos:8080/honeybar/;
}
# Ihre zwei Abfragen — einzeln benannt und nur lesend. Ein pauschales
# /api/ hinge die ganze HoneyOS-Schnittstelle unter die Adresse der
# App. Den Ausweis setzt der Server ein.
location = /honeyos-api/apps {
limit_except GET { deny all; }
proxy_pass http://honeyos:8080/api/apps;
proxy_set_header X-HoneyOS-Key "${HONEYOS_APPS_KEY}";
}
location = /honeyos-api/weather {
limit_except GET { deny all; }
proxy_pass http://honeyos:8080/api/weather;
proxy_set_header X-HoneyOS-Key "${HONEYOS_APPS_KEY}";
}
# ── Die App selbst ───────────────────────────────────────────────
location / {
proxy_pass http://$$ziel;
proxy_set_header Host $$host;
proxy_set_header X-Forwarded-For $$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $$scheme;
proxy_set_header X-Real-IP $$remote_addr;
# WebSockets durchlassen — Live-Anzeigen brechen sonst ab.
proxy_http_version 1.1;
proxy_set_header Upgrade $$http_upgrade;
proxy_set_header Connection $$connection_upgrade;
# Unkomprimiert anfordern, sonst ist nichts zu ersetzen.
proxy_set_header Accept-Encoding "";
sub_filter_once on;
sub_filter '</head>'
'<script defer src="/honeybar/honeybar.js" data-app="$$appid" data-apps="/honeyos-api/apps" data-home="https://honeyos.duckdns.org/"></script></head>';
proxy_buffering off;
proxy_read_timeout 300s;
}
}
networks:
honeybar:
# Fester Name, damit die App-Stapel ihn als `external` finden.
name: honeybar