feat(deploy): Caddy reverse proxy — clean port-80 URL, server internal
Operators/admins reach the booth at http://<name-or-ip>/ (no :3000). Adds a caddy:2-alpine
proxy to the prod override that reverse-proxies :80 → server:3000 (the /api/ws WebSocket
upgrades pass through natively); the server is now `expose: 3000` (internal, no published
port), vision stays internal. The Caddyfile binds `:80` so it matches ANY hostname/IP —
works for the booth IP, localhost, AND parksystems.msai.al (pointed at the booth via
hosts/DNS on-site; no domain baked into any image). TLS later = swap `:80` for the real
hostname + uncomment :443 → Caddy auto-provisions HTTPS.
Pairs with the relative-/api SPA fix (77b2acb): together verified end-to-end locally —
through Caddy on :80 with Host: parksystems.msai.al, GET / serves the SPA, assets/health
200, and POST /api/auth/login reaches the server (real 401, no CORS/connection error).
Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
# Booth reverse proxy. `:80` matches ANY hostname/IP, so the booth is reachable as
|
||||||
|
# http://<booth-ip>/, 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
|
||||||
|
}
|
||||||
+35
-4
@@ -1,14 +1,41 @@
|
|||||||
# PROD override: pull pinned registry images (no local build), restart always, real
|
# 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
|
# recognizer, and a CADDY reverse proxy in front so operators reach the booth on a clean
|
||||||
# base file and pin TAG to the branch/SHA you deploy:
|
# 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 \
|
# REGISTRY=git.infra.msai.al/mca/parking_solution TAG=main \
|
||||||
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||||
|
# See wiki/decisions/container-deployment.md.
|
||||||
|
|
||||||
services:
|
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://<name-or-ip>/ (the name set via hosts/DNS on-site — NOT baked into any image).
|
||||||
|
proxy:
|
||||||
|
image: caddy:2-alpine
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
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:
|
logging:
|
||||||
driver: json-file
|
driver: json-file
|
||||||
options:
|
options:
|
||||||
@@ -26,3 +53,7 @@ services:
|
|||||||
options:
|
options:
|
||||||
max-size: "10m"
|
max-size: "10m"
|
||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
caddy-data:
|
||||||
|
caddy-config:
|
||||||
|
|||||||
Reference in New Issue
Block a user