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.

Homeserver: Setup Raspberry Pi with AdGuard and Traefik-heroimage

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.

Externe SSD als System Festplatte

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.

  1. Before clicking on “Write”, open the advanced options. Here you can now:
  2. Enable SSH directly (choose “SSH with password authentication”)
  3. 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.


Oh no, Comentario failed to start.
If you own this website, you might want to look at the browser console to find out why.
This website uses cookies. These are necessary for the functionality of the website. You can find more information in the privacy policy