Skip to content

Technitium DNS Companion - Getting Started Guide

Getting started is quick and easy with Docker (or an equivalent container runtime). Just a few environment variables are needed to connect to your Technitium DNS nodes.

Getting Started (2-minute path)

You don't need to clone the repo. Download the script and run it from the host where you want to run the container:

  • macOS/Linux:
curl -fsSL https://raw.githubusercontent.com/Fail-Safe/Technitium-DNS-Companion/main/scripts/docker-quickstart.sh -o docker-quickstart.sh
chmod +x docker-quickstart.sh
./docker-quickstart.sh
  • Windows PowerShell:
iwr https://raw.githubusercontent.com/Fail-Safe/Technitium-DNS-Companion/main/scripts/docker-quickstart.ps1 -OutFile docker-quickstart.ps1
powershell -ExecutionPolicy Bypass -File .\docker-quickstart.ps1
  • What the script does:
  • Verifies Docker is running
  • Downloads .env.example into technitium.env if missing
  • Pulls the selected image first (so :latest stays current)
  • Shows the exact docker run command and can run it for you
  • Prompts to confirm HTTP/HTTPS ports before running (must be different; it will re-prompt if you choose the same port)

  • If technitium.env didn’t exist, the script will create it and exit so you can edit it.

  • After editing technitium.env, rerun the script and press Enter to launch (any other key cancels).

Option B: Manual docker run (no clone required)

Runs the single container that serves both the API and built frontend. Use this if you prefer to type the command yourself.

  1. Prepare environment:

  2. Download .env.example (or copy it from a clone) and save as technitium.env.

  3. Minimum variables:
  4. TECHNITIUM_NODES=node1,node2
  5. TECHNITIUM_<NODE>_BASE_URL for each node.
  6. Recommended (and required starting in v1.4): AUTH_SESSION_ENABLED=true (Technitium login/RBAC for UI access).
  7. Recommended for background features in session-auth mode: TECHNITIUM_BACKGROUND_TOKEN (least-privilege, read-only).
  8. Legacy only (Technitium DNS < v14 / migration): env-token mode using TECHNITIUM_<NODE>_TOKEN.
  9. TECHNITIUM_CLUSTER_TOKEN is deprecated as of v1.3.0 (legacy / migration source) and will be removed in v1.4.
  10. Optional: set TZ, CORS_ORIGINS, and HTTPS variables.

  11. Run the container:

docker run --rm -p 3000:3000 -p 3443:3443 \
  --env-file technitium.env \
  -v technitium-dns-companion-data:/data \
  ghcr.io/fail-safe/technitium-dns-companion:latest

Notes on persistence (/data volume):

  • -v technitium-dns-companion-data:/data is recommended. It is used for caches and optional on-disk features.
  • If you enable the optional SQLite rolling query-log store, set QUERY_LOG_SQLITE_PATH to a path under /data so stored logs survive container restarts.
  • DNS Filtering History snapshots can also be stored under /data (see .env.example / DNS_FILTERING_SNAPSHOT_DIR).

Optional: Enable SQLite rolling query logs storage (accuracy for “Last 24h” presets)

  • In technitium.env:
QUERY_LOG_SQLITE_ENABLED=true
QUERY_LOG_SQLITE_PATH=/data/query-logs.sqlite
QUERY_LOG_SQLITE_RETENTION_HOURS=24
QUERY_LOG_SQLITE_POLL_INTERVAL_MS=10000
QUERY_LOG_SQLITE_OVERLAP_SECONDS=60
QUERY_LOG_SQLITE_MAX_ENTRIES_PER_POLL=20000
  • If you are using session auth (AUTH_SESSION_ENABLED=true), ingestion runs as a background task and requires TECHNITIUM_BACKGROUND_TOKEN (least-privilege token that can read query logs). Without it, the DB may exist but will not stay up to date.

  • HTTP: http://localhost:3000

  • HTTPS (if enabled): https://localhost:3443

  • Enable HTTPS (optional but recommended):

  • Place certs locally:

certs/
├── fullchain.pem
└── privkey.pem
  • In technitium.env, set:
HTTPS_ENABLED=true
HTTPS_PORT=3443
HTTPS_CERT_PATH=/app/certs/fullchain.pem
HTTPS_KEY_PATH=/app/certs/privkey.pem
# HTTPS_CA_PATH=/app/certs/chain.pem  # (optional) Specify if you have a separate CA file
  • Mount certs when running:
docker run --rm -p 3000:3000 -p 3443:3443 \
  --env-file technitium.env \
  -v technitium-dns-companion-data:/data \
  -v $(pwd)/certs:/app/certs:ro \
  ghcr.io/fail-safe/technitium-dns-companion:latest
  • For Windows PowerShell, use ${PWD}\certs for the host path.

  • Operations:

  • Logs: docker logs -f <container-id> (if run without --rm, add --name tdc then docker logs -f tdc)

  • Restart (named container): docker restart tdc
  • Upgrade image: docker pull ghcr.io/fail-safe/technitium-dns-companion:latest

Option C: docker compose (from a repo clone)

Use this if you’ve cloned the repo and prefer compose for repeatability or dev overrides.

  1. Copy .env.example to .env and set your variables.

  2. Start:

docker compose up -d --build
  1. HTTPS: place certs in certs/ and set the HTTPS vars in .env, then ensure the certs volume is mounted in docker-compose.yml.

  2. Operations:

  3. Logs: docker compose logs -f

  4. Restart: docker compose restart
  5. Upgrade: git pull && docker compose up -d --build

Troubleshooting

  • Container will not start: docker compose logs then docker compose config to validate env vars.
  • Port bind error ("port is already allocated"): pick different host ports (e.g., -p 1234:3000 -p 1235:3443) or stop the other container/service using that port.
  • Cannot connect to Technitium DNS nodes: Check URLs and tokens in .env.

Docker Secrets / File-based Secrets

For production deployments, you can use Docker secrets or file-based secrets instead of passing sensitive values directly as environment variables. The application supports the common _FILE suffix pattern.

Supported Variables

Environment Variable File Variant
TECHNITIUM_CLUSTER_TOKEN TECHNITIUM_CLUSTER_TOKEN_FILE
TECHNITIUM_BACKGROUND_TOKEN TECHNITIUM_BACKGROUND_TOKEN_FILE
TECHNITIUM_<NODE>_TOKEN TECHNITIUM_<NODE>_TOKEN_FILE

When the _FILE variant is set, the application reads the secret from that file path. The _FILE variant takes precedence if both are set.

Docker Swarm Example

  1. Create the secrets:
echo "your-cluster-token" | docker secret create technitium_cluster_token -
echo "your-background-token" | docker secret create technitium_background_token -
  1. Reference in your stack file:
version: "3.8"

services:
  technitium-dns-companion:
    image: ghcr.io/fail-safe/technitium-dns-companion:latest
    environment:
      TECHNITIUM_NODES: "node1,node2"
      TECHNITIUM_NODE1_BASE_URL: "http://dns1.example.com:5380"
      TECHNITIUM_NODE2_BASE_URL: "http://dns2.example.com:5380"
      AUTH_SESSION_ENABLED: "true"
      # Use _FILE variants for secrets
      TECHNITIUM_CLUSTER_TOKEN_FILE: /run/secrets/technitium_cluster_token
      TECHNITIUM_BACKGROUND_TOKEN_FILE: /run/secrets/technitium_background_token
    secrets:
      - technitium_cluster_token
      - technitium_background_token
    ports:
      - "3000:3000"
    volumes:
      - companion-data:/data

secrets:
  technitium_cluster_token:
    external: true
  technitium_background_token:
    external: true

volumes:
  companion-data:

Kubernetes Example

  1. Create the secret:
kubectl create secret generic technitium-tokens \
  --from-literal=cluster-token='your-cluster-token' \
  --from-literal=background-token='your-background-token'
  1. Mount in your deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: technitium-dns-companion
spec:
  template:
    spec:
      containers:
        - name: companion
          image: ghcr.io/fail-safe/technitium-dns-companion:latest
          env:
            - name: TECHNITIUM_NODES
              value: "node1,node2"
            - name: TECHNITIUM_CLUSTER_TOKEN_FILE
              value: /secrets/cluster-token
            - name: TECHNITIUM_BACKGROUND_TOKEN_FILE
              value: /secrets/background-token
          volumeMounts:
            - name: secrets
              mountPath: /secrets
              readOnly: true
      volumes:
        - name: secrets
          secret:
            secretName: technitium-tokens

Per-Node Tokens

For legacy deployments with per-node tokens:

# Create secrets for each node
echo "node1-token" | docker secret create technitium_node1_token -
echo "node2-token" | docker secret create technitium_node2_token -
environment:
  TECHNITIUM_NODE1_TOKEN_FILE: /run/secrets/technitium_node1_token
  TECHNITIUM_NODE2_TOKEN_FILE: /run/secrets/technitium_node2_token
secrets:
  - technitium_node1_token
  - technitium_node2_token

Need contributor/dev container instructions? See DEVELOPMENT.md or docker-compose.dev.yml.