Supercheck LogoSupercheck

Single-Location

Docker Compose deployment on a single serverEdit

Deploy Supercheck on a single server with Docker Compose.

Architecture

Loading diagram...

All services run on a single Linux server managed by Docker Compose. Workers consume jobs from Redis via BullMQ and execute each test as an ephemeral Kubernetes Job in a local K3s cluster, sandboxed with gVisor for kernel-level isolation. Scale by increasing WORKER_REPLICAS or expanding to multiple regions.


Docker Compose

Install Docker

A Linux server is required (Ubuntu 22.04+, Debian 12+). Supercheck uses K3s and gVisor for sandboxed test execution, which require the Linux kernel. macOS, Windows, and WSL2 are not supported.

# Review Docker's official installation script before running it.
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker

For production hosts, you can instead follow Docker's distribution-specific Engine installation instructions to install from its package repository. Verify that docker compose version reports Compose v2 before continuing.

Clone and Configure

git clone https://github.com/supercheck-io/supercheck.git
cd supercheck/deploy/docker
./init-secrets.sh

Edit .env for optional integrations (SMTP, AI, OAuth). If you will open this HTTP deployment from another computer, also set the externally reachable origin (with no trailing slash):

NEXT_PUBLIC_APP_URL=http://YOUR_SERVER_IP:3000

Set Up Execution Sandbox

sudo bash setup-k3s.sh

This installs K3s with gVisor for sandboxed Playwright and K6 execution.

Deploy

KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig docker compose up -d

Access

Open the URL configured in NEXT_PUBLIC_APP_URL and create your account. If you are working directly on the server and left the default unchanged, use http://localhost:3000.

# Optional: grant super admin
docker compose exec app node scripts/bootstrap-admin.js your-email@example.com

Install Docker

A Linux server is required (Ubuntu 22.04+, Debian 12+). Supercheck uses K3s and gVisor for sandboxed test execution, which require the Linux kernel. macOS, Windows, and WSL2 are not supported.

# Review Docker's official installation script before running it.
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker

For production hosts, you can instead follow Docker's distribution-specific Engine installation instructions to install from its package repository. Verify that docker compose version reports Compose v2 before continuing.

Configure DNS

TypeNameValue
AappYour Server IP
A*Your Server IP

The wildcard (*) record enables default status page URLs like abc123.example.com.

The same wildcard usually also covers the derived custom-domain target (for example, cname.example.com). If the target shown in Settings is outside that wildcard or on another zone, add an A/AAAA record for that target as well.

Customer-facing custom domains should stay outside the STATUS_PAGE_DOMAIN namespace. For example, you might reserve example.com for default UUID URLs and serve a status page at status.example.net by pointing its CNAME to cname.example.com.

Cloudflare Users: Set SSL/TLS mode to "Full" or "Full (Strict)".

Keep inbound TCP ports 80 and 443 open. Traefik uses port 80 for the ACME HTTP challenge and redirects HTTP traffic to HTTPS.

Clone and Configure

git clone https://github.com/supercheck-io/supercheck.git
cd supercheck/deploy/docker
./init-secrets.sh

Edit .env:

APP_DOMAIN=app.example.com
ACME_EMAIL=admin@example.com
STATUS_PAGE_DOMAIN=example.com

STATUS_PAGE_DOMAIN reserves the default status page namespace ([uuid].STATUS_PAGE_DOMAIN). In the HTTPS Compose examples, Supercheck derives the custom-domain target from it automatically, usually as cname.STATUS_PAGE_DOMAIN.

Set STATUS_PAGE_DOMAIN to a publicly reachable hostname. Keep customer-facing custom domains outside that reserved namespace, and keep those hostnames as CNAME records only. The target shown in Settings must already point to your app, usually via the wildcard * record above or a dedicated A/AAAA record for that target.

Local development still stays on http://localhost:3000/status/[subdomain]. STATUS_PAGE_DOMAIN is only used for public/default status-page hostnames once you access the app through that public hostname.

Set Up Execution Sandbox

sudo bash setup-k3s.sh

This installs K3s with gVisor for sandboxed Playwright and K6 execution.

Deploy

KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig docker compose -f docker-compose-secure.yml up -d

Access

Open https://app.example.com and create your account.

# Optional: grant super admin
docker compose -f docker-compose-secure.yml exec app node scripts/bootstrap-admin.js your-email@example.com

Use docker-compose-external.yml when you want to connect Supercheck to managed external services (Neon, Supabase, Upstash, Cloudflare R2) instead of running PostgreSQL, Redis, and MinIO in Docker.

Configure External Services

Generate a secure .env, then replace its database, Redis, storage, and public URL values with your managed-service settings:

./init-secrets.sh

# Managed PostgreSQL (Neon, Supabase, RDS)
DATABASE_URL=postgresql://user:password@host:5432/supercheck
DB_HOST=host
DB_PORT=5432
DB_USER=user
DB_PASSWORD=password
DB_NAME=supercheck

# Managed Redis (Upstash, Redis Cloud)
REDIS_URL=redis://user:password@host:6379
REDIS_HOST=host
REDIS_PORT=6379
REDIS_PASSWORD=password
REDIS_TLS_ENABLED=true

# Managed S3-compatible storage (Cloudflare R2, AWS S3)
S3_ENDPOINT=https://your-account.r2.cloudflarestorage.com
AWS_REGION=auto
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key

# Public HTTPS configuration
APP_DOMAIN=app.example.com
APP_URL=https://app.example.com
NEXT_PUBLIC_APP_URL=https://app.example.com
BETTER_AUTH_URL=https://app.example.com
STATUS_PAGE_DOMAIN=example.com
ACME_EMAIL=admin@example.com

Keep the generated BETTER_AUTH_SECRET and SECRET_ENCRYPTION_KEY. For Redis providers that do not use TLS, set REDIS_TLS_ENABLED=false.

Set Up Execution Sandbox

sudo bash setup-k3s.sh

This installs K3s with gVisor for sandboxed test execution.

Start Services

# Create .env with your managed service credentials
# Use the template below or start from the compose file's documented variables
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig docker compose -f docker-compose-external.yml up -d

This compose file skips the bundled PostgreSQL, Redis, and MinIO containers. It starts the App, Worker, and Traefik containers; the Worker submits sandboxed jobs to the host K3s cluster.


Optional Configuration


Operations

Scaling

WORKER_LOCATION=local (default) processes all queues on a single server. The UI auto-hides location selectors when only one location exists. Expand later via Multi-Location Workers.

# Quick Start (HTTP):
WORKER_REPLICAS=2 RUNNING_CAPACITY=2 QUEUED_CAPACITY=20 \
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig \
docker compose up -d

# Production (HTTPS):
WORKER_REPLICAS=2 RUNNING_CAPACITY=2 QUEUED_CAPACITY=20 \
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig \
docker compose -f docker-compose-secure.yml up -d
SizeWorkersCapacityServer
Small112 vCPU / 4GB
Medium224 vCPU / 8GB
Large448 vCPU / 16GB

RUNNING_CAPACITY and QUEUED_CAPACITY are enforced by the App. Set them in .env; workers may receive the shared values but do not use them. WORKER_REPLICAS controls the number of worker containers. Keep RUNNING_CAPACITY equal to the total number of worker replicas.

Backups

docker compose exec postgres sh -c 'pg_dump -U "$DB_USER" "$DB_NAME"' > backup.sql        # Create
docker compose exec -T postgres sh -c 'psql -U "$DB_USER" "$DB_NAME"' < backup.sql        # Restore

Updates

Images are pinned to a specific release through SUPERCHECK_VERSION, which defaults to the release bundled with this Compose file. Set it in .env to upgrade, and keep the App and Worker on the same value so the execution sandbox cannot drift from the control plane.

# In .env: set the target release (see GitHub Releases for available tags)
SUPERCHECK_VERSION=1.3.6

Then pull and restart:

# Quick Start (HTTP):
docker compose pull && \
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig \
docker compose up -d

# Production (HTTPS):
docker compose -f docker-compose-secure.yml pull && \
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig \
docker compose -f docker-compose-secure.yml up -d

Upgrading from pre-1.3.3 releases — Supercheck moved from Docker socket-based test execution to a sandboxed K3s + gVisor model in 1.3.3. Before upgrading an older deployment, you must run the setup script:

# 1. Back up your database first
docker compose exec postgres sh -c 'pg_dump -U "$DB_USER" "$DB_NAME"' > backup-pre-k3s-migration.sql

# 2. Install K3s + gVisor execution sandbox
sudo bash setup-k3s.sh

# 3. Pull new images and restart with kubeconfig
# Quick Start (HTTP):
docker compose pull && \
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig \
docker compose up -d

# Production (HTTPS):
docker compose -f docker-compose-secure.yml pull && \
KUBECONFIG_FILE=/etc/rancher/k3s/supercheck-worker.kubeconfig \
docker compose -f docker-compose-secure.yml up -d

The worker container no longer requires the Docker socket. Existing tests and monitors continue to work without modification. If you have remote workers (Multi-Location), run setup-k3s.sh on each remote server as well.


Next Steps

On this page