# Backend deployment and Gitea Actions Repository: `ssh://git@git.my-rm.com:2222/Robot-Market/mqtt-5-test.git`. Deployment branch: `main`. Target: existing test server `109.122.252.129`, separate Compose project `mqtt5-test-backend`, runtime `/opt/test-mqtt-5/backend`. Broker remains in `/opt/test-mqtt-5/deploy`. The backend uses TLS to the existing broker, accepts raw test messages and sends receipt ACKs. No simulator is deployed. Private credentials and CA are provisioned on the server; never include ESP32 ZIP, private JSON, local .env or certificates/keys in Git. Event history is in memory and resets when the backend restarts. ## Access the UI Run on your local computer and keep it running: ```sh ssh -N -L 8080:127.0.0.1:18080 root@109.122.252.129 ``` Open http://127.0.0.1:8080. If local port 8080 is occupied, use `-L 8081:127.0.0.1:18080` and open http://127.0.0.1:8081. The server listens only on 127.0.0.1:18080. No public firewall port is required. Stop a local receipt observer while using this server backend to avoid two independent receipt ACK publishers. ## CI/CD `.gitea/workflows/backend.yml` runs on main pushes, main pull requests and manual dispatch. The test job builds the Docker test target (unit tests plus vet); remote integration tests are opt-in and skipped without private handoffs. The deploy job runs only on main, never for a PR. It builds an immutable UTC timestamp plus commit tag, then runs `server/deploy.sh`. No registry or SSH deployment secret is needed: the existing ubuntu-latest runner uses this server's Docker socket. The runner configuration allows `/opt/test-mqtt-5/backend` in `container.valid_volumes`; only the deploy job requests that mount as `/runtime`. The prior runner configuration is backed up before this addition. Existing frontend job mounts remain unchanged. This workflow assumes that label continues to use the same server Docker daemon; moving the runner requires updating the deployment arrangement. `deploy.sh` locks the runtime directory, validates Compose, preserves the previous image-tag file and Compose, deploys only backend, and checks container health for up to 60 seconds. Health requires the UI snapshot to report MQTT connected. Failed updates restore the previous release; a failed first deployment stops the backend. Images are retained for rollback. No host-wide image prune is run. Remote device return-path checks should still be performed after significant MQTT changes. ## Server operations Standard Linux commands on the server: ```sh cd /opt/test-mqtt-5/backend docker compose --env-file .env -f compose.yaml ps docker compose --env-file .env -f compose.yaml logs -f backend docker compose --env-file .env -f compose.yaml restart backend ``` Manual rollback to the preserved release: ```sh cd /opt/test-mqtt-5/backend cp .env.previous .env cp compose.previous.yaml compose.yaml docker compose --env-file .env -f compose.yaml up -d --force-recreate backend ``` During deployments do not run a simultaneous manual rollback. Before changing broker credentials, update the server's private `secrets/backend.json` (root:10001, mode 0640, parent directory 0750) and restart backend. Do not rotate the broker's existing credentials as part of ordinary backend deployments.