Skip to content

Cloud services

LilBub’s optional cloud extension is a group of independently observable components:

Public site ------> static origin
Management app ---> static origin ------> HTTPS API
|--> Supabase
|--> Redis
|--> MQTT broker
Android relay --------------------------> relay service
LilBub ------------ HTTPS + MQTTS ------> API and broker

The diagram shows separate static sites for public information and device management. The management app calls the HTTPS API. The API coordinates Supabase, Redis, and MQTT. Android connects to the relay when it offers a phone-assisted route. LilBub uses HTTPS for signed device operations and MQTTS for its direct command route.

This page is an operational map for the cited initial-preview sources. It does not label the combined deployment as reproduced or production-ready.

Component Required for Persistent state
Public static site Product and documentation pages Versioned site artifacts
Management static site Browser account and device management No server-side state in the static origin
Go API Authentication boundary, orchestration, device and integration APIs Delegates durable data to Supabase
Relay Phone-assisted WebSocket routing No durable product records
Supabase Configured authentication and application persistence Accounts, ownership, profiles, releases, bindings, and related records
Redis Presence, enrollment, rate limits, route leases, replay, and coordination Bounded ephemeral state
MQTT broker Direct backend/device transport Broker policy and any explicitly configured transport persistence
Ingress Public HTTPS routing and response policy Deployment configuration and release mapping

Losing Redis should not erase durable account data, but it can invalidate presence, pending enrollments, rate-limit state, and active routes. Losing Supabase is an application outage for account-backed API work. Losing MQTT removes the direct device route while a separately healthy phone-assisted route may still be possible.

Keep configuration in four groups:

The management build needs public API, application, relay, and Supabase endpoints plus the publishable Supabase key. Public Vite variables are shipped to the browser. They must never contain a service-role key, private signing key, broker client key, or deployment token.

The backend needs the Supabase service role, authentication verification configuration, session and CSRF behavior, allowed frontend origins, internal service authentication, and release authorization appropriate to enabled features.

The backend broker client and the device-certificate issuer have separate key roles. Generic configuration names identify CA chains, client certificates, client keys, issuer material, certificate validity, and revocation output. Private bytes belong in the deployment secret store or protected mounted storage, never in the repository.

Redis address, authentication, database selection, and TTL-related behavior belong to the backend and relay deployment. Redis must remain a private service dependency rather than a public application endpoint.

The committed example environment and backend configuration source are the field-level reference for the cited release. Copy names, not values.

Use layered checks. A green ingress response is not enough.

  1. Static origins: expected release bytes, routes, headers, and cache behavior are present.
  2. API process: /health answers through the intended public ingress.
  3. Relay process: its health endpoint answers and it can reach required coordination services.
  4. Supabase: authentication verification and a narrow read/write path used by the API succeed.
  5. Redis: the API and relay can create and expire bounded state.
  6. Broker: backend mutual TLS succeeds and broker policy permits only the intended topics.
  7. Device presence: a linked device renews its lease.
  8. Command acknowledgement: a test command reaches physical firmware and the matching acknowledgement returns.

Only the final step verifies the complete server-to-device path. Do not turn a passing HTTP response or MQTT publish into a physical-device claim.

The server hardware-in-the-loop profile exercises the deployed API and broker with a physical device. It requires a short-lived user access token and an account that owns the selected device:

Terminal window
$env:LILBUB_E2E_ACCESS_TOKEN = Read-Host 'Paste a short-lived user access token'
& .\harness\.venv\Scripts\lilbub.exe e2e server `
--serial COM6 `
--api-url https://api.example.com `
--origin https://app.example.com `
--output artifacts/e2e/server.json
Remove-Item Env:LILBUB_E2E_ACCESS_TOKEN

The run confirms identity, Wi-Fi, cloud link, broker identity, API health, ownership, Redis-backed presence, live-session authentication, MQTT delivery, firmware application, acknowledgement, preview cleanup, and final device health. Keep it as an explicit credential-gated lab job, not a default pull request test.

Back up by ownership instead of copying an entire host:

  • Supabase backups cover durable application records and schema-compatible restore.
  • Broker CA, issuer, client identity, revocation state, and OTA signing authority require protected key-management and recovery procedures.
  • Release artifacts and their manifests need immutable storage and digest verification.
  • Static site and management releases should be reproducible from immutable source and dependencies.
  • Redis state is intentionally expiring. Restoring an old Redis snapshot can resurrect invalid tickets, leases, or presence and should not be the default recovery strategy.

A backup is not established until a clean restore reaches the corresponding health checks. Store private recovery material outside the public documentation.

Cloud-linked devices use client certificates for MQTT. Operations therefore need to cover:

  1. issuing a certificate only for an authenticated device identity;
  2. recording its serial, fingerprint, and validity;
  3. refreshing it before expiry while the current identity still works;
  4. revoking credentials when a device is unpaired or compromised;
  5. publishing broker revocation state safely; and
  6. verifying that the replacement path works before removing the previous one.

Never revoke the last working administrative or device credential without a verified replacement and rollback path.

Symptom Inspect first Do not assume
Management app will not load Static origin, route mapping, headers The API is also down
Login fails Supabase auth path, API auth configuration, cookies and origin policy Device connectivity is involved
Device appears offline Redis presence, broker session, phone route lease, device Wi-Fi Durable device records are missing
Command accepted but not applied Selected route, broker or relay delivery, matching acknowledgement HTTP success proves application
Phone relay fails Relay health, ticket issuance, lease ownership, Android session MQTT must also be failing
Direct cloud fails Device cloud policy, Wi-Fi, certificate validity, broker TLS and ACL Nearby control is unavailable
Enrollment stalls Redis enrollment state, expiry, API limits, device polling Retrying indefinitely is safe
Update fails Signed manifest, compatibility, download, inactive slot, boot health Reflashing the active slot is the first remedy

Recovery should restore the narrowest failed layer and preserve independent working routes. For example, a broker repair should not require resetting Supabase, and a web-origin rollback should not rotate device credentials.

For a coordinated release:

  1. capture recoverable persistent state;
  2. validate schema changes against a disposable local environment;
  3. deploy backward-consistent infrastructure needed by the candidate;
  4. deploy API and relay;
  5. publish static management and public assets;
  6. verify health and route contracts;
  7. exercise a physical device acknowledgement path; and
  8. promote firmware only after its required services are available.

The project is greenfield, so prefer a clean schema and protocol design over long-lived compatibility layers. That does not remove the need for an explicitly scoped rollback during deployment.

End of article