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)¶
Option A: One-command quickstart (recommended)¶
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.exampleintotechnitium.envif missing - Pulls the selected image first (so
:lateststays current) - Shows the exact
docker runcommand 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.envdidn’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.
-
Prepare environment:
-
Download
.env.example(or copy it from a clone) and save astechnitium.env. - Minimum variables:
TECHNITIUM_NODES=node1,node2TECHNITIUM_<NODE>_BASE_URLfor each node.- Recommended (and required starting in v1.4):
AUTH_SESSION_ENABLED=true(Technitium login/RBAC for UI access). - Recommended for background features in session-auth mode:
TECHNITIUM_BACKGROUND_TOKEN(least-privilege, read-only). - Legacy only (Technitium DNS < v14 / migration): env-token mode using
TECHNITIUM_<NODE>_TOKEN. TECHNITIUM_CLUSTER_TOKENis deprecated as of v1.3.0 (legacy / migration source) and will be removed in v1.4.-
Optional: set
TZ,CORS_ORIGINS, and HTTPS variables. -
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:/datais 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_PATHto a path under/dataso 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 requiresTECHNITIUM_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}\certsfor the host path. -
Operations:
-
Logs:
docker logs -f <container-id>(if run without--rm, add--name tdcthendocker 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.
-
Copy
.env.exampleto.envand set your variables. -
Start:
docker compose up -d --build
-
HTTPS: place certs in
certs/and set the HTTPS vars in.env, then ensure the certs volume is mounted indocker-compose.yml. -
Operations:
-
Logs:
docker compose logs -f - Restart:
docker compose restart - Upgrade:
git pull && docker compose up -d --build
Troubleshooting¶
- Container will not start:
docker compose logsthendocker compose configto 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¶
- Create the secrets:
echo "your-cluster-token" | docker secret create technitium_cluster_token -
echo "your-background-token" | docker secret create technitium_background_token -
- 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¶
- Create the secret:
kubectl create secret generic technitium-tokens \
--from-literal=cluster-token='your-cluster-token' \
--from-literal=background-token='your-background-token'
- 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.