Skip to main content

Quickstart guide

This guide will help you deploy Joystick IoT locally using Docker Compose. You’ll have a fully functional IoT platform running in minutes.

Prerequisites

Before you begin, ensure you have the following installed:
  • Docker: Version 20.10 or later
  • Docker Compose: Version 2.0 or later
  • Linux/amd64 platform: Or Docker Desktop with amd64 emulation enabled
All Joystick services run on linux/amd64. If you’re using an ARM-based Mac (M1/M2/M3), Docker Desktop will automatically handle platform emulation.

Installation

1

Clone the repository

Clone the Joystick repository to your local machine:
git clone https://github.com/skylineagle/joystick.git
cd joystick
2

Review the Docker Compose configuration

The docker-compose.yml file orchestrates all services. Key services include:
  • Traefik (port 80): Reverse proxy and load balancer
  • PocketBase (port 8090): Database and authentication
  • MediaMTX (network_mode: host): Video streaming server
  • App: Web interface (via Traefik at /)
  • Joystick: Device control API (via Traefik at /joystick)
  • Panel, Baker, Studio, Switcher, Whisper: Supporting microservices
MediaMTX uses network_mode: host for optimal streaming performance. It will use ports 8554 (RTSP), 8888 (HLS), and 9997 (API).
3

Start the platform

Launch all services with Docker Compose:
docker-compose up -d
This will pull the latest images from GitHub Container Registry and start all services in detached mode.
First-time startup may take a few minutes to download all container images.
4

Verify services are running

Check that all services are healthy:
docker-compose ps
You should see all services in the running state. PocketBase includes a health check that must pass before dependent services start.
5

Access the web interface

Open your browser and navigate to:
http://localhost
You’ll see the Joystick web interface.

First login

After deployment, you’ll need to create an admin account and authenticate.
1

Access PocketBase admin

Navigate to the PocketBase admin interface:
http://localhost:8090/_/
Create an admin account when prompted.
2

Create a user account

In the PocketBase admin interface:
  1. Navigate to Collections > users
  2. Click New record
  3. Fill in the user details (email and password)
  4. Save the record
3

Configure permissions

Set up user permissions in the permissions collection:
  1. Navigate to Collections > permissions
  2. Create permission records for your user
  3. Grant access to features like device-control, device-gps, device-battery, etc.
See the Authentication guide for detailed information about the permission system.
4

Log in to Joystick

Return to http://localhost and log in with your user credentials.

Test the API

Verify that the Joystick API is working correctly.

Health check

Test the public health endpoint (no authentication required):
curl http://localhost/joystick/api/health
You should receive a successful response.

Authenticated request

Get a JWT token from PocketBase:
curl -X POST http://localhost:8090/api/collections/users/auth-with-password \
  -H "Content-Type: application/json" \
  -d '{
    "identity": "user@example.com",
    "password": "yourpassword"
  }'
Use the token to make authenticated API calls:
curl http://localhost/joystick/api/device-list \
  -H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"

Using the development API key

For testing, you can use the development API key:
curl http://localhost/joystick/api/device-list \
  -H "X-API-Key: dev-api-key-12345"
The development API key (dev-api-key-12345) is for testing only. Change it in production by setting the JOYSTICK_API_KEY environment variable.

Configure your first device

1

Add a device

In the Joystick web interface:
  1. Navigate to Devices
  2. Click Add Device
  3. Enter device details (name, host, phone number)
  4. Configure available actions
  5. Save the device
2

Set up device permissions

Grant yourself access to the device:
  1. Edit the device in PocketBase admin
  2. Add your user ID to the allow field (array of user IDs)
  3. Save the changes
3

Execute an action

Test device control by executing an action:
curl -X POST http://localhost/joystick/api/run/DEVICE_ID/ACTION_ID \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"param": "value"}'

Enable automatic slot switching

For devices with dual connection slots, enable automatic failover:
1

Configure secondary slot

In the device settings:
  1. Enable Configure Secondary Connection Slot
  2. Enter secondary slot host and phone number
  3. Save the configuration
2

Enable auto-switching

Check the Enable automatic slot switching option. The Switcher service will now:
  • Run health checks every 30 seconds (default)
  • Automatically failover to the secondary slot after 2 consecutive failures
  • Switch back when the primary slot recovers
3

Monitor slot health

Check slot health status:
curl http://localhost/switcher/api/health/DEVICE_ID
The response shows active slot, health status, and failure counts.

View logs

Monitor service logs using Docker Compose:
# All services
docker-compose logs -f

# Specific service
docker-compose logs -f joystick

# Or use Dozzle (web-based log viewer)
open http://localhost:8084
Dozzle provides a web interface for viewing container logs in real-time at http://localhost:8084.

Environment variables

Customize your deployment by setting environment variables:
# Set custom hostname
export HOST=joystick.local
docker-compose up -d

# Set custom API key
export JOYSTICK_API_KEY=your-secure-api-key
docker-compose up -d
Key environment variables:
VariableDefaultDescription
HOSTlocalhostHostname for Traefik routing
JOYSTICK_API_KEYdev-api-key-12345API key for service authentication
SLOT_HEALTH_CHECK_INTERVAL30Health check interval in seconds

Next steps

Architecture overview

Learn how the microservices work together

Authentication

Understand JWT tokens and permissions

Device control

Master device actions and sensor monitoring

Slot switching

Configure automatic failover systems

Troubleshooting

Services not starting

  • Verify Docker and Docker Compose are installed correctly
  • Check for port conflicts (especially 80, 8090, and host-mode ports)
  • Review logs: docker-compose logs

Cannot access web interface

  • Ensure Traefik is running: docker-compose ps traefik
  • Check Traefik dashboard: http://localhost:8080
  • Verify HOST environment variable matches your access URL

PocketBase health check failing

  • Wait a few moments for PocketBase to initialize
  • Check PocketBase logs: docker-compose logs pocketbase
  • Verify the pb_data volume is writable

Authentication errors

  • Ensure you’ve created a user in PocketBase
  • Verify JWT token is not expired
  • Check user permissions in the permissions collection
If you continue experiencing issues, check the GitHub Issues or consult the detailed service logs.

Build docs developers (and LLMs) love