Files
kosmo-connect/DEPLOY.md
Tomas Kracmar 0a4fb7b55e
Some checks failed
CI / lint-docs (push) Has been cancelled
CI / build-firmware (push) Has been cancelled
CI / test-backend (push) Has been cancelled
CI / test-web (push) Has been cancelled
feat: initial KosmoConnect platform v0.1
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
2026-04-12 17:30:15 +02:00

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 password
  • BTCPAY_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

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:1883 internally

Option B: Public MQTT with Authentication

  • Change the Mosquitto port binding in docker-compose.prod.yml to 0.0.0.0:1883
  • Enable TLS on Mosquitto and require username/password
  • Update mosquitto.conf with 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

  1. Log in to https://pay.cqre.net
  2. Go to your store → WebhooksCreate Webhook
  3. Payload URL:
    https://kosmo.example.com/api/v1/billing/webhooks/btcpay
    
  4. Select events:
    • Invoice created
    • Invoice settled
    • Invoice expired
    • Invoice invalid
  5. Save and copy the Webhook Secret
  6. Paste it into your cloud server's .env as WEBHOOK_SECRET
  7. 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.py or 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_id matches 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_SECRET matches 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."