- Python 55%
- HTML 43.6%
- Dockerfile 1.4%
- shop.html unter /: Sortiment aus Template-JSONs, dynamisches Formular, Live-Vorschau = serverseitiges Druckbild (WYSIWYG), Logo-Upload mit clientseitigem Downscale, Preisanzeige - Templates: price_cents, description, Feld-Labels - /api/templates liefert Preis + Beschreibung mit |
||
|---|---|---|
| agent | ||
| server | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.agent-mode.server.yml | ||
| docker-compose.agent.yml | ||
| docker-compose.yml | ||
| README.md | ||
Labelshop -- Godex-Etikettenshop (Docker)
Webserver und Godex stehen im selben LAN -> EIN Stack reicht. Der Labelshop-Container druckt direkt auf die LAN-IP des Godex (Port 9100), ein interner Worker arbeitet die Job-Warteschlange ab:
Internet LAN zuhause
Kunde --HTTPS--> Reverse Proxy --> +--------------------------+
(Plesk/nginx) | labelshop (Docker) |
| Shop-API + Vorschau |
| Bestellungen (SQLite) |
| Druckzentrale /admin |
| Druck-Worker -----------+--Raw 9100--> Godex
+--------------------------+
Die Warteschlange bleibt trotzdem: Drucker aus = Jobs bleiben liegen und werden automatisch nachgeholt, sobald er wieder erreichbar ist. Der Worker prueft vor jedem Job die Erreichbarkeit.
Agent-Modus als Reserve: Laesst man PRINTER_HOST leer, druckt der
Server nicht selbst, sondern stellt die Agent-API bereit
(docker-compose.agent.yml + agent/ -- fuer den Fall, dass der Shop
irgendwann auf einen externen Server umzieht). Fuer dein Setup: ignorieren.
Verzeichnis
labelshop/
├── docker-compose.server.yml Stack fuer den Webserver
├── docker-compose.agent.yml Stack fuer zuhause (neben Home Assistant o.ae.)
├── server/
│ ├── app.py FastAPI: Shop-, Admin- und Agent-API
│ ├── db.py SQLite (orders, jobs) auf Volume /data
│ ├── label_renderer.py Template + Daten -> 1-Bit-Bitmap (WYSIWYG)
│ ├── ezpl.py Bitmap -> EZPL-Druckjob (GW-Grafik)
│ ├── admin.html Druckzentrale (Web-UI unter /admin)
│ ├── label_templates/*.json Etikettendefinitionen = Shop-Sortiment
│ └── Dockerfile installiert auch fonts-dejavu-core!
└── agent/
├── agent.py Poller: Job holen -> an 9100 senden -> done
└── Dockerfile
Deployment
Stack aus docker-compose.yml (auch via Portainer):
ADMIN_TOKENdurch langen Zufallswert ersetzen (openssl rand -hex 24).PRINTER_HOST= LAN-IP des Godex. Dem Drucker am besten eine feste IP bzw. DHCP-Reservierung geben, sonst wandert er irgendwann.- Stack starten -> lauscht auf Port 8080. Reverse Proxy mit HTTPS davor
(Plesk/nginx), z.B.
labels.deine-domain.de -> 127.0.0.1:8080. - Druckzentrale:
https://labels.deine-domain.de/admin. Zeigt oben live, ob der Godex erreichbar ist (gruener/roter Punkt).
Docker-Hinweis: Der Container erreicht die Drucker-IP aus dem normalen
Bridge-Netz heraus (ausgehendes NAT ueber den Host) -- kein
network_mode: host und keine Sonderkonfiguration noetig.
Ablauf einer Bestellung
- Kunde (spaeter: Shop-Frontend) ->
POST /api/ordersmit Template-ID, Feldtexten, optional Logo (Base64-PNG), Stueckzahl. Der Server rendert einmal zur Probe -- kaputte Bestellungen werden sofort abgelehnt. - Abends: Druckzentrale
/adminzeigt alles gruppiert nach Etikettentyp. Vorschau pruefen, richtige Rolle einlegen, "Rolle liegt ein -> alle drucken". Es wird nie ueber Typgrenzen hinweg gemischt gedruckt. - Der Druck-Worker im Container schickt die EZPL-Jobs nacheinander an den
Godex -> Bestellung steht auf
printed. Druckzentrale kurz aktualisieren und zuschauen, wie die Liste leer wird.
Neues Etikett ins Sortiment
Eine JSON-Datei in server/label_templates/ ablegen (Vorlage: die
vorhandene), Container neu starten. Feldtypen: text (mit Auto-Verkleinern
bei zu langem Text), image (Logo-Box mit Dithering), line.
Wichtig: dpi muss zum Drucker passen (203 oder 300).
Kalibrierung beim ersten echten Druck
- Invertierter Ausdruck ->
LABEL_INVERT: "1"im Server-Stack. - Zu blass/zu fett ->
LABEL_DARKNESS(0-19). - Laenge/Gap verrutscht ->
gap_mmim Template + Gap-Kalibrierung am Drucker.
Shop-Frontend
Unter / liegt der Kundenshop (server/shop.html): Sortiment aus den
Template-JSONs, Editor mit Live-Vorschau (debounced ueber POST /api/preview), Logo-Upload (wird clientseitig auf max. 1000px verkleinert),
Stueckzahl mit Preisanzeige (price_cents im Template), Bestellabschluss.
Die Vorschau ist das identische Bitmap, das spaeter gedruckt wird.
Was bewusst noch fehlt (naechste Ausbaustufen)
- Stripe Checkout: Bestellung anlegen -> Checkout-Session -> Webhook
setzt Status
paid; Druckzentrale zeigt dann nur bezahlte Bestellungen. - Rate-Limiting auf den oeffentlichen Endpunkten, bevor der Shop live geht (Preview rendert Bilder, das soll niemand automatisiert hammern).
- Job-Wiederholung/Storno in der Druckzentrale.