diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..9140933 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,13 @@ +# Booth reverse proxy. `:80` matches ANY hostname/IP, so the booth is reachable as +# http:///, http://localhost/, or http://parksystems.msai.al/ (the name pointed +# at the booth's IP via hosts/DNS on-site) — with no domain baked into any image. The SPA +# uses a relative /api base, so everything (HTTP + the /api/ws WebSocket, which Caddy +# upgrades automatically) just flows through to the server container. +# +# TLS later: replace `:80` with the real hostname (e.g. `parksystems.msai.al`), uncomment +# Caddy's :443 in docker-compose.prod.yml, and Caddy auto-provisions HTTPS. For a private +# CA / internal cert, use `tls /path/cert.pem /path/key.pem`. +:80 { + encode gzip + reverse_proxy server:3000 +} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 7aff09a..ce7656e 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,14 +1,41 @@ # PROD override: pull pinned registry images (no local build), restart always, real -# recognizer, and keep vision INTERNAL (only the server port is published). Use with the -# base file and pin TAG to the branch/SHA you deploy: +# recognizer, and a CADDY reverse proxy in front so operators reach the booth on a clean +# port-80 URL (no :3000) — and a path to real TLS later. Server + vision stay INTERNAL +# (only Caddy publishes a port). Use with the base file and pin TAG to the branch you deploy: # REGISTRY=git.infra.msai.al/mca/parking_solution TAG=main \ # docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d +# See wiki/decisions/container-deployment.md. services: - server: + # Reverse proxy: :80 → server:3000 (WebSocket /api/ws upgrades pass through natively). + # Caddy is a single static binary with a one-line proxy config; swapping http:// for the + # site's real hostname later enables automatic HTTPS. The booth is reached at + # http:/// (the name set via hosts/DNS on-site — NOT baked into any image). + proxy: + image: caddy:2-alpine restart: always ports: - - "3000:3000" + - "80:80" + # - "443:443" # uncomment when moving to TLS (and set a real hostname in Caddyfile) + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile:ro + - caddy-data:/data + - caddy-config:/config + depends_on: + - server + networks: + - parking + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + + server: + restart: always + # No published port — only the proxy reaches the server, over the private network. + expose: + - "3000" logging: driver: json-file options: @@ -26,3 +53,7 @@ services: options: max-size: "10m" max-file: "3" + +volumes: + caddy-data: + caddy-config: