Stack prinet uruchamia 4 mocki drukarek Zebra.
Adresy IP w sieci compose są konfigurowalne (ZEBRA_N_IPV4, NETWORK_SUBNET w .env).
| ID (RPI API) | Kontener | Model | ZPL (host) | Web UI (host) | IP compose (domyślne) |
|---|---|---|---|---|---|
zebra-1 |
zebra-printer-1 |
ZT230 | localhost:9100 |
http://localhost:28091 | 172.25.9.165 |
zebra-2 |
zebra-printer-2 |
ZT410 | localhost:9101 |
http://localhost:28092 | 172.25.9.166 |
zebra-3 |
zebra-printer-3 |
ZT410 | localhost:9102 |
http://localhost:28093 | 172.25.9.167 |
zebra-4 |
zebra-printer-4 |
ZT411 | localhost:9103 |
http://localhost:28094 | 172.25.9.168 |
Podsieć: NETWORK_SUBNET=172.25.9.0/24 · MSSQL 172.25.9.20 · RPI 172.25.9.100
Wewnątrz sieci Docker każdy mock nasłuchuje na :9100 (ZPL) i :8080 (HTTP). Na hoście mapowane są unikalne porty z .env (ZEBRA_N_EXTERNAL_*).
Tak — Docker Compose może używać tej samej podsieci i IP co produkcja, przez ipam.subnet + ipv4_address.
cp .env.production-lan.example .env
# albo: docker compose --env-file .env.production-lan.example --profile full up -d
Mapa (zgodna z TODO / typową LAN):
| Rola | IP |
|---|---|
| Gateway (bridge) | 192.168.8.1 |
| MSSQL | 192.168.8.20 |
| RPI | 192.168.8.100 |
| Zebra 1–4 | 192.168.8.165 … .168 |
.env ustaw zarówno IP kontenera, jak i host docelowy dla RPI:
NETWORK_SUBNET=192.168.8.0/24
NETWORK_GATEWAY=192.168.8.1
ZEBRA_1_IPV4=192.168.8.165
ZEBRA_1_HOST=192.168.8.165 # RPI łączy się po IP, nie po DNS
# … analogicznie 2–4, MSSQL_HOST=192.168.8.20
docker compose --profile full down
docker network rm prinet_wapro-network 2>/dev/null || true
docker compose --profile full up -d
docker-compose.yml| Zmienna | Rola |
|---|---|
NETWORK_SUBNET |
CIDR sieci bridge (np. 192.168.8.0/24) |
NETWORK_GATEWAY |
Gateway bridge |
MSSQL_IPV4 |
Stały IP kontenera MSSQL |
RPI_IPV4 |
Stały IP kontenera RPI |
ZEBRA_N_IPV4 |
Stały IP mocka drukarki N |
ZEBRA_N_HOST / MSSQL_HOST |
Adres, na który łączy się RPI (DNS lub IP) |
| Sytuacja | Skutek |
|---|---|
Inna sieć Docker już zajmuje ten zakres (np. 192.168.0.0/20 → obejmuje .8 i .9) |
Konflikt routingu / błąd tworzenia sieci |
Host jest w prawdziwej LAN 192.168.8.0/24 i ma te same IP urządzeń |
Bridge z tymi IP nie zastąpi fizycznych hostów — ryzyko kolizji ARP |
Host jest poza biurem (192.168.188.x itd.) |
Mock z IP .8.x działa tylko między kontenerami; z hosta nadal używasz localhost:9100 itd. |
| Chcesz prawdziwe drukarki w biurze | docker-compose.prod.yml + ZEBRA_N_HOST=<realne IP> bez mocków, albo macvlan na NIC biurowym |
Na obecnym hoście deweloperskim sieć subactor-platform_company-lan ma 192.168.0.0/20, więc nie włączaj profilu 192.168.8.0/24 / 192.168.9.0/24 dopóki ta sieć istnieje — zostaw domyślne 172.25.9.0/24.
W pliku .env:
ZEBRA_1_ENABLED=true
ZEBRA_2_ENABLED=true
ZEBRA_3_ENABLED=true
ZEBRA_4_ENABLED=true
# ZEBRA_5/6 — sloty zarezerwowane, domyślnie false (brak serwisów w compose)
RPI ładuje tylko drukarki z ENABLED=true (rpi-server/server.js → loadPrinters(), services/zebraService.js).
cd prinet
# pełny stack: MSSQL + RPI + 4× Zebra
docker compose --profile full up -d --build
# tylko drukarki
docker compose --profile zebra up -d --build
# pojedyncza drukarka
docker compose --profile zebra3 up -d zebra-printer-3
# Web status
curl -s http://localhost:28091/api/status | jq .
curl -s http://localhost:28092/api/status | jq .
curl -s http://localhost:28093/api/status | jq .
curl -s http://localhost:28094/api/status | jq .
# ZPL
printf '^XA^FO50,50^A0N,40,40^FDHELLO-1^FS^XZ\n' | nc -w 2 localhost 9100
printf '^XA^FO50,50^A0N,40,40^FDHELLO-2^FS^XZ\n' | nc -w 2 localhost 9101
printf '^XA^FO50,50^A0N,40,40^FDHELLO-3^FS^XZ\n' | nc -w 2 localhost 9102
printf '^XA^FO50,50^A0N,40,40^FDHELLO-4^FS^XZ\n' | nc -w 2 localhost 9103
# RPI — lista drukarek
curl -s http://localhost:28081/api/zebra/status | jq .
curl -s http://localhost:28081/api/health | jq .
curl -s http://localhost:28081/api/health/detailed | jq .
# E2E (czyta porty z .env)
./scripts/test-e2e.sh
| Metoda | Ścieżka | Opis |
|---|---|---|
| GET | /api/zebra/status |
Status TCP wszystkich włączonych drukarek |
| GET | /api/zebra/status/:id |
zebra-1 … zebra-4 → online / offline |
| GET | /api/zebra/test/:id |
Test połączenia |
| POST | /api/zebra/test-print/:id |
Prosta etykieta testowa ZPL |
| POST | /api/zebra/command |
Body: { "printerId": "zebra-3", "command": "^XA...^XZ" } |
| GET | /api/health |
HEALTHY tylko gdy DB + wszystkie włączone drukarki OK |
| GET | /api/health/detailed |
Szczegóły per drukarka |
GUI: http://localhost:8082 → zakładka Printers (karty ZEBRA-001 … 004).
prinet/
├── docker-compose.yml # serwisy zebra-printer-1..4 + rpi + mssql
├── .env # hosty mock, porty, ENABLED
├── zebra-printer-1/ … 4/ # ten sam mock Flask + socket ZPL
├── rpi-server/
│ ├── server.js # PRINTERS z env (1–4)
│ ├── services/zebraService.js
│ ├── routes/zebraRoutes.js # walidacja zebra-1..4
│ └── public/ # GUI 4 kart drukarek
└── scripts/test-e2e.sh # testuje 1–4 wg ENABLED
Gdy host ma dostęp do LAN z prawdziwymi Zebrami:
docker-compose.prod.yml (tylko RPI; bez mocków MSSQL/Zebra)..env (lub .env.prod) realne IP zamiast nazw serwisów:MSSQL_HOST=192.168.8.20
ZEBRA_1_HOST=192.168.8.168
ZEBRA_2_HOST=192.168.8.169
# itd.
ZEBRA_1_ENABLED=true
# wyłącz mocki nieistniejące w sieci
ZEBRA_3_ENABLED=false
ZEBRA_4_ENABLED=false
make prod / docker compose -f docker-compose.prod.yml up --buildUwaga: z maszyny deweloperskiej spoza sieci biurowej (192.168.8.x / 192.168.9.x) fizyczne drukarki są niedostępne — używaj mocka Docker.
Historyczny skan (TODO): m.in. 192.168.8.168, 192.168.8.169 (Zebra). To nie jest gwarancja 4 fizycznych urządzeń.
Domyślne porty mocka są podniesione (28081, 28091–28094), żeby nie kolidować z popularnymi 8081 / 8091 innych projektów na tym samym hoście. E2E zawsze czyta wartości z .env — nie hardcoduje starych 8091/8092.
zebra-printer-N i dodaj serwis w docker-compose.yml.ZEBRA_N_* w .env.for (let i = 1; i <= N; i++) w server.js i zebraService.js (oraz walidację w zebraRoutes.js).public/index.html) lub generuj listę z /api/zebra/status.