Homeserver: Setup Raspberry Pi with AdGuard and Traefik
Step-by-step guide to set up a Raspberry Pi as a home server with AdGuard Home, Traefik, and Heimdall in 2025.

Table of Contents
- Prerequisites and Hardware Recommendations
- OS Installation: Headless Setup with Raspberry Pi OS
- Configuring Raspberry Pi OS
- Installing Docker and Docker Compose
- Setting Up AdGuard Home as an Ad Blocker
- Setting Up Traefik as a Reverse Proxy
- Setting Up Heimdall as a Dashboard
- Automatic Updates and Maintenance
- Public Access to Your Services
- Conclusion and Outlook
In 2021, I published a blog post about setting up a Raspberry Pi as a home server with a proxy manager and ad blocker. Since then, much has changed. In this updated post, I’ll show you how to set up an efficient home server based on a Raspberry Pi in 2025.
Prerequisites and Hardware Recommendations
For a reliable home server, you don’t necessarily need the latest Raspberry Pi. At minimum, I recommend a Raspberry Pi 4 with at least 4GB RAM for better performance with multiple parallel services. Basically, any other device running Debian as an operating system can also be used.
SD cards are definitely not suitable for continuous operation as system storage. They have limited write/read cycles and will eventually fail with intensive use. Instead, I strongly recommend an external SSD connected via USB 3.0. The advantages are clear: higher speed, longer lifespan, and greater reliability.
The consumption of a Raspberry Pi remains manageable. A Raspberry Pi 5 requires about 4-5 watts at idle and up to 10 watts under full load. Compared to a full-sized server, this is still very economical.
Ergebnis: €35.92 / Jahr | €2.99 / Monat
OS Installation: Headless Setup with Raspberry Pi OS
The Raspberry Pi Imager has become much more user-friendly and offers more configuration options directly when creating the boot media.
First, download the current Raspberry Pi Imager from the official website. After starting, select “Raspberry Pi OS Lite (64-bit)” as the operating system. The 64-bit version is now the standard recommendation and no longer labeled as beta. The Lite version without a desktop is completely sufficient for a server and saves valuable resources.
- Before clicking on “Write”, open the advanced options. Here you can now:
- Enable SSH directly (choose “SSH with password authentication”)
- Set a username and password (no longer the insecure default user “pi”)
Configure WiFi if you’re not using a LAN cable
This preconfiguration saves you many manual steps later. Choose your external SSD as the storage medium and click “Write”. After the writing process is complete, the SSD can be connected directly to the Raspberry Pi.
After the first boot, you can connect to your Pi via SSH. On Windows, this is easiest through PowerShell or Windows Terminal:
ssh username@ip-adresse
Use the IP address that you can find in your router’s settings.
Configuring Raspberry Pi OS
After successfully connecting, we first update the system:
sudo apt update -y
sudo apt upgrade -y
sudo apt autoremove -y
This may take some time. Afterward, it’s useful to check the basic system settings:
# Check timezone
date
# If necessary, set timezone
sudo timedatectl set-timezone 'Europe/Berlin'
# Monitor system load
htop
# Monitor temperature
cat /sys/class/thermal/thermal_zone0/temp
The last command shows the CPU temperature in millidegrees Celsius (divide the displayed value by 1000). During extended use under load, you should ensure adequate cooling. Modern Raspberry Pi 5 models generate more heat than their predecessors and typically require active cooling.
Installing Docker and Docker Compose
Docker has become the de-facto standard for application deployment. Installing Docker on Raspberry Pi OS is now done through the official Debian repositories:
# Install necessary packages
sudo apt-get update
sudo apt-get install -y ca-certificates curl
# Set up Docker repository
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
In 2025, Docker Compose is already integrated as a plugin in Docker and doesn’t need to be installed separately. To verify that everything has been installed correctly:
docker --version
docker compose version
Now we create a basic structure for our Docker containers:
mkdir -p ~/docker
cd ~/docker
Setting Up AdGuard Home as an Ad Blocker
Instead of Blocky, which was used in the original blog post, we now use AdGuard Home. AdGuard Home offers a more modern user interface, regular updates, and greater community support.
We create a folder for AdGuard Home and the necessary subfolders:
mkdir -p ~/docker/adguard/{work,conf}
cd ~/docker/adguard
Now we create the Docker Compose file:
nano docker-compose.yml
We add the following configuration to this file:
services:
adguard:
image: adguard/adguardhome
container_name: adguard
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "81:80/tcp"
- "3000:3000/tcp"
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
environment:
TZ: Europe/Berlin
networks:
- proxy
networks:
proxy:
external: true
Before we start the container, we need to create the Docker network “proxy” that will later be used by all our services:
sudo docker network create proxy
Now we can start AdGuard Home:
sudo docker compose up -d
After startup, AdGuard Home is accessible at http://[raspberry-pi-ip]:3000
A setup wizard will guide you through the configuration when first accessed. Choose port 53 for the DNS service and port 80 for the web interface. Then create an administrator account.
To use AdGuard Home as a DNS server across your entire network, you need to enter the IP address of the Raspberry Pi as the primary DNS server in your router settings. On a Fritz!Box, you can find this setting under “Internet > Login Details > DNS Server”
In the AdGuard dashboard, you can add pre-configured blocklists under “Filters”. Supplement these with a whitelist to avoid false positives, for example this Whitelist.
https://raw.githubusercontent.com/deployn/adguardhomelist/main/whitelist.txt
Setting Up Traefik as a Reverse Proxy
In the original guide, I used the Nginx Proxy Manager. For the updated version, we’re using Traefik for a change, which is now in version 3 and offers excellent integration with Docker.
We create a new folder for Traefik:
mkdir -p ~/docker/traefik
cd ~/docker/traefik
Then we create the Docker Compose file:
nano docker-compose.yml
With the following content:
services:
traefik:
image: traefik:3
container_name: traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./acme.json:/acme.json
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.home`)"
- "traefik.http.routers.traefik.entrypoints=web"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
networks:
proxy:
external: true
Now we need the Traefik configuration file:
nano traefik.yml
With this content:
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: proxy
api:
dashboard: true
insecure: true
log:
level: INFO
And we create an empty file for SSL certificates:
touch acme.json
chmod 600 acme.json
Now we can start Traefik:
sudo docker compose up -d
Traefik is now accessible at https://traefik.home
. The dashboard shows you all active Docker containers and the configured routes.
Setting Up Heimdall as a Dashboard
As the final component of our basic system, we install Heimdall as a modern dashboard to centrally manage all our services. Homer, which was used in the original guide, is still a good option, but Heimdall offers more integration possibilities with various services.
We create a new folder for Heimdall:
mkdir -p ~/docker/heimdall/config
cd ~/docker/heimdall
Then we create the Docker Compose file:
nano docker-compose.yml
With the following content:
services:
heimdall:
image: linuxserver/heimdall:latest
container_name: heimdall
restart: unless-stopped
volumes:
- ./config:/config
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Berlin
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.heimdall.rule=Host(`heimdall.home`)"
- "traefik.http.routers.heimdall.entrypoints=web"
- "traefik.http.services.heimdall.loadbalancer.server.port=80"
networks:
proxy:
external: true
Now we start Heimdall:
sudo docker compose up -d
Heimdall is now accessible via http://heimdall.home
and can serve as a central hub for all your self-hosted services. You can add tiles for AdGuard Home, Traefik, and any other services you install later.
Automatic Updates and Maintenance
An often-neglected aspect of home servers is regular maintenance. We at least set up automatic updates for the operating system:
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
For Docker containers, there are various solutions. Manual updates are easy with:
sudo docker compose -f ~/docker/adguard/docker-compose.yml pull
sudo docker compose -f ~/docker/træfik/docker-compose.yml pull
sudo docker compose -f ~/docker/heimdall/docker-compose.yml pull
sudo docker compose -f ~/docker/adguard/docker-compose.yml down && sudo docker compose -f ~/docker/adguard/docker-compose.yml up -d
sudo docker compose -f ~/docker/træfik/docker-compose.yml down && sudo docker compose -f ~/docker/træfik/docker-compose.yml up -d
sudo docker compose -f ~/docker/heimdall/docker-compose.yml down && sudo docker compose -f ~/docker/heimdall/docker-compose.yml up -d
Additionally, you should regularly remove unused Docker images and volumes:
sudo docker system prune -af
This will remove:
- All stopped containers
- All networks not used by at least one container
- All unused images (not just the “dangling” images, thanks to the -a/—all option)
- Unused build cache
The -f/--force
option skips the confirmation prompt, so the cleanup is executed immediately without confirmation.
Public Access to Your Services
If you want to make your services accessible from outside your home network, you need:
- A dynamic DNS solution (e.g., DuckDNS)
- Port forwarding in your router
- SSL certificates for secure connections
To use Let’s Encrypt certificates with Traefik, you need to adjust the Traefik configuration:
cd ~/docker/traefik
nano traefik.yml
Add the following sections to the file:
certificatesResolvers:
letsencrypt:
acme:
email: your@email.com
storage: acme.json
httpChallenge:
entryPoint: web
For a container that should be publicly accessible, you would then add the following labels:
labels:
- "traefik.enable=true"
- "traefik.http.routers.dienst.rule=Host(`service.your-domain.com`)"
- "traefik.http.routers.dienst.entrypoints=websecure"
- "traefik.http.routers.dienst.tls.certresolver=letsencrypt"
- "traefik.http.services.dienst.loadbalancer.server.port=80"
If you don’t have a public IP address, you can also build a tunnel to your home server via Pangolin.
Conclusion and Outlook
With this setup, you have configured a modern, efficient, and secure home server based on a Raspberry Pi. The basic structure with Docker, AdGuard Home as an ad blocker, Traefik as a reverse proxy, and Heimdall as a dashboard provides a solid foundation for additional services.