SkyTalk Docs

Getting Started

How to run the full SkyTalk stack locally — server, database, mobile app, and admin portal.

This page covers running the stack on your local machine for development and testing.

Prerequisites

ToolVersionNotes
Node.js20+LTS
Docker24+Real Docker via get.docker.com — not snap
pnpm10.23.0Managed via Corepack
Android StudioLatestFor mobile emulator testing

Setup

Clone and Bootstrap

git clone <repo-url>
cd TheForbiddenLAN
pnpm setup:local

pnpm setup:local enables Corepack, pins pnpm to 10.23.0, installs all workspace dependencies, and runs Android environment checks.

Start the Server

Create packages/server/.env:

POSTGRES_USER=skytalk
POSTGRES_PASSWORD=skytalkpass
POSTGRES_DB=skytalk
JWT_SECRET=dev-jwt-secret-change-in-prod
DATABASE_URL=postgresql://skytalk:skytalkpass@localhost:5432/skytalk

Then start Docker Compose:

cd packages/server
docker compose up -d

Docker Compose starts Postgres 16 and the Node.js server. On first start, the server runs prisma db push to create all tables, then listens on port 3000.

Verify it's up:

curl http://localhost:3000/ping
# → {"pong":true}

Seed Development Data

docker compose exec server npx tsx prisma/seed.ts

Creates:

  • admin / admin — role: admin
  • pilot1 / test — role: user
  • Talkgroup: Ground Ops (both users as members)

Mobile App

The app connects to the relay server on startup. Make sure the server is running (or use the hosted instance at 134.122.32.45:3000).

cd packages/mobile
pnpm dev:mobile      # browser mode — fastest iteration
# or
pnpm android         # Android emulator

Configure the server URL in packages/mobile/.env:

EXPO_PUBLIC_API_URL=http://134.122.32.45:3000
EXPO_PUBLIC_WS_URL=ws://134.122.32.45:3000/ws
EXPO_PUBLIC_DLS140_URL=http://192.168.111.1:3000
EXPO_PUBLIC_LOOPBACK=false

Admin Portal

cd packages/portal
pnpm dev

Opens at http://localhost:5173. Requires an admin JWT in localStorage. Get one:

curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}'

Then in the browser console:

localStorage.setItem('jwt', '<paste-jwt-here>')

Environment Variables Reference

See Environment & Config → for the full table of all variables across all packages.


Current Feature Status

FeatureStatus
PTT audio record + relay + playback✓ Working (Opus 16kHz CBR, two-device tested)
AES-GCM-256 encryption✓ Working (hardcoded test key)
Floor control (walk-on prevention)✓ Server-authoritative
Talkgroup membership✓ From server REST API
GPS signalDLS-140 integration exists, untested on hardware
Presence✓ From server WebSocket
Loopback testing✓ Single-device (EXPO_PUBLIC_LOOPBACK=true)

The crypto polyfill is a pass-through shim. Audio is sent with AES-GCM but the key is hardcoded. Production requires proper KDF and key rotation.

On this page