Running Checkstack with Docker
This guide walks you through deploying Checkstack using Docker.
Prerequisites
Section titled “Prerequisites”- Docker installed and running
- PostgreSQL database (or use a managed service like Supabase, Neon, etc.)
Required Environment Variables
Section titled “Required Environment Variables”Checkstack requires four environment variables to run:
| Variable | Description | Requirements |
|---|---|---|
DATABASE_URL | PostgreSQL connection string | Valid Postgres URI |
ENCRYPTION_MASTER_KEY | Encrypts secrets in the database | 64 hex characters (32 bytes) |
BETTER_AUTH_SECRET | Signs session cookies and OAuth states | Minimum 32 characters |
BASE_URL | Exact URL used to access Checkstack in the browser | e.g. http://192.168.1.123:3000 or https://status.example.com |
Generating Secrets
Section titled “Generating Secrets”ENCRYPTION_MASTER_KEY
Section titled “ENCRYPTION_MASTER_KEY”Generate a secure 32-byte key:
# Using Node.jsnode -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Using OpenSSLopenssl rand -hex 32This produces a 64-character hexadecimal string (e.g., a1b2c3d4e5f6...).
BETTER_AUTH_SECRET
Section titled “BETTER_AUTH_SECRET”Generate a secure random string (minimum 32 characters):
# Using Node.jsnode -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
# Using OpenSSLopenssl rand -base64 32Quick Start
Section titled “Quick Start”# Pull the latest imagedocker pull ghcr.io/enyineer/checkstack:latest
# Run with required environment variablesdocker run -d \ --name checkstack \ -e DATABASE_URL="postgresql://user:password@host:5432/checkstack" \ -e ENCRYPTION_MASTER_KEY="<your-64-char-hex-key>" \ -e BETTER_AUTH_SECRET="<your-32-char-secret>" \ -e BASE_URL="http://192.168.1.123:3000" \ -p 3000:3000 \ ghcr.io/enyineer/checkstack:latestDocker Compose (Recommended)
Section titled “Docker Compose (Recommended)”The Checkstack repository includes a ready-to-use docker-compose.yml in the project root that runs both Checkstack and PostgreSQL:
# Clone the repository (or download just the docker-compose.yml)git clone https://github.com/enyineer/checkstack.gitcd checkstack
# Create your .env file with required secretscat > .env << EOFPOSTGRES_USER=checkstackPOSTGRES_PASSWORD=checkstackPOSTGRES_DB=checkstackENCRYPTION_MASTER_KEY=$(openssl rand -hex 32)BETTER_AUTH_SECRET=$(openssl rand -base64 32)BASE_URL="http://192.168.1.123:3000" # Must match exactly how you access Checkstack!EOF
# Start everythingdocker compose up -dUpdating the Checkstack Image
Section titled “Updating the Checkstack Image”To update to a newer version:
# Pull the latest imagedocker compose pull
# Recreate containers with the new imagedocker compose up -dQuick Start (Single Container)
Section titled “Quick Start (Single Container)”If you already have a PostgreSQL database, you can run Checkstack as a single container:
docker run -d \ --name checkstack \ -e DATABASE_URL="postgresql://user:password@host:5432/checkstack" \ -e ENCRYPTION_MASTER_KEY="<your-64-char-hex-key>" \ -e BETTER_AUTH_SECRET="<your-32-char-secret>" \ -e BASE_URL="http://192.168.1.123:3000" \ -p 3000:3000 \ ghcr.io/enyineer/checkstack:latestOptional Environment Variables
Section titled “Optional Environment Variables”| Variable | Default | Description |
|---|---|---|
LOG_LEVEL | info | Logging level (debug, info, warn, error) |
INTERNAL_URL | (falls back to BASE_URL) | Internal RPC URL for backend-to-backend calls. Set to K8s service name (e.g., http://checkstack-service:3000) for multi-pod load balancing. |
Onboarding flow
Section titled “Onboarding flow”Health Check
Section titled “Health Check”Verify Checkstack is running:
curl http://localhost:3000/api/healthTroubleshooting
Section titled “Troubleshooting””ENCRYPTION_MASTER_KEY must be 32 bytes (64 hex characters)”
Section titled “”ENCRYPTION_MASTER_KEY must be 32 bytes (64 hex characters)””Your encryption key is not the correct length. Generate a new one using the commands above.
”BETTER_AUTH_SECRET must be at least 32 characters”
Section titled “”BETTER_AUTH_SECRET must be at least 32 characters””Your auth secret is too short. Generate a longer one using the commands above.
Onboarding screen does not appear / app loads empty or very slowly
Section titled “Onboarding screen does not appear / app loads empty or very slowly”This is almost always caused by a wrong BASE_URL. When BASE_URL points to an incorrect or unreachable address, the frontend cannot reach the backend for session and onboarding checks, which causes it to silently show empty state.
Make sure BASE_URL matches the EXACT URL YOU put into the browser address bar (including possible LAN IPs or the domain):
# Example (Docker on LAN):BASE_URL=http://192.168.1.123:3000
# Example (Production):BASE_URL=https://status.example.comYou can verify the value your container is using by checking the config endpoint:
curl http://localhost:3000/api/config# Expected: {"baseUrl":"http://localhost:3000"}If baseUrl in the response points to port 5173 or any other wrong address, update BASE_URL in your .env file and recreate the container:
docker compose up -d --force-recreateDatabase connection errors
Section titled “Database connection errors”- Verify your
DATABASE_URLis correct and the database is reachable - Ensure PostgreSQL is running and accepting connections
- Check firewall rules allow connections between containers