Includes: - Backend services: ingestion (:8001), weather API (:8002), gateway (:8003), billing (:8004) with BTCPay integration - Shared asyncpg pool, TimescaleDB hypertable, Redis, Mosquitto MQTT - React frontend: Dashboard (MapLibre) and Messaging (chat UI) - Bridge daemon for Pi + Meshtastic (Serial/TCP T-Deck support) - Production Docker Compose, Nginx reverse proxy, ops scripts - DEPLOY.md with step-by-step deployment guide
8.0 KiB
KosmoConnect Deployment Guide
This document walks you through deploying the entire KosmoConnect stack: cloud backend, web frontends, Raspberry Pi bridge daemon, and T-Deck integration.
1. Prerequisites
Cloud Server (VPS or bare metal)
- OS: Ubuntu 22.04 LTS or Debian 12 recommended
- RAM: 2GB minimum, 4GB recommended
- Ports: 22 (SSH), 80 (HTTP), 443 (HTTPS), 1883 (MQTT — can be restricted)
- Domain: Optional but strongly recommended (e.g.,
kosmo.example.com)
Raspberry Pi (Bridge Node)
- Model: Pi 3B+ or Pi 4
- OS: Raspberry Pi OS Lite (64-bit)
- Peripherals: Reliable power supply, internet (WiFi or Ethernet)
- Meshtastic device: T-Deck (WiFi mode) or T-Beam (USB)
Local Development Machine
- Docker & Docker Compose
- Node.js 20+ and npm
- Python 3.13+ (for testing)
2. Cloud Backend Deployment
2.1 Prepare the Server
# On your server
sudo apt update && sudo apt upgrade -y
sudo apt install -y git docker.io docker-compose nginx certbot python3-certbot-nginx
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect
2.2 Clone the Repository
git clone https://your-repo/kosmo-connect.git
cd kosmo-connect
2.3 Configure Environment
cd backend
cp .env.prod.example .env
nano .env
Fill in:
POSTGRES_PASSWORD— strong random passwordBTCPAY_API_KEY,BTCPAY_STORE_ID,WEBHOOK_SECRET— from your BTCPay Server
2.4 Build Web Frontends
cd ../web
./build.sh
This produces:
web/dashboard/dist/web/messaging/dist/
2.5 Start Backend Services
cd ../backend
docker-compose -f docker-compose.prod.yml up -d --build
Services will be available on localhost ports inside the server:
- API:
127.0.0.1:8002 - Ingestion:
127.0.0.1:8001 - Gateway:
127.0.0.1:8003 - Billing:
127.0.0.1:8004 - MQTT:
127.0.0.1:1883(only locally exposed by default)
Nginx serves the static frontends on port 80 and proxies /api to the correct service.
2.6 Seed the Database (First Time Only)
# Seed test users for dev / early testing
docker-compose -f docker-compose.prod.yml exec -T timescaledb \
psql -U kosmo -d kosmoconnect < migrations/002_seed_test_users.sql
2.7 Configure SSL (Recommended)
If you have a domain pointing to the server:
sudo certbot --nginx -d kosmo.example.com
Update backend/nginx.conf to use HTTPS and redirect HTTP to HTTPS. Then reload nginx:
docker-compose -f docker-compose.prod.yml restart nginx
2.8 Open MQTT to the Bridge (If Needed)
By default, Mosquitto only listens on 127.0.0.1:1883. If your Pi bridge needs to connect over the internet, you have two options:
Option A: VPN / WireGuard (recommended for security)
- Run a WireGuard server on the cloud host
- Connect the Pi as a peer
- The Pi can then reach Mosquitto at
mosquitto:1883internally
Option B: Public MQTT with Authentication
- Change the Mosquitto port binding in
docker-compose.prod.ymlto0.0.0.0:1883 - Enable TLS on Mosquitto and require username/password
- Update
mosquitto.confwith authentication
3. Raspberry Pi Bridge Deployment
3.1 Prepare the Pi
# On the Pi
sudo apt update
sudo apt install -y python3-venv python3-pip git rsync
3.2 Deploy from Your Dev Machine
cd firmware/infrastructure-node/bridge-daemon
./deploy-pi.sh 192.168.1.50 pi
This copies the daemon to /opt/kosmo-bridge and installs the systemd service.
3.3 Configure the Bridge
Edit the service to point to your cloud MQTT broker:
ssh pi@192.168.1.50
sudo systemctl edit --full kosmo-bridge
Example for T-Deck over WiFi:
[Service]
Environment="PYTHONUNBUFFERED=1"
Environment="MQTT_HOST=kosmo.example.com"
Environment="MQTT_PORT=1883"
Environment="MESHTASTIC_HOST=192.168.1.45"
Environment="MESHTASTIC_TCP_PORT=4403"
Environment="GATEWAY_NODE_ID=!yourgateway01"
Or for USB T-Beam:
Environment="MQTT_HOST=kosmo.example.com"
Environment="MQTT_PORT=1883"
Environment="MESHTASTIC_DEVICE=/dev/ttyUSB0"
Environment="GATEWAY_NODE_ID=!yourgateway01"
3.4 Start and Monitor
sudo systemctl daemon-reload
sudo systemctl restart kosmo-bridge
sudo journalctl -u kosmo-bridge -f
4. T-Deck WiFi Setup
4.1 Enable WiFi on the T-Deck
Using the Meshtastic app on your phone or the Python CLI:
meshtastic --host <t-deck-ip> --set wifi_ssid "YourNetwork" --set wifi_psk "YourPassword"
Or via the device menu if the T-Deck firmware supports on-screen WiFi config.
4.2 Find the T-Deck IP
Check your router's DHCP table, or scan the network:
nmap -p 4403 192.168.1.0/24
You should see an open port 4403 on the T-Deck's IP.
4.3 Test Mesh Connectivity
Send a text message from another Meshtastic node. You should see it appear in the cloud logs:
# On the cloud server
docker-compose -f docker-compose.prod.yml logs -f gateway
5. BTCPay Server Webhook Configuration
- Log in to
https://pay.cqre.net - Go to your store → Webhooks → Create Webhook
- Payload URL:
https://kosmo.example.com/api/v1/billing/webhooks/btcpay - Select events:
Invoice createdInvoice settledInvoice expiredInvoice invalid
- Save and copy the Webhook Secret
- Paste it into your cloud server's
.envasWEBHOOK_SECRET - Restart billing:
cd backend docker-compose -f docker-compose.prod.yml restart billing
6. Post-Deployment Checklist
| Check | Command / Test |
|---|---|
| Dashboard loads | Open https://kosmo.example.com/ in browser |
| Messaging client loads | Open https://kosmo.example.com/messaging |
| API healthy | curl https://kosmo.example.com/api/v1/weather/latest |
| Gateway healthy | curl https://kosmo.example.com/api/v1/messages/conversations -H "X-User-ID: ..." |
| Billing healthy | curl https://kosmo.example.com/api/v1/billing/invoices -H "X-User-ID: ..." |
| MQTT reachable from Pi | nc -vz kosmo.example.com 1883 (or via VPN) |
| Bridge daemon running | ssh pi@... "sudo systemctl status kosmo-bridge" |
| Mesh messages flow | Send text from T-Deck, check gateway logs |
| Web-to-mesh works | Send message from browser, receive on T-Deck |
| BTCPay webhook works | Create invoice, pay it, verify subscription activates |
7. Updating After Deployment
Update Backend
cd kosmo-connect/backend
git pull
docker-compose -f docker-compose.prod.yml up -d --build
Update Web Frontends
cd kosmo-connect/web
./build.sh
cd ../backend
docker-compose -f docker-compose.prod.yml restart nginx
Update Bridge Daemon on Pi
cd kosmo-connect/firmware/infrastructure-node/bridge-daemon
./deploy-pi.sh 192.168.1.50 pi
ssh pi@192.168.1.50 "sudo systemctl restart kosmo-bridge"
8. Troubleshooting
Dashboard shows no nodes
- Verify ingestion service is running
- Check that
simulate-bridge.pyor a real bridge is publishing to MQTT - Inspect ingestion logs:
docker-compose -f docker-compose.prod.yml logs ingestion
T-Deck not reachable over TCP
- Ensure T-Deck and Pi are on the same WiFi network
- Verify port 4403 is open:
nmap -p 4403 <t-deck-ip> - Try restarting the T-Deck
Bridge daemon cannot connect to MQTT
- If using VPN, verify WireGuard tunnel is up (
wg show) - If exposing MQTT publicly, confirm firewall rules allow port 1883
- Check Mosquitto logs:
docker-compose -f docker-compose.prod.yml logs mosquitto
Messages send but T-Deck never receives them
- Confirm the target
node_idmatches exactly (case-sensitive, includes!) - Check gateway logs for outbound publishes
- Check bridge daemon logs for MQTT subscription hits
BTCPay webhook not triggering subscriptions
- Verify
WEBHOOK_SECRETmatches BTCPay exactly - Test webhook manually with a simulated payload
- Check billing logs for signature verification errors
"Through openness, we preserve. Through preservation, we evolve. Through evolution, we return."