Skip to main content

Overview

Better Uptime uses environment variables for configuration. Variables can be set in a .env file in the project root or packages/config/.env.
Never commit .env files to version control. Add .env to your .gitignore.

Required Variables

These variables must be set for Better Uptime to function:

Database

DATABASE_URL
string
required
PostgreSQL connection stringFormat: postgresql://user:password@host:5432/databaseExample: postgresql://postgres:mypassword@localhost:5432/better_uptime

Authentication

JWT_SECRET
string
required
Secret key for JWT token signingDevelopment: Can use dev-secretProduction: Must use cryptographically secure random stringGenerate: openssl rand -base64 32
Never use development defaults in production

GitHub OAuth

CLIENT_ID_GITHUB
string
required
GitHub OAuth application client IDCreate at: https://github.com/settings/developers
CLIENT_SECRET_GITHUB
string
required
GitHub OAuth application client secretAvailable after creating GitHub OAuth app

Email Service

RESEND_API_KEY
string
required
Resend API key for sending emailsGet your API key at: https://resend.com/api-keys

Redis Configuration

REDIS_HOST
string
required
Redis server hostname or IP addressDevelopment (Docker): redisProduction (Docker): redis or 127.0.0.1Production (PM2): 127.0.0.1
REDIS_PORT
number
default:"6379"
Redis server port
REDIS_USERNAME
string
default:"default"
Redis username (for Redis 6+ ACL)Development: defaultProduction: Set if using Redis ACL, otherwise leave empty
REDIS_PASSWORD
string
required
Redis password for authenticationDevelopment: dev-passwordProduction: Strong random password (required)Generate: openssl rand -base64 32
Production deployments must use a strong password

Service Configuration

Backend

BACKEND_PORT
number
default:"8084"
Port for the backend tRPC API server
NODE_ENV
string
default:"development"
Node environment modeValues: development, production

Frontend

FRONTEND_PORT
number
default:"3000"
Port for the Next.js frontend application
NEXT_PUBLIC_BACKEND_URL
string
required
Public URL for the backend APIDevelopment: http://localhost:8084Production: http://your-backend-url:8084
Must be prefixed with NEXT_PUBLIC_ to be accessible in the browser
WATCHPACK_POLLING
string
default:"false"
Enable polling for file changes (useful in Docker)Development: true (recommended for Docker)Production: Not needed
NEXT_PUBLIC_GITHUB_CLIENT_ID
string
GitHub OAuth client ID exposed to the browserAutomatically set from CLIENT_ID_GITHUB by Next.js build process
Usually not needed to set manually - Next.js copies from CLIENT_ID_GITHUB
NEXT_PUBLIC_API_URL
string
Override the tRPC API URLDefaults to NEXT_PUBLIC_BACKEND_URL if not setUse case: Custom API routing or proxy configuration
NEXT_PUBLIC_API_PROXY_TARGET
string
API proxy target for Next.js rewritesUsed in development to proxy API requestsExample: http://localhost:8084

Worker

REGION_ID
string
default:"us-east-1"
Geographic region identifier for the workerUsed for organizing workers by location
WORKER_ID
string
default:"worker-1"
Unique identifier for the worker instanceUse different IDs when scaling workers (e.g., worker-1, worker-2, worker-3)

Optional Variables

ClickHouse (Analytics)

ClickHouse is optional and used for storing uptime check metrics.
CLICKHOUSE_URL
string
ClickHouse server URLExample: https://clickhouse.example.com:8443Leave empty to disable ClickHouse integration
CLICKHOUSE_USERNAME
string
default:"default"
ClickHouse username
CLICKHOUSE_PASSWORD
string
ClickHouse password
CLICKHOUSE_DATABASE
string
default:"default"
ClickHouse database name
CLICKHOUSE_METRICS_TABLE
string
default:"uptime_checks"
Table name for storing uptime check metrics

Status Pages

STATUS_PAGE_CNAME_TARGET
string
CNAME target for custom status page domainsDevelopment: localhost (default)Production: status.raashed.xyz (default)Override to use your own domain for status pages
STATUS_PAGE_VERIFY_TXT_PREFIX
string
default:"_uptique-verify"
Prefix for TXT verification recordsUsed when verifying custom domain ownershipFormat: {prefix}.yourdomain.com

Environment Templates

Development Template

Create .env with these values for local development:
.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
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
WATCHPACK_POLLING=true

# 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

Production Template

Create .env with these values for production:
.env
# Database
DATABASE_URL=postgresql://user:password@host:5432/database

# Auth (REQUIRED - use strong secret)
JWT_SECRET=your-strong-jwt-secret-here

# 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 (REQUIRED - use strong password)
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_USERNAME=
REDIS_PASSWORD=your-strong-redis-password

# Backend
BACKEND_PORT=8084

# Frontend
FRONTEND_PORT=3000
NEXT_PUBLIC_BACKEND_URL=http://your-backend-url:8084

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

# ClickHouse (optional)
CLICKHOUSE_URL=https://clickhouse.example.com:8443
CLICKHOUSE_USERNAME=default
CLICKHOUSE_PASSWORD=your-clickhouse-password
CLICKHOUSE_DATABASE=default
CLICKHOUSE_METRICS_TABLE=uptime_checks

Security Best Practices

Use cryptographically secure random strings for all secrets:
# Generate JWT secret
openssl rand -base64 32

# Generate Redis password
openssl rand -base64 32
  • Add .env to .gitignore
  • Never commit secrets to version control
  • Use different .env files for each environment
  • Set restrictive file permissions: chmod 600 .env
  • Change JWT_SECRET periodically (will invalidate existing tokens)
  • Rotate Redis password with zero downtime using Redis ACL
  • Update OAuth secrets if compromised
For production deployments, consider using:
  • AWS Secrets Manager
  • HashiCorp Vault
  • Docker Secrets
  • Kubernetes Secrets

Environment Variable Loading

Better Uptime loads environment variables in this order:
  1. System environment variables (highest priority)
  2. .env file in project root
  3. packages/config/.env
  4. Default values (lowest priority)
Place your .env file in the project root for simplest configuration.

Docker-Specific Notes

Service Networking

When running in Docker:
# Backend connects to Redis using service name
REDIS_HOST=redis  # Not localhost or 127.0.0.1

# Frontend connects to backend using service name
NEXT_PUBLIC_BACKEND_URL=http://backend:8084

Host Access

For services running on the host to connect to Docker Redis:
REDIS_HOST=127.0.0.1  # or localhost
REDIS_PORT=6379       # Ensure port is exposed

Volume Mounts (Development)

Development configuration mounts source code:
  • Hot reload works automatically
  • Changes persist across container restarts
  • No need to set additional environment variables

Troubleshooting

  1. Check file location (project root or packages/config/)
  2. Verify file is named exactly .env (not env.txt or .env.local)
  3. Ensure no syntax errors (no spaces around =)
  4. Restart services after changing .env
  1. Verify REDIS_HOST is correct for your environment
  2. Check REDIS_PASSWORD matches Redis configuration
  3. Ensure Redis port is exposed (Docker)
  4. Test connection: redis-cli -h $REDIS_HOST -p $REDIS_PORT -a $REDIS_PASSWORD ping
  1. Check NEXT_PUBLIC_BACKEND_URL is set
  2. Verify URL is accessible from browser
  3. Ensure backend service is running
  4. Check for CORS issues in browser console
  1. Verify JWT_SECRET is set and consistent across services
  2. Changing JWT_SECRET invalidates all existing tokens
  3. Users will need to log in again after secret change

Next Steps

Development Setup

Set up local development environment

Production Deployment

Deploy to production

Database Setup

Configure PostgreSQL database

Build docs developers (and LLMs) love