74 lines
5.4 KiB
Markdown
74 lines
5.4 KiB
Markdown
# 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 `/healthz` to confirm current MQTT readiness, independent of bounded event-history eviction. 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.
|
|
|
|
## Deployment verification — 2026-10-10
|
|
|
|
The deployed observer was healthy and MQTT-ready. Independent device clients passed MQTT3.1.1 and5 over both plaintext and TLS, receiving receipt ACKs for raw text, arbitrary JSON and empty messages. Exact incoming/outgoing evidence was verified in the SERVER UI through the private SSH tunnel. Native response/correlation, controlled wire DUP and auth/TLS rejection checks passed. Duplicate local observer remained stopped. This is independent test-client evidence, not physical ESP32 firmware proof.
|
|
|
|
For repeatable checks against a tunnel, use:
|
|
|
|
```sh
|
|
rtk python3 scripts/check_receipts.py --credentials esp32-test-kit/connection.txt --ca esp32-test-kit/ca.crt --viewer-url http://127.0.0.1:18081
|
|
```
|
|
|
|
The script allows bounded waiting for UI evidence (default15 seconds), reports transient HTTP failures and still fails if matching evidence never appears. The old tunnel timeout was not reproduced; no historical root cause is claimed. Broker restart/persistence verification remains a separate Sprint5 gate.
|
|
|
|
## Nginx Proxy Manager setup for shop.my-mm.ir
|
|
|
|
Docker `ui-proxy` listens only on the private Docker gateway `172.20.0.1:18082` and forwards read-only requests to the backend's loopback viewer. NPM already has a network with this gateway. The public server IP has no new UI listener. The relay rewrites Host/Origin for the private viewer and streams SSE without buffering. Both backend and relay must pass deployment health checks; rollback removes only orphan services in this backend Compose project.
|
|
|
|
In NPM, add a Proxy Host:
|
|
|
|
- Domain Names: `shop.my-mm.ir`
|
|
- Scheme: `http`
|
|
- Forward Hostname/IP: `172.20.0.1`
|
|
- Forward Port: `18082`
|
|
- Cache Assets: off
|
|
- Advanced: `proxy_buffering off;` and `proxy_read_timeout 3600s;`
|
|
- SSL: request a new Let's Encrypt certificate for the domain, then enable Force SSL.
|
|
|
|
DNS already points to109.122.252.129. NPM owns domain/TLS settings; this task does not modify its routes or certificates. If its Docker network is recreated with a different gateway, update the relay listener/healthcheck and NPM upstream together. Keep the backend itself at127.0.0.1:18080.
|