Skip to main content

Overview

The development configuration is optimized for local development with hot reload, volume mounts, and developer-friendly defaults. All services run in Docker containers with live code reloading enabled.

Services Included

The development environment includes five core services:

Redis

Self-hosted Redis instance for message streams

Backend

Bun server with tRPC API on port 8084

Frontend

Next.js client application on port 3000

Worker

Bun worker service for processing uptime checks

Publisher

Bun publisher service for publishing website checks to Redis streams

Development Features

All services use hot reload:
  • Backend, Worker, and Publisher use Bun’s --hot flag
  • Frontend uses Next.js dev mode
  • Code changes are reflected instantly without container restarts
Source code is mounted into containers:
  • Changes persist across container restarts
  • No need to rebuild containers for code changes
  • Separate node_modules volumes to prevent conflicts
Convenient defaults for local development:
  • Default Redis password: dev-password
  • Default JWT secret: dev-secret
  • Docker network: better-uptime-network-dev
  • Redis volume: redis-data-dev (separate from production)

Environment Setup

Development defaults use weak passwords. Never use these settings in production.
Create a .env file in your project root or packages/config/.env:
# Database
DATABASE_URL=postgresql://user:password@host:5432/database

# Auth (can use dev defaults)
JWT_SECRET=dev-secret-change-in-production

# GitHub OAuth
CLIENT_ID_GITHUB=your-github-client-id
CLIENT_SECRET_GITHUB=your-github-client-secret

# Email (Resend)
RESEND_API_KEY=your-resend-api-key

# Redis Configuration (dev defaults)
REDIS_HOST=redis  # Use 'redis' for Docker networking
REDIS_PORT=6379
REDIS_USERNAME=default
REDIS_PASSWORD=dev-password

# Backend
BACKEND_PORT=8084

# Frontend
FRONTEND_PORT=3000
NEXT_PUBLIC_BACKEND_URL=http://localhost:8084

# Worker Configuration
REGION_ID=us-east-1
WORKER_ID=worker-1

# ClickHouse (optional)
CLICKHOUSE_URL=
CLICKHOUSE_USERNAME=default
CLICKHOUSE_PASSWORD=
CLICKHOUSE_DATABASE=default
CLICKHOUSE_METRICS_TABLE=uptime_checks

Quick Start

1

Navigate to Docker directory

cd docker
2

Start development services

docker compose -f docker-compose.dev.yaml up --build
This will:
  • Build all service images
  • Start all containers
  • Show logs in your terminal
3

Access services

Once all services are running:

Development Commands

Starting Services

# Start all services (foreground)
docker compose -f docker-compose.dev.yaml up

# Start in background (detached mode)
docker compose -f docker-compose.dev.yaml up -d

# Rebuild and start
docker compose -f docker-compose.dev.yaml up --build

Viewing Logs

# View all service logs
docker compose -f docker-compose.dev.yaml logs -f

# View logs for specific service
docker compose -f docker-compose.dev.yaml logs -f backend
docker compose -f docker-compose.dev.yaml logs -f worker

Stopping Services

# Stop services
docker compose -f docker-compose.dev.yaml down

# Stop and remove volumes (deletes Redis data)
docker compose -f docker-compose.dev.yaml down -v

Working with Redis

# Connect to Redis CLI
docker compose -f docker-compose.dev.yaml exec redis redis-cli -a dev-password

# View Redis info
docker compose -f docker-compose.dev.yaml exec redis redis-cli -a dev-password info

Troubleshooting

If services can’t connect to Redis:
  1. Check Redis is healthy:
    docker compose -f docker-compose.dev.yaml ps
    
  2. Verify Redis password matches in .env
  3. Check network connectivity:
    docker compose -f docker-compose.dev.yaml exec backend ping redis
    
  4. View Redis logs:
    docker compose -f docker-compose.dev.yaml logs redis
    
If builds fail:
  1. Clear Docker cache:
    docker compose -f docker-compose.dev.yaml build --no-cache
    
  2. Check Dockerfile paths are correct
  3. Verify all package.json files exist
  4. Ensure pnpm-lock.yaml is up to date
If ports are already in use:
  1. Change ports in .env file:
    BACKEND_PORT=8085
    FRONTEND_PORT=3001
    
  2. Restart services:
    docker compose -f docker-compose.dev.yaml restart
    
  1. Verify volume mounts:
    docker compose -f docker-compose.dev.yaml config
    
  2. Check file permissions on mounted volumes
  3. Ensure source code is in the correct location
  4. Restart the service:
    docker compose -f docker-compose.dev.yaml restart backend
    

Switching to Production

To switch from development to production:
# Stop development services
docker compose -f docker-compose.dev.yaml down

# Start production services
docker compose -f docker-compose.prod.yaml up --build -d
Development and production use separate networks and volumes, so they won’t interfere with each other.

Next Steps

Production Deployment

Deploy Better Uptime to production

Environment Variables

Configure all environment variables

Database Setup

Set up and configure PostgreSQL

Build docs developers (and LLMs) love