Skip to content

Running Checkstack with Docker

This guide walks you through deploying Checkstack using Docker.

  • Docker installed and running
  • PostgreSQL database (or use a managed service like Supabase, Neon, etc.)

Checkstack requires four environment variables to run:

VariableDescriptionRequirements
DATABASE_URLPostgreSQL connection stringValid Postgres URI
ENCRYPTION_MASTER_KEYEncrypts secrets in the database64 hex characters (32 bytes)
BETTER_AUTH_SECRETSigns session cookies and OAuth statesMinimum 32 characters
BASE_URLExact URL used to access Checkstack in the browsere.g. http://192.168.1.123:3000 or https://status.example.com

Generate a secure 32-byte key:

Terminal window
# Using Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Using OpenSSL
openssl rand -hex 32

This produces a 64-character hexadecimal string (e.g., a1b2c3d4e5f6...).

Generate a secure random string (minimum 32 characters):

Terminal window
# Using Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
# Using OpenSSL
openssl rand -base64 32
Terminal window
# Pull the latest image
docker pull ghcr.io/enyineer/checkstack:latest
# Run with required environment variables
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:latest

The Checkstack repository includes a ready-to-use docker-compose.yml in the project root that runs both Checkstack and PostgreSQL:

Terminal window
# Clone the repository (or download just the docker-compose.yml)
git clone https://github.com/enyineer/checkstack.git
cd checkstack
# Create your .env file with required secrets
cat > .env << EOF
POSTGRES_USER=checkstack
POSTGRES_PASSWORD=checkstack
POSTGRES_DB=checkstack
ENCRYPTION_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 everything
docker compose up -d

To update to a newer version:

Terminal window
# Pull the latest image
docker compose pull
# Recreate containers with the new image
docker compose up -d

If you already have a PostgreSQL database, you can run Checkstack as a single container:

Terminal window
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:latest
VariableDefaultDescription
LOG_LEVELinfoLogging 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.

Verify Checkstack is running:

Terminal window
curl http://localhost:3000/api/health

”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):

Terminal window
# Example (Docker on LAN):
BASE_URL=http://192.168.1.123:3000
# Example (Production):
BASE_URL=https://status.example.com

You can verify the value your container is using by checking the config endpoint:

Terminal window
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:

Terminal window
docker compose up -d --force-recreate
  • Verify your DATABASE_URL is correct and the database is reachable
  • Ensure PostgreSQL is running and accepting connections
  • Check firewall rules allow connections between containers