<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ad-Blocker – Serverküche</title><link>https://serverkueche.de/en/tags/ad-blocker/</link><description>Ad-Blocker – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>en-US</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Mon, 17 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/en/tags/ad-blocker/index.xml" rel="self" type="application/rss+xml"/><item><title>AdGuard Home: network-wide ad and tracking blocker</title><link>https://serverkueche.de/en/tutorials/adguard-home-ad-blocker/</link><pubDate>Mon, 17 Aug 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/adguard-home-ad-blocker/</guid><description>Set up AdGuard Home with Docker: your own DNS server that blocks ads, trackers and malicious sites for all devices – securely, only via the VPN.</description><content:encoded><![CDATA[<p>Ads and trackers are blocked most effectively not in the browser, but <strong>in DNS</strong> – there, where every device asks which IP belongs to a domain. <strong>AdGuard Home</strong> is a self-hosted DNS server that simply lets requests to known ad, tracking and malicious domains run into the void. One server, all devices – phone, TV, laptop – without a single app on the client.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>By the end, <strong>AdGuard Home v0.107.78</strong> runs as a DNS server on your VPS. It answers DNS requests, filters out ads/trackers/malware based on block lists, and shows you live in a web interface what was blocked. Concretely:</p>
<ul>
<li>a <strong>DNS filter</strong> with over 150,000 rules (default block list), extensible with any lists,</li>
<li>a <strong>web interface</strong> with statistics and a query log, secured behind your reverse proxy,</li>
<li>the DNS service reachable <strong>exclusively via your WireGuard tunnel</strong> – not open on the internet.</li>
</ul>
<p>The last point is decisive and the reason this tutorial requires WireGuard: an <strong>open DNS resolver</strong> on the internet is abused within hours for <strong>DNS amplification attacks</strong>. So we bind the DNS port to the VPN interface, and only your own devices talk to it via the tunnel.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A server with <strong><a href="/en/tutorials/install-docker/">Docker</a></strong> and a running <strong><a href="/en/tutorials/traefik-reverse-proxy/">Traefik reverse proxy</a></strong> (for the web interface under its own domain with TLS).</li>
<li>A set-up <strong><a href="/en/tutorials/wireguard-vpn-setup/">WireGuard VPN</a></strong> with the server interface <code>wg0</code> at <code>10.8.0.1</code>. Your devices later reach the DNS server through it.</li>
<li>Basic understanding of DNS (domain → IP) helps but isn&rsquo;t a must.</li>
</ul>
<p>AdGuard Home is extremely frugal – it gets by with a few tens of MB of RAM. The smallest plan is plenty, especially since it probably runs alongside other services at your place anyway.</p>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20"
     data-track-content data-content-name="Affiliate-Box · /en/tutorials/adguard-home-ad-blocker/" data-content-piece="VPS 1000 G12">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Recommendation</span>
    <span title="Links marked with * are affiliate links.">Ad</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 1000 G12</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCores · 8 GB RAM · 256 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €10.36/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">More than sufficient for AdGuard Home.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12-iv-12m?ref=44083" rel="sponsored noopener" target="_blank"
   data-track-event="Affiliate|netcup: Affiliate-Box|VPS 1000 G12 · {page}"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Go to netcup →
</a>

  </div><div class="px-4 pb-4"><p class="not-prose my-3 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <span>💶 <strong>5 € voucher</strong> for new netcup customers:</span><code data-track-voucher="36nc17844976032"
        class="rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</code>
  <span class="text-xs text-slate-500 dark:text-slate-400">(new customers only, no domains)</span>
</p></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-is-port-53-free">Step 1: Is port 53 free?</h3>
<p>AdGuard Home needs <strong>port 53</strong> – the DNS port. On some systems <code>systemd-resolved</code> already occupies it. Check that:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ss -tulpn <span class="p">|</span> grep <span class="s2">&#34;:53 &#34;</span></span></span></code></pre></div>
</div>
<p>On the netcup Debian 13 image used here, the port was <strong>free</strong> (no systemd-resolved active), so the output was empty. If you instead get a line with <code>systemd-resolve</code>, you have to disable its stub listener – otherwise AdGuard won&rsquo;t start (&ldquo;address already in use&rdquo;):</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mkdir -p /etc/systemd/resolved.conf.d
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -e <span class="s2">&#34;[Resolve]\nDNSStubListener=no&#34;</span> <span class="p">|</span> sudo tee /etc/systemd/resolved.conf.d/adguard.conf
</span></span><span class="line"><span class="cl">sudo systemctl restart systemd-resolved</span></span></code></pre></div>
</div>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Don&#39;t forget resolv.conf
  </p>
  <div class="prose-kitchen text-sm">If you disable the stub listener, <code>/etc/resolv.conf</code> may still point to <code>127.0.0.53</code> and the server itself can no longer resolve names. In that case, set a working resolver, e.g. <code>nameserver 9.9.9.9</code> (or your provider&rsquo;s), so <code>apt</code> &amp; co. keep working.</div>
</div>
<h3 id="step-2-create-the-docker-compose">Step 2: Create the Docker Compose</h3>
<p>Create the project folder:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p /opt/adguardhome/work /opt/adguardhome/conf <span class="o">&amp;&amp;</span> <span class="nb">cd</span> /opt/adguardhome</span></span></code></pre></div>
</div>
<p>Create the <code>compose.yaml</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">adguardhome</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">adguard/adguardhome:v0.107.78</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">adguardhome</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./work:/opt/adguardhome/work</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./conf:/opt/adguardhome/conf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;10.8.0.1:53:53/tcp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;10.8.0.1:53:53/udp&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">proxy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.enable=true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.adguard.rule=Host(`YOUR_DOMAIN`)&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.adguard.entrypoints=websecure&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.adguard.tls.certresolver=le&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.services.adguard.loadbalancer.server.port=3000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">proxy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">external</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></div>
</div>
<p>The most important things:</p>
<ul>
<li><strong><code>ports: &quot;10.8.0.1:53:53&quot;</code></strong> – the DNS port is bound <strong>only to the WireGuard address</strong>, not to <code>0.0.0.0</code>. This makes the resolver reachable exclusively via the VPN tunnel and <strong>never open on the internet</strong>. This one line is the difference between &ldquo;secure&rdquo; and &ldquo;abused for attacks&rdquo;.</li>
<li>The <strong>web interface</strong> runs on container port <strong>3000</strong> and is published under <code>YOUR_DOMAIN</code> with TLS via the four Traefik labels. Replace <code>YOUR_DOMAIN</code> with your real domain.</li>
<li>Both <code>volumes</code> (<code>work</code>, <code>conf</code>) make the configuration and statistics persistent.</li>
</ul>
<p>Start the container:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose up -d</span></span></code></pre></div>
</div>
<p>Check that it&rsquo;s running:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose ps</span></span></code></pre></div>
</div>
<p>You should see <code>Up</code> and that port 53 is bound to <code>10.8.0.1</code>.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-paprika-400 bg-paprika-50 dark:border-paprika-700 dark:bg-paprika-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🔥</span>Never port 53 open to the internet
  </p>
  <div class="prose-kitchen text-sm"><strong>Never</strong> write <code>- &quot;53:53/udp&quot;</code> (that binds to all interfaces) on a public server. An open resolver is found automatically and abused for amplification DDoS against third parties – your provider then rightly suspends you. Always bind to a private interface (<code>10.8.0.1</code>).</div>
</div>
<h3 id="step-3-the-initial-setup">Step 3: The initial setup</h3>
<p>Open your domain in the browser – you land in the <strong>setup wizard</strong>. At the bottom right you can set the language.</p>
<p><figure class="my-6"><img src="/en/tutorials/adguard-home-ad-blocker/adguard-ersteinrichtung_hu_c311aab651123880.webp" srcset="/en/tutorials/adguard-home-ad-blocker/adguard-ersteinrichtung_hu_b9d344ef6275f05.webp 480w, /en/tutorials/adguard-home-ad-blocker/adguard-ersteinrichtung_hu_c311aab651123880.webp 768w, /en/tutorials/adguard-home-ad-blocker/adguard-ersteinrichtung_hu_7e27318e4165fd3f.webp 1200w, /en/tutorials/adguard-home-ad-blocker/adguard-ersteinrichtung_hu_4ac10ab9d2a0eb86.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/adguard-home-ad-blocker/adguard-ersteinrichtung_hu_8ac30040b70ac554.webp"
    alt="The welcome screen of the AdGuard Home setup wizard." title="The setup wizard greets you – set the language at the bottom right."
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The setup wizard greets you – set the language at the bottom right.</figcaption></figure></p>
<p>Click through the five steps. Two settings are important:</p>
<ul>
<li><strong>Admin web interface:</strong> as the port you must enter <strong>3000</strong> (All interfaces, port <code>3000</code>) – because that&rsquo;s exactly where Traefik forwards. The suggestion is often port 80; if you don&rsquo;t change it, the interface is no longer reachable via Traefik after the setup.</li>
<li><strong>DNS server:</strong> port <strong>53</strong> (All interfaces). The restriction to the VPN interface is already handled by the port binding from the Compose – inside the container, AdGuard may listen on all interfaces.</li>
</ul>
<p>Then you create a <strong>username and a strong password</strong> for the login. Done – you&rsquo;re redirected to the login.</p>
<h3 id="step-4-the-dashboard">Step 4: The dashboard</h3>
<p>After logging in you see the <strong>overview</strong>: number of requests, how many of them were blocked, the most frequently requested and the most frequently blocked domains.</p>
<p><figure class="my-6"><img src="/en/tutorials/adguard-home-ad-blocker/adguard-dashboard_hu_e6dce879e2886fe9.webp" srcset="/en/tutorials/adguard-home-ad-blocker/adguard-dashboard_hu_3e7b6bff6fbe3d76.webp 480w, /en/tutorials/adguard-home-ad-blocker/adguard-dashboard_hu_e6dce879e2886fe9.webp 768w, /en/tutorials/adguard-home-ad-blocker/adguard-dashboard_hu_50acf7e88d89a3df.webp 1200w, /en/tutorials/adguard-home-ad-blocker/adguard-dashboard_hu_ea241b771fe2457e.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/adguard-home-ad-blocker/adguard-dashboard_hu_66db0ed993db9114.webp"
    alt="The AdGuard Home dashboard with request statistics and top domains." title="The dashboard shows live how many requests arrive and how many are blocked."
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The dashboard shows live how many requests arrive and how many are blocked.</figcaption></figure></p>
<p>At first everything is at zero – it fills up as soon as the first device uses AdGuard as its DNS (step 6).</p>
<h3 id="step-5-manage-block-lists">Step 5: Manage block lists</h3>
<p>Under <strong>Filters → DNS blocklists</strong> you see the active block lists. By default the <strong>AdGuard DNS filter</strong> is active – for us with <strong>159,173 rules</strong>.</p>
<p><figure class="my-6"><img src="/en/tutorials/adguard-home-ad-blocker/adguard-filterlisten_hu_90382eb83dafae56.webp" srcset="/en/tutorials/adguard-home-ad-blocker/adguard-filterlisten_hu_5787b59e5e3e0f7c.webp 480w, /en/tutorials/adguard-home-ad-blocker/adguard-filterlisten_hu_90382eb83dafae56.webp 768w, /en/tutorials/adguard-home-ad-blocker/adguard-filterlisten_hu_770f40222343234.webp 1200w, /en/tutorials/adguard-home-ad-blocker/adguard-filterlisten_hu_bf02ff6c1ff9313f.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/adguard-home-ad-blocker/adguard-filterlisten_hu_38ec8a520cd49363.webp"
    alt="The management of DNS block lists in AdGuard Home." title="The default block list is active; you enable or add more lists here."
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The default block list is active; you enable or add more lists here.</figcaption></figure></p>
<p>Via <strong>Add blocklist</strong> you can include more curated lists (AdGuard brings a catalog, e.g. AdAway or OISD). Less is often more: one or two good lists block most, without legitimate sites constantly breaking. With <strong>Check for updates</strong> you update the rules manually; AdGuard otherwise keeps them current automatically (see &ldquo;Maintenance&rdquo;).</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Don&#39;t overdo it
  </p>
  <div class="prose-kitchen text-sm">It&rsquo;s tempting to stack ten aggressive lists. But that leads to <strong>overblocking</strong>: login pages, images or shopping carts suddenly don&rsquo;t work anymore, and troubleshooting is tedious. Start with the default list and add specifically.</div>
</div>
<h3 id="step-6-switch-devices-to-adguard">Step 6: Switch devices to AdGuard</h3>
<p>For your devices to use the filter, they have to use AdGuard as their DNS server. Via the WireGuard tunnel this works most elegantly <strong>centrally in the client configuration</strong>: enter the server&rsquo;s tunnel address as DNS in the <code>[Interface]</code> section of your WireGuard clients:</p>
<div class="sk-code">
  <span class="sk-code-head">INI</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Interface]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># ... your existing lines ...</span>
</span></span><span class="line"><span class="cl"><span class="na">DNS</span> <span class="o">=</span> <span class="s">10.8.0.1</span></span></span></code></pre></div>
</div>
<p>As soon as the tunnel is up, the device sends all DNS requests to AdGuard – whether on Wi-Fi on the go or on the mobile network. No intervention at the router needed, and the protection works on the go too.</p>
<h3 id="step-7-does-it-really-work">Step 7: Does it really work?</h3>
<p>Check the resolver directly on the server via the VPN address. A normal domain must resolve:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig @10.8.0.1 +short example.com</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">172.66.147.243</span></span></code></pre></div>
</div>
<p>A known tracking domain must be <strong>blocked</strong> – AdGuard then answers with <code>0.0.0.0</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig @10.8.0.1 +short doubleclick.net</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0.0.0.0</span></span></code></pre></div>
</div>
<p>As a counter-check that the resolver does <strong>not</strong> listen openly, you query it via the loopback address – that must fail:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig @127.0.0.1 +time<span class="o">=</span><span class="m">2</span> +tries<span class="o">=</span><span class="m">1</span> example.com</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">;; communications error to 127.0.0.1#53: connection refused</span></span></code></pre></div>
</div>
<p>Exactly as it should be: reachable via <code>10.8.0.1</code> (the tunnel), rejected on all other addresses. A look at the <strong>query log</strong> in the web interface shows the same requests live – blocked entries are marked red and name the list that took effect:</p>
<p><figure class="my-6"><img src="/en/tutorials/adguard-home-ad-blocker/adguard-abfrageprotokoll_hu_eb5c1b3656056f41.webp" srcset="/en/tutorials/adguard-home-ad-blocker/adguard-abfrageprotokoll_hu_83b4bfc3848bbc92.webp 480w, /en/tutorials/adguard-home-ad-blocker/adguard-abfrageprotokoll_hu_eb5c1b3656056f41.webp 768w, /en/tutorials/adguard-home-ad-blocker/adguard-abfrageprotokoll_hu_3a2604c938b303fa.webp 1200w, /en/tutorials/adguard-home-ad-blocker/adguard-abfrageprotokoll_hu_3be87d28e48aa39e.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/adguard-home-ad-blocker/adguard-abfrageprotokoll_hu_b89c4e8e72981ac2.webp"
    alt="The query log of AdGuard Home with allowed and blocked requests." title="The query log: blocked domains (red) with the list that blocked them."
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The query log: blocked domains (red) with the list that blocked them.</figcaption></figure></p>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>The container won&rsquo;t start, the log says &ldquo;listen udp :53: bind: address already in use&rdquo;.</strong>
<code>systemd-resolved</code> (or another DNS service) occupies port 53. disable the stub listener as in step
1, then <code>docker compose up -d</code> again.</p>
<p><strong><code>docker compose up</code> fails with &ldquo;cannot assign requested address&rdquo; for <code>10.8.0.1</code>.</strong> the WireGuard
interface <code>wg0</code> with <code>10.8.0.1</code> doesn&rsquo;t exist (yet) – Docker can&rsquo;t bind the port to a non-existent
address. first set up the <a href="/en/tutorials/wireguard-vpn-setup/">WireGuard VPN</a> and bring <code>wg0</code> up
(<code>ip -br addr show wg0</code> must show <code>10.8.0.1</code>), then start the container.</p>
<p><strong>After the setup, the web interface is no longer reachable.</strong> in the wizard, the admin port was set
to 80 (the suggestion) instead of <strong>3000</strong> – but Traefik forwards to 3000. in
<code>./conf/AdGuardHome.yaml</code> under <code>http:</code> correct the <code>address</code> to <code>0.0.0.0:3000</code> and <code>docker compose restart</code>.</p>
<p><strong>DNS doesn&rsquo;t filter, even though the device is connected.</strong> the browser uses <strong>DNS-over-HTTPS
(DoH)</strong> and thus bypasses your server completely – Firefox and Chrome have this active by default in
part. disable &ldquo;Secure DNS&rdquo; / &ldquo;DNS over HTTPS&rdquo; in the browser settings. You can check with <code>dig @10.8.0.1 …</code> (always takes effect).</p>
<p><strong>A website is suddenly broken (empty pages, missing images, no login).</strong> overblocking – a block
list blocks a domain the site really needs. find the blocked domain in the query log, <strong>allow</strong> it
via right-click/menu (exception) or disable the overly aggressive list.</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<p><strong>Block-list updates.</strong> AdGuard updates the lists automatically (default: every 24 hours). You don&rsquo;t have to do anything here; a manual <strong>Check for updates</strong> is possible any time if needed.</p>
<p><strong>Backups.</strong> The entire configuration is in <strong><code>/opt/adguardhome/conf/AdGuardHome.yaml</code></strong> – admin login, DNS settings, lists, exceptions. You back up this file (plus the <code>work</code> folder with the statistics) regularly, e.g. via <a href="/en/tutorials/restic-backups/">Restic</a>. This way a server migration is done in minutes: bring up the container, restore <code>conf</code>, done.</p>
<p><strong>Updates.</strong> You fetch new versions like with any Compose stack. Pin the tag deliberately (not <code>latest</code>) so updates happen in a controlled way:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> /opt/adguardhome
</span></span><span class="line"><span class="cl">docker compose pull <span class="o">&amp;&amp;</span> docker compose up -d</span></span></code></pre></div>
</div>
<p><strong>Privacy.</strong> The query log stores which device requested which domain – that&rsquo;s gold for troubleshooting, but also sensitive. Under <strong>Settings → General settings</strong> you can shorten the <strong>retention period</strong> of the log or disable logging entirely. Especially when other people share your DNS, a short retention is fair.</p>
]]></content:encoded></item></channel></rss>