How to setup Blocky DNS ad blocker on Docker

A lightweight alternative to Pi-hole and AdGuard Home written in Go that can be deployed in Docker or wherever you want

Victor Bayas
Victor Bayas
August 30, 2023
7 min read
How to setup Blocky DNS ad blocker on Docker

Introduction

DNS (Domain Name System): Is an important part of the Internet that translates domain names such as bayas.dev into an IP address like 76.76.21.21 that your computer can understand.

Blocky is a powerful and versatile DNS proxy and ad-blocker for your local network. It is written in Go, a fast and reliable programming language, and it offers many features to enhance your online privacy and security. Blocky can be easily configured with a YAML file, which allows you to customize its behavior according to your needs. You can run Blocky on any device that supports Go, such as a Raspberry Pi, OpenWrt, Docker, Kubernetes or your own server.

One of the advantages of Blocky is that it can integrate with Grafana, a popular platform for data visualization and monitoring. This way, you can see how Blocky is performing and how much traffic it is blocking on your network. However, Grafana integration is optional and not required for using Blocky. In this guide, we will focus on how to install and configure Blocky for basic usage.

Features

  • Blocking - Blocking of DNS queries with external lists (Ad-block, malware) and whitelisting

    • Definition of black and white lists per client group (Kids, Smart home devices, etc.)
    • Periodical reload of external black and white lists
    • Regex support
    • Blocking of request domain, response CNAME (deep CNAME inspection) and response IP addresses (against IP lists)
  • Advanced DNS configuration - not just an ad-blocker

    • Custom DNS resolution for certain domain names
    • Conditional forwarding to external DNS server
    • Upstream resolvers can be defined per client group
  • Performance - Improves speed and performance in your network

    • Customizable caching of DNS answers for queries -> improves DNS resolution speed and reduces amount of external DNS queries
    • Prefetching and caching of often used queries
    • Using multiple external resolver simultaneously
    • Low memory footprint
  • Various Protocols - Supports modern DNS protocols

    • DNS over UDP and TCP
    • DNS over HTTPS (aka DoH)
    • DNS over TLS (aka DoT)
  • Security and Privacy - Secure communication

    • Supports modern DNS extensions: DNSSEC, eDNS, ...
    • Free configurable blocking lists - no hidden filtering etc.
    • Provides DoH Endpoint
    • Uses random upstream resolvers from the configuration - increases your privacy through the distribution of your DNS traffic over multiple provider
    • Blocky does NOT collect any user data, telemetry, statistics etc.
  • Integration - various integration

    • Prometheus metrics
    • Prepared Grafana dashboards (Prometheus and database)
    • Logging of DNS queries per day / per client in CSV format or MySQL/MariaDB/PostgreSQL database - easy to analyze
    • Various REST API endpoints
    • CLI tool
  • Simple configuration - single or multiple configuration files in YAML format

    • Simple to maintain
    • Simple to backup
  • Simple installation/configuration - blocky was designed for simple installation

    • Stateless (no database, no temporary files)
    • Docker image with Multi-arch support
    • Single binary
    • Supports x86-64 and ARM architectures -> runs fine on Raspberry PI
    • Community supported Helm chart for k8s deployment

Docker compose setup

For this guide I'll use Docker for the deployment but you can directly download and run the latest Blocky release in your system.

Create a docker-compose.yml file with the following content:

docker-compose.yml

version: "3"
services:
blocky:
image: spx01/blocky:latest
container_name: blocky
restart: unless-stopped
# Optional the instance hostname for logging purpose
hostname: blocky-homelab-pi
ports:
- "53:53/tcp"
- "53:53/udp"
environment:
- TZ=America/Guayaquil # Optional to synchronize the log timestamp with host
volumes:
# config file
- ./config.yml:/app/config.yml

Configuration example (config.yml)

Before starting the container you need to create a config.yml file within the same directory as the docker-compose.yml file. This file will contain the configuration for Blocky.

I have added some comments to the configuration file to explain what each section does. You can find more information about the configuration options in the official documentation.

config.yml

upstreams:
groups:
default:
# unencrypted DNS upstreams
- 1.1.1.1
# DNS over HTTPS upstreams
- https://dns.google/dns-query
- https://dns.nextdns.io
# DNS over TLS upstreams
- tcp-tls:dns.quad9.net
# blocky will pick the 2 fastest upstreams but you can also use the `strict` strategy
strategy: parallel_best
timeout: 2s
# check if upstreams are working
startVerifyUpstream: true
# there's no IPv6 connectivity inside Docker networks
connectIPVersion: v4
# useful for self hosted services
customDNS:
customTTL: 1h
mapping:
someservice.bayas.dev: 10.1.0.4
# useful for local network DNS resolution
conditional:
mapping:
lan: 10.1.0.1
# for reverse DNS lookups of local devices
0.1.10.in-addr.arpa: 10.1.0.1
# for all unqualified hostnames
.: 10.1.0.1
blocking:
# I prefer the HaGeZi Light blocklist for set and forget setup, you can use any other blacklist nor whitelist you want
# Blocky supports hosts, domains and regex syntax
blackLists:
ads:
- https://raw.githubusercontent.com/hagezi/dns-blocklists/main/domains/light.txt
clientGroupsBlock:
default:
- ads
blockType: zeroIp
blockTTL: 1m
loading:
refreshPeriod: 6h
downloads:
timeout: 60s
attempts: 5
cooldown: 10s
concurrency: 16
# start answering queries immediately after start
strategy: fast
maxErrorsPerSource: 5
caching:
# enable prefetching improves performance for often used queries
prefetching: true
# if a domain is queried more than prefetchThreshold times, it will be prefetched for prefetchExpires time
prefetchExpires: 24h
prefetchThreshold: 2
# use encrypted DNS for resolving upstreams
# same syntax as normal upstreams
bootstrapDns:
- https://8.8.8.8/dns-query

Final thoughts

Blocky is a great alternative to Pi-hole and AdGuard Home, it's lightweight and highly configurable. I have been using it for the last week and I'm very happy with it.

Enjoy!

Let's build together

I'm always open to new projects and opportunities. Drop me an email or DM me on X and I'll get back to you.

cta

© 2024 Victor Bayas.