# Fixed public deployment The public demo is hosted directly on the server at `https://511.kendeji.fun`. Caddy terminates HTTPS and proxies only to the container port bound on `127.0.0.1:8511`; the application port is not exposed to the public network. The server layout is: ```text /opt/511-project/ ├── .env # OpenAI connection settings, mode 0600 ├── .env.auth # Web authentication settings, mode 0600 ├── deploy/server/ ├── artifacts/runs/ # Persistent request artifacts └── artifacts/user-presets/ ``` Build and start the service: ```bash cd /opt/511-project chown -R root:root artifacts/runs artifacts/user-presets chmod 0700 artifacts/runs artifacts/user-presets docker compose -f deploy/server/compose.yaml up -d --build docker compose -f deploy/server/compose.yaml ps ``` Add `deploy/server/Caddyfile.example` to the host Caddyfile, validate, and reload Caddy: ```bash caddy validate --config /etc/caddy/Caddyfile systemctl restart caddy ``` This host disables Caddy's admin endpoint, so `caddy reload` and `systemctl reload caddy` cannot apply configuration. Validate first, then use a service restart. Operational checks: ```bash curl -I https://511.kendeji.fun/ docker compose -f /opt/511-project/deploy/server/compose.yaml logs --tail=100 systemctl status caddy ``` Never place `.env`, `.env.auth`, API keys, login passwords, or SSH credentials inside the image or source control. Updating the application uses the same source synchronization followed by `docker compose ... up -d --build`. ## Public physical-bench gateway When the physical T2G bench is attached to a separate trusted workstation, Caddy may prefer a restricted reverse-SSH upstream on `127.0.0.1:18512` and retain the container on `127.0.0.1:8511` as the unavailable-bench fallback. The workstation service must use the same `.env.auth` as the public container; the SSH key must be restricted to that single reverse-listen port and must not be allowed to run remote commands. The physical bench is a process-wide single-flight resource. A hardware action owns the bench from intent planning through final physical feedback. Concurrent hardware actions and passive physical-state reads receive HTTP `409` (`hardware_busy`) with `Retry-After`; they never enter the CAN path or wait to run later against stale position state. Dry-run and simulated-hardware requests are not serialized by this gate.