blockinator.
GitHub ↗

Get started

Install the Docker Hub container

Run the prebuilt Blockinator image with Compose and Caddy or standalone Docker.

Choose a container deployment

The published image is stealthcat128/blockinator. These examples use 1.20.1, the published Linux AMD64/ARM64 image documented upstream. The corresponding Git configuration is v1.20.1; a newer source version does not imply a matching Docker image exists.

Compose + Caddy supports the managed HTTPS and certificate controls. Standalone Docker serves HTTP without the Caddy sidecar. Choose one method; both examples use host port 8080 and should not be started unchanged on the same host.

Option A: Compose with Caddy

Have Docker Engine, Compose v2, Git, Bash, and OpenSSL ready. Get the configuration matching the image. The detached Git checkout is expected:

bash
git clone --branch v1.20.1 --single-branch https://github.com/StealthCat/blockinator-web.git
cd blockinator-web

For a fresh deployment, create private first-run credentials in this directory. The block refuses to overwrite an existing .env:

bash
(
  set -eu
  umask 077
  set -o noclobber
  admin_password=$(openssl rand -hex 24)
  policy_api_key=$(openssl rand -hex 32)
  cat > .env <<EOF
ADMIN_USERNAME=admin
ADMIN_PASSWORD=$admin_password
POLICY_API_KEY=$policy_api_key
DATABASE_BACKEND=sqlite
TZ=UTC
POLICY_PORT=8080
HTTPS_PORT=8443
EOF
)

Keep the generated values private and retrieve them locally from .env. Set an IANA TZ before first startup. Existing database credentials are managed through Access & Security.

Select the prebuilt image with this override:

bash
cat > docker-compose.hub.yml <<'EOF'
services:
  blockinator:
    image: stealthcat128/blockinator:1.20.1
EOF
bash
docker compose -f docker-compose.yml -f docker-compose.hub.yml pull
docker compose -f docker-compose.yml -f docker-compose.hub.yml up -d --no-build

Open http://DOCKER-HOST:8080/ and sign in as admin with the generated password. Configure managed HTTPS under System Settings → HTTPS & TLS; the default HTTPS port is 8443. Preserve .env and the complete ./data directory.

bash
docker compose -f docker-compose.yml -f docker-compose.hub.yml ps
docker compose -f docker-compose.yml -f docker-compose.hub.yml logs --tail=100 blockinator caddy

Option B: standalone Docker

For a separate minimal installation, create a working directory. You do not need a Git checkout:

bash
mkdir -p ~/blockinator
cd ~/blockinator

In that directory, run the same first-run credential block shown in Option A. Do not continue without .env. Pull and start the application with a persistent named volume:

bash
docker pull stealthcat128/blockinator:1.20.1
docker run -d \
  --name blockinator \
  --restart unless-stopped \
  --env-file ./.env \
  -e FORWARDED_ALLOW_IPS=127.0.0.1 \
  -p 8080:8080 \
  -v blockinator-data:/data \
  stealthcat128/blockinator:1.20.1

Open http://DOCKER-HOST:8080/ and sign in with your generated credentials. blockinator-data preserves SQLite data when the container is replaced. Change the left-hand port in -p for a different host port; POLICY_PORT and HTTPS_PORT in .env do not change this standalone command.

bash
docker logs --tail=100 blockinator
docker inspect --format '{{.State.Health.Status}}' blockinator

Connect and verify

Create a list, test it in Policy Tester, and follow the Technitium, CoreDNS, or PowerDNS Recursor walkthrough. Use the host address reachable from the resolver for /api/v1/decision.

A fresh database requires a unique administrator password of at least 12 characters and an API key of at least 24 characters. A bare docker run without the environment file will not initialize it.

Update without losing data

Back up first. For Compose, stop the stack with both Compose files, back up .env and ./data, select a published image and matching Git configuration tag, then pull and start with both files and --no-build. Preserve local edits when changing tags.

For standalone Docker, stop the container and back up the named volume before replacing the container with the desired image. Reuse blockinator-data; never delete the volume to upgrade. MySQL deployments also require a separate remote database backup. Pulling an image alone does not update a running container.

Read the backup guide →

Read the upstream documentation ↗

Find your next step