ops/deploy.py ships each service's build context to the remote Docker
daemon's /build endpoint and pushes docker-compose.prod.yml as a Portainer
stack — there is no docker CLI in WSL and Unraid's SSH is closed.
The prod compose file drops the dev bind mounts and uvicorn --reload,
publishes only the frontend port (8000 is taken by Portainer's Edge
tunnel), and pins bms_net to 172.31.42.0/24 because the host's default
address pools are fully subnetted. Mosquitto's config is baked into an
image since the repo is not checked out on the host.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>