The native app downloads per-venue UI bundles from the plain-HTTP LAN port (integrity via the sha256 in the manifest it fetched over pinned TLS), so it needs to know the published port. compose passes HTTP_PORT to the backend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
2.6 KiB
YAML
79 lines
2.6 KiB
YAML
services:
|
|
backend:
|
|
image: ${REGISTRY}/pos-backend:${VERSION:-latest}
|
|
restart: unless-stopped
|
|
environment:
|
|
- SITE_ID=${SITE_ID}
|
|
- SITE_KEY=${SITE_KEY}
|
|
- CLOUD_URL=${CLOUD_URL}
|
|
- SECRET_KEY=${SECRET_KEY}
|
|
- LICENSE_GRACE_HOURS=${LICENSE_GRACE_HOURS:-24}
|
|
- DATABASE_URL=sqlite:////app/data/pos.db
|
|
- VERSION=${VERSION:-0.0.0}
|
|
- HOST_IP=${HOST_IP:-}
|
|
- TLS_PORT=${TLS_PORT:-8443} # published port of the proxy's TLS entry (advertised to the app)
|
|
- HTTP_PORT=${HTTP_PORT:-80} # published plain-HTTP LAN port (app downloads UI bundles from it)
|
|
- MASTER_USERNAME=${MASTER_USERNAME:-}
|
|
- MASTER_PASSWORD=${MASTER_PASSWORD:-}
|
|
volumes:
|
|
- ${DATA_PATH}:/app/data
|
|
- ${LOGO_PATH}:/app/logo.png:ro
|
|
- ${FISCAL_PATH}:/mnt/fiscal
|
|
- netinfo:/netinfo:ro
|
|
# "Healthy" = app started, which also means the TLS key/cert for the
|
|
# proxy's :8443 exist (created at startup by services/tls_identity.py)
|
|
healthcheck:
|
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/system/health', timeout=3)"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 12
|
|
start_period: 20s
|
|
|
|
# Finds the server's LAN IP on the PHYSICAL network (never a VPN) every minute
|
|
# and shares it with the backend (pairing QR, manager, heartbeat). Needs the
|
|
# host's network namespace because the backend's bridge network can't see
|
|
# real NICs. Same image as the backend — see services/netinfo_helper.py.
|
|
netinfo:
|
|
image: ${REGISTRY}/pos-backend:${VERSION:-latest}
|
|
restart: unless-stopped
|
|
network_mode: host
|
|
command: ["python", "-m", "services.netinfo_helper"]
|
|
volumes:
|
|
- netinfo:/netinfo
|
|
|
|
waiter_pwa:
|
|
image: ${REGISTRY}/pos-waiter:${VERSION:-latest}
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- backend
|
|
|
|
manager_dashboard:
|
|
image: ${REGISTRY}/pos-manager:${VERSION:-latest}
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- backend
|
|
|
|
proxy:
|
|
image: nginx:alpine
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
- "4443:4443"
|
|
- "8081:8081" # manager over plain HTTP (LAN only)
|
|
- "8443:8443" # native app over TLS with a pinned key (LAN only)
|
|
volumes:
|
|
- ./nginx-proxy/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
|
- ./certs:/etc/nginx/certs:ro
|
|
- ${DATA_PATH}/tls:/etc/nginx/xenia-tls:ro
|
|
depends_on:
|
|
backend:
|
|
condition: service_healthy
|
|
waiter_pwa:
|
|
condition: service_started
|
|
manager_dashboard:
|
|
condition: service_started
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
netinfo:
|