<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dale John Dunlop</title><description>Personal website and blog of Dale John Dunlop</description><link>https://dalejohndunlop.com/</link><language>en-us</language><lastBuildDate>Thu, 03 Apr 2025 22:19:34 GMT</lastBuildDate><ttl>60</ttl><image><url>https://dalejohndunlop.com/favicon.png</url><title>Dale John Dunlop</title><link>https://dalejohndunlop.com</link></image><item><title>Why Build a Zero Trust Home Server?</title><link>https://dalejohndunlop.com/blog/182/</link><guid isPermaLink="true">https://dalejohndunlop.com/blog/182/</guid><pubDate>Thu, 03 Apr 2025 22:06:12 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;In today&amp;#39;s digital landscape, running your own private infrastructure is becoming increasingly popular. With a simple Raspberry Pi, you can self-host your own media, files, ad blocker, automation workflows, and more right from home, while maintaining complete control over your data.&lt;/p&gt;
&lt;p&gt;This guide will help you understand how to set up a secure and accessible home server using zero trust principles, with no open ports on your home router.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;why-build-a-zero-trust-home-server&quot;&gt;Why Build a Zero Trust Home Server?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Complete Digital Privacy&lt;/strong&gt;: Keep your data local and away from big tech companies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Access services without opening ports on your router&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Centralised Control&lt;/strong&gt;: Host your own media, files, dashboards, and automation tools&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accessible From Anywhere&lt;/strong&gt;: Use secure tunnelling to access your services globally&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;what-you-can-self-host-securely&quot;&gt;What You Can Self-Host Securely&lt;/h2&gt;
&lt;p&gt;Here are some powerful services you can run on your Raspberry Pi:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;th&gt;Resource Requirements&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ad Blocking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AdGuard Home / Pi-hole&lt;/td&gt;
&lt;td&gt;Network-wide ad and tracker blocking&lt;/td&gt;
&lt;td&gt;Low: 100MB RAM, minimal CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zero Trust Access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tailscale / Cloudflare Tunnel&lt;/td&gt;
&lt;td&gt;Secure remote access without port forwarding&lt;/td&gt;
&lt;td&gt;Low: 200MB RAM, minimal CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Firewall &amp;amp; Protection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;UFW / Fail2Ban&lt;/td&gt;
&lt;td&gt;Secure your server from unwanted access&lt;/td&gt;
&lt;td&gt;Very Low: System level&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Media Streaming&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Jellyfin&lt;/td&gt;
&lt;td&gt;Host your own Netflix-like streaming platform&lt;/td&gt;
&lt;td&gt;Medium-High: 1-2GB RAM, moderate CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Personal Cloud Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nextcloud&lt;/td&gt;
&lt;td&gt;Self-hosted alternative to Dropbox/Google Drive&lt;/td&gt;
&lt;td&gt;Medium: 1-2GB RAM, moderate CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Smart Home&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Home Assistant&lt;/td&gt;
&lt;td&gt;Smart home automation hub&lt;/td&gt;
&lt;td&gt;Medium: 1GB RAM, moderate CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Service Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uptime Kuma&lt;/td&gt;
&lt;td&gt;Monitor your services&amp;#39; health&lt;/td&gt;
&lt;td&gt;Low: 200-500MB RAM, low CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Password Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vaultwarden&lt;/td&gt;
&lt;td&gt;Self-hosted Bitwarden-compatible password manager&lt;/td&gt;
&lt;td&gt;Low: 500MB RAM, minimal CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Portainer&lt;/td&gt;
&lt;td&gt;Graphical interface to manage Docker containers&lt;/td&gt;
&lt;td&gt;Low: 500MB RAM, minimal CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workflow Automation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;n8n&lt;/td&gt;
&lt;td&gt;Create powerful automation workflows&lt;/td&gt;
&lt;td&gt;Medium: 1GB RAM, moderate CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RSS Aggregator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FreshRSS&lt;/td&gt;
&lt;td&gt;Track news and updates from your favorite sites&lt;/td&gt;
&lt;td&gt;Low: 200MB RAM, minimal CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Document Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Paperless-ngx&lt;/td&gt;
&lt;td&gt;Scan, store, and search your documents&lt;/td&gt;
&lt;td&gt;Medium: 1GB RAM, moderate CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/homer_88ae207b36.png&quot;&gt;https://strapi.my-home-portal.com/uploads/homer_88ae207b36.png&lt;/a&gt;
&lt;em&gt;Example Homer dashboard showing various self-hosted services&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;real-world-performance-expectations-on-raspberry-pi-4-4gb&quot;&gt;Real-World Performance Expectations on Raspberry Pi 4 (4GB)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Jellyfin&lt;/strong&gt;: 1-2 direct play streams OR 1 1080p transcode&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nextcloud&lt;/strong&gt;: Comfortable file syncing for 3-5 users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AdGuard + Tailscale + Uptime Kuma&lt;/strong&gt;: Can run simultaneously with minimal impact&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage needs&lt;/strong&gt;: Start with 128GB SSD for OS + Docker, external HDD for media/backups&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;setting-up-your-raspberry-pi&quot;&gt;Setting Up Your Raspberry Pi&lt;/h2&gt;
&lt;h3 id=&quot;hardware-requirements&quot;&gt;Hardware Requirements&lt;/h3&gt;
&lt;p&gt;For a reliable zero trust home server, you&amp;#39;ll need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Raspberry Pi 4&lt;/strong&gt; (4GB or 8GB recommended)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;USB SSD&lt;/strong&gt; (128GB+ recommended) instead of microSD for reliability&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Official Power Supply&lt;/strong&gt; (3A for Pi 4)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Case with cooling&lt;/strong&gt; (like the Argon ONE M.2 or Flirc case)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ethernet connection&lt;/strong&gt; (strongly recommended for stability)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/PI_layout_fed29699e0.png&quot;&gt;https://strapi.my-home-portal.com/uploads/PI_layout_fed29699e0.png&lt;/a&gt;
&lt;em&gt;Raspberry Pi 4 with SSD and cooling case for optimal home server performance&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;step-1-install-raspberry-pi-os&quot;&gt;Step 1: Install Raspberry Pi OS&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Download and Install Raspberry Pi Imager:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visit the &lt;a href=&quot;https://www.raspberrypi.com/software/&quot;&gt;Raspberry Pi Software page&lt;/a&gt; and download for your OS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configure with Raspberry Pi Imager:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open the Raspberry Pi Imager application&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&amp;quot;Choose device&amp;quot;&lt;/strong&gt; and select your Raspberry Pi model&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&amp;quot;Choose OS&amp;quot;&lt;/strong&gt; and select &lt;strong&gt;Raspberry Pi OS Lite (64-bit)&lt;/strong&gt; for a headless server&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;&amp;quot;Choose storage&amp;quot;&lt;/strong&gt; and select your SSD (connected via USB adapter)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configure Advanced Options:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Press &lt;strong&gt;Ctrl+Shift+X&lt;/strong&gt; to open advanced options&lt;/li&gt;
&lt;li&gt;Set a hostname (e.g., &lt;code&gt;homeserver&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Enable SSH and configure an SSH key for passwordless login&lt;/li&gt;
&lt;li&gt;Configure your WiFi (if not using Ethernet)&lt;/li&gt;
&lt;li&gt;Set locale settings&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt; and then &lt;strong&gt;Write&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Insert the SSD into your Raspberry Pi and power it on&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;step-2-initial-configuration&quot;&gt;Step 2: Initial Configuration&lt;/h3&gt;
&lt;p&gt;Connect to your Raspberry Pi via SSH:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;ssh username@homeserver.local&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Update your system:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; apt update &amp;&amp; &lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; apt full-upgrade -y&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Set a static IP address (recommended):&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; nano /etc/dhcpcd.conf&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add these lines, customizing for your network:&lt;/p&gt;
&lt;pre data-language=&quot;&quot; class=&quot;code-wrapper&quot;&gt;
          &lt;code class=&quot;hljs language-&quot;&gt;interface eth0
static &lt;span class=&quot;hljs-attribute&quot;&gt;ip_address&lt;/span&gt;=192.168.1.100/24
static &lt;span class=&quot;hljs-attribute&quot;&gt;routers&lt;/span&gt;=192.168.1.1
static &lt;span class=&quot;hljs-attribute&quot;&gt;domain_name_servers&lt;/span&gt;=1.1.1.1 1.0.0.1&lt;/code&gt;
          &lt;div class=&quot;code-footer&quot;&gt;
            &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
              &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
              &lt;/svg&gt;
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/pre&gt;&lt;p&gt;Reboot to apply changes:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; reboot&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;step-3-security-hardening&quot;&gt;Step 3: Security Hardening&lt;/h3&gt;
&lt;h3 id=&quot;remove-password-authentication-for-ssh&quot;&gt;Remove Password Authentication for SSH&lt;/h3&gt;
&lt;p&gt;If you didn&amp;#39;t set up SSH keys during installation:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-comment&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;# On your &lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;local&lt;/span&gt;&lt;/span&gt; machine&lt;/span&gt;
ssh-keygen -t ed25519 -C &lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;your_email@example.com&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
ssh-copy-id username@your-pi-ip-address&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Then disable password authentication:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; nano /etc/ssh/sshd_config&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Find and modify these lines:&lt;/p&gt;
&lt;pre data-language=&quot;&quot; class=&quot;code-wrapper&quot;&gt;
          &lt;code class=&quot;hljs language-&quot;&gt;&lt;span class=&quot;hljs-attribute&quot;&gt;PasswordAuthentication&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;no&lt;/span&gt;
ChallengeResponseAuthentication &lt;span class=&quot;hljs-literal&quot;&gt;no&lt;/span&gt;
UsePAM &lt;span class=&quot;hljs-literal&quot;&gt;no&lt;/span&gt;&lt;/code&gt;
          &lt;div class=&quot;code-footer&quot;&gt;
            &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
              &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
              &lt;/svg&gt;
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/pre&gt;&lt;p&gt;Restart SSH service:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; systemctl restart sshd&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;set-up-basic-firewall&quot;&gt;Set Up Basic Firewall&lt;/h3&gt;
&lt;p&gt;Install and configure UFW:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; apt install ufw
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ufw default deny incoming
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ufw default allow outgoing
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ufw allow ssh
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ufw &lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;enable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;install-fail2ban-to-protect-from-brute-force-attacks&quot;&gt;Install Fail2Ban to Protect from Brute Force Attacks&lt;/h3&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; apt install fail2ban
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;cp&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; systemctl &lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;enable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; fail2ban
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; systemctl start fail2ban&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Configure a custom SSH jail:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; nano /etc/fail2ban/jail.local&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add/modify the SSH section:&lt;/p&gt;
&lt;pre data-language=&quot;&quot; class=&quot;code-wrapper&quot;&gt;
          &lt;code class=&quot;hljs language-&quot;&gt;&lt;span class=&quot;hljs-section&quot;&gt;[sshd]&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;enabled&lt;/span&gt; = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;port&lt;/span&gt; = ssh
&lt;span class=&quot;hljs-attr&quot;&gt;filter&lt;/span&gt; = sshd
&lt;span class=&quot;hljs-attr&quot;&gt;logpath&lt;/span&gt; = /var/log/auth.log
&lt;span class=&quot;hljs-attr&quot;&gt;maxretry&lt;/span&gt; = &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;hljs-attr&quot;&gt;bantime&lt;/span&gt; = &lt;span class=&quot;hljs-number&quot;&gt;86400&lt;/span&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;# 24 hours&lt;/span&gt;&lt;/code&gt;
          &lt;div class=&quot;code-footer&quot;&gt;
            &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
              &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
              &lt;/svg&gt;
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/pre&gt;&lt;p&gt;Restart Fail2Ban:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; systemctl restart fail2ban&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;hr&gt;
&lt;h2 id=&quot;setting-up-docker-and-portainer&quot;&gt;Setting Up Docker and Portainer&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/port_db6453290a.png&quot;&gt;https://strapi.my-home-portal.com/uploads/port_db6453290a.png&lt;/a&gt;
&lt;em&gt;Portainer dashboard showing running containers and resource usage&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docker allows you to run multiple services in isolated containers.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;install-docker-and-docker-compose&quot;&gt;Install Docker and Docker Compose&lt;/h3&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;curl -fsSL https://get.docker.com | sh
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; usermod -aG docker &lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-variable&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-variable&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-variable&quot;&gt;$USER&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; apt install -y docker-compose-plugin&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Log out and log back in for group changes to take effect:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-comment&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;# Reconnect via SSH&lt;/span&gt;&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;create-directory-structure&quot;&gt;Create Directory Structure&lt;/h3&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; -p ~/docker/{compose,configs,data}&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;install-portainer-for-docker-management&quot;&gt;Install Portainer for Docker Management&lt;/h3&gt;
&lt;p&gt;Create a docker-compose file for Portainer:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;nano ~/docker/compose/portainer.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add the following content:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &apos;3&apos;
services:
  portainer:
    container_name: portainer
    image: portainer/portainer-ce:latest
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ~/docker/data/portainer:/data
    ports:
      - 9000:9000&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Start Portainer:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/docker/compose
docker compose -f portainer.yml up -d&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;You can now access Portainer at &lt;code&gt;http://your-pi-ip:9000&lt;/code&gt; to set up your admin account.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;setting-up-adguard-home-in-detail&quot;&gt;Setting Up AdGuard Home In Detail&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/adgaurd_21ae0461fd.png&quot;&gt;https://strapi.my-home-portal.com/uploads/adgaurd_21ae0461fd.png&lt;/a&gt;
&lt;em&gt;AdGuard Home dashboard showing blocked requests and filtering statistics&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;AdGuard Home is a powerful network-wide ad blocker and DNS server. Here&amp;#39;s how to set it up and configure it properly.&lt;/p&gt;
&lt;h3 id=&quot;initial-setup&quot;&gt;Initial Setup&lt;/h3&gt;
&lt;p&gt;First Create and deploy the docker file&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &apos;3&apos;
services:
  # Network-wide ad blocking
  adguard:
    container_name: adguard
    image: adguard/adguardhome:latest
    restart: unless-stopped
    volumes:
      - ~/docker/configs/adguard:/opt/adguardhome/conf
      - ~/docker/data/adguard:/opt/adguardhome/work
    ports:
      - 3000:3000  # Admin Panel
      - 53:53/tcp  # DNS
      - 53:53/udp  # DNS
      - 784:784/udp # DNS-over-QUIC
      - 853:853/tcp # DNS-over-TLS
      - 443:443/udp # DNS-over-HTTPS
    cap_add:
      - NET_ADMIN
    networks:
      - home_network&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Then run the file and access it &lt;/p&gt;
&lt;pre data-language=&quot;&quot; class=&quot;code-wrapper&quot;&gt;
          &lt;code class=&quot;hljs language-&quot;&gt;&lt;span class=&quot;hljs-symbol&quot;&gt;http:&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;//your-pi-ip:3000&lt;/span&gt;&lt;/code&gt;
          &lt;div class=&quot;code-footer&quot;&gt;
            &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
              &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
              &lt;/svg&gt;
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/pre&gt;&lt;p&gt;Follow the setup wizard:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create an administrator account&lt;/li&gt;
&lt;li&gt;Configure network settings:&lt;ul&gt;
&lt;li&gt;Choose the interfaces to listen on (typically all)&lt;/li&gt;
&lt;li&gt;Keep default ports:&lt;ul&gt;
&lt;li&gt;DNS: 53&lt;/li&gt;
&lt;li&gt;Web interface: 3000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;common-dns-issues-and-fixes&quot;&gt;Common DNS Issues and Fixes&lt;/h3&gt;
&lt;p&gt;Before AdGuard can function correctly, make sure port 53 is available:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-comment&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;# Check &lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-keyword&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt;&lt;/span&gt; port 53 is &lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-keyword&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt;&lt;/span&gt; use&lt;/span&gt;
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; lsof -i :53&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;If systemd-resolved is using it, reconfigure it:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-comment&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;# Edit resolved configuration&lt;/span&gt;
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; nano /etc/systemd/resolved.conf&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add or modify these lines:&lt;/p&gt;
&lt;pre data-language=&quot;&quot; class=&quot;code-wrapper&quot;&gt;
          &lt;code class=&quot;hljs language-&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;DNSStubListener&lt;/span&gt;=&lt;span class=&quot;hljs-literal&quot;&gt;no&lt;/span&gt;&lt;/code&gt;
          &lt;div class=&quot;code-footer&quot;&gt;
            &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
              &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
              &lt;/svg&gt;
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/pre&gt;&lt;p&gt;Then restart the service:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; systemctl restart systemd-resolved&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;configuring-adguard-home&quot;&gt;Configuring AdGuard Home&lt;/h3&gt;
&lt;h3 id=&quot;1-dns-settings&quot;&gt;1. DNS Settings&lt;/h3&gt;
&lt;p&gt;In the AdGuard Home dashboard, go to &lt;strong&gt;Settings &amp;gt; DNS Settings&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set upstream DNS servers (recommended):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare: &lt;code&gt;1.1.1.1&lt;/code&gt; and &lt;code&gt;1.0.0.1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Quad9: &lt;code&gt;9.9.9.9&lt;/code&gt; and &lt;code&gt;149.112.112.112&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable DNS-over-HTTPS/TLS (for security)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable blocking of domains from filters&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2-filtering&quot;&gt;2. Filtering&lt;/h4&gt;
&lt;p&gt;Go to &lt;strong&gt;Filters &amp;gt; DNS blocklists&lt;/strong&gt; and add these recommended lists:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AdGuard DNS filter&lt;/li&gt;
&lt;li&gt;AdAway Default Blocklist&lt;/li&gt;
&lt;li&gt;Peter Lowe&amp;#39;s Ad and tracking server list&lt;/li&gt;
&lt;li&gt;Malicious URL Blocklist by Curben&lt;/li&gt;
&lt;li&gt;NoCoin Filter List&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-configuring-local-dns-records&quot;&gt;3. Configuring Local DNS Records&lt;/h4&gt;
&lt;p&gt;To use &lt;code&gt;.home.internal&lt;/code&gt; domain names for local services:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings &amp;gt; DNS rewrite&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add entries for each service:&lt;ul&gt;
&lt;li&gt;Domain name: &lt;code&gt;jellyfin.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Answer: &lt;code&gt;your-pi-ip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Repeat for other services&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;4-client-configuration&quot;&gt;4. Client Configuration&lt;/h4&gt;
&lt;p&gt;Set your router to use AdGuard as the DNS server:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Access your router&amp;#39;s admin interface&lt;/li&gt;
&lt;li&gt;Find DHCP/DNS settings&lt;/li&gt;
&lt;li&gt;Set primary DNS to your Raspberry Pi&amp;#39;s IP address&lt;/li&gt;
&lt;li&gt;Save changes&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alternatively, configure individual devices to use your Pi&amp;#39;s IP as their DNS server.&lt;/p&gt;
&lt;h4 id=&quot;5-security-features&quot;&gt;5. Security Features&lt;/h4&gt;
&lt;p&gt;Enable these additional security features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Safe Search&lt;/strong&gt;: Forces safe search on Google, Bing, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parental Control&lt;/strong&gt;: Optional content filtering&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Safe Browsing&lt;/strong&gt;: Blocks malicious domains&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;6-statistics-and-logs&quot;&gt;6. Statistics and Logs&lt;/h4&gt;
&lt;p&gt;AdGuard Home provides detailed statistics and logs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;View top blocked domains&lt;/li&gt;
&lt;li&gt;Check query logs for troubleshooting&lt;/li&gt;
&lt;li&gt;Monitor overall network activity&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;using-adguard-with-tailscale&quot;&gt;Using AdGuard with Tailscale&lt;/h3&gt;
&lt;p&gt;To use AdGuard as your DNS server while connected to Tailscale:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In Tailscale admin console, set a DNS nameserver:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;DNS &amp;gt; Nameservers&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add your Raspberry Pi&amp;#39;s Tailscale IP&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure split DNS (optional):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Tailscale admin, set up split DNS for &lt;code&gt;.home.internal&lt;/code&gt; domains&lt;/li&gt;
&lt;li&gt;This allows resolving local domains when away from home&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;setting-up-zero-trust-remote-access&quot;&gt;Setting Up Zero Trust Remote Access&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/jumpbox01_dfed666cdc.jpg&quot;&gt;https://strapi.my-home-portal.com/uploads/jumpbox01_dfed666cdc.jpg&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;method-1-tailscale---vpn-like-mesh-network&quot;&gt;Method 1: Tailscale - VPN-Like Mesh Network&lt;/h3&gt;
&lt;p&gt;Tailscale creates a secure mesh network between your devices without opening ports.&lt;/p&gt;
&lt;h3 id=&quot;install-tailscale&quot;&gt;Install Tailscale&lt;/h3&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;curl -fsSL https://tailscale.com/install.sh | sh
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; tailscale up&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Follow the authentication link to connect your Raspberry Pi to your Tailscale account.&lt;/p&gt;
&lt;h3 id=&quot;configure-tailscale-for-subnet-routing-optional&quot;&gt;Configure Tailscale for Subnet Routing (Optional)&lt;/h3&gt;
&lt;p&gt;To access other devices on your home network through Tailscale:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;sudo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; tailscale up --advertise-routes=192.168.1.0/24&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Go to the Tailscale admin console and approve the subnet routes.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-acls-and-policy&quot;&gt;Setting Up ACLs and Policy&lt;/h3&gt;
&lt;p&gt;For enhanced security, set up access control policies in the Tailscale admin panel.&lt;/p&gt;
&lt;p&gt;Example ACL policy:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;{
  &quot;acls&quot;: [
    {
      &quot;action&quot;: &quot;accept&quot;,
      &quot;users&quot;: [&quot;user@example.com&quot;],
      &quot;ports&quot;: [&quot;*:*&quot;]
    }
  ]
}&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;method-2-cloudflare-tunnel-with-docker-compose&quot;&gt;Method 2: Cloudflare Tunnel with Docker Compose&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/cloudflare_d4e7776782.png&quot;&gt;https://strapi.my-home-portal.com/uploads/cloudflare_d4e7776782.png&lt;/a&gt;
&lt;em&gt;Diagram showing how Cloudflare Tunnel provide secure remote access&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Cloudflare Tunnel lets you expose services using a custom domain without opening ports. Running it in Docker keeps everything neatly containerized.&lt;/p&gt;
&lt;h4 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Registered domain on Cloudflare&lt;/li&gt;
&lt;li&gt;Cloudflare account&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;setting-up-cloudflare-tunnel-via-web-ui-docker-compose&quot;&gt;Setting Up Cloudflare Tunnel via Web UI Docker Compose&lt;/h3&gt;
&lt;p&gt;The Cloudflare Tunnel can also be set up directly from the Cloudflare Zero Trust dashboard, which many users find more convenient:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log in to your Cloudflare account and navigate to &lt;strong&gt;Zero Trust&lt;/strong&gt; &amp;gt; &lt;strong&gt;Access&lt;/strong&gt; &amp;gt; &lt;strong&gt;Tunnels&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create a tunnel&lt;/strong&gt; and give it a name (e.g., &amp;quot;Home Server&amp;quot;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You&amp;#39;ll be provided with a tunnel token. Create a docker-compose file for Cloudflare:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;nano ~/docker/compose/cloudflare.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add the following content:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &quot;3.8&quot;
services:
  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    environment:
      - LOG_LEVEL=info
      - CAPTCHA_SOLVER=none
    ports:
      - 8191:8191
    restart: unless-stopped&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Start the Cloudflare tunnel:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/docker/compose
docker compose -f cloudflare.yml up -d&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;&lt;p&gt;Back in the Cloudflare dashboard, you&amp;#39;ll be asked to configure public hostnames:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Add a public hostname&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enter the subdomain and domain (e.g., jellyfin.yourdomain.com)&lt;/li&gt;
&lt;li&gt;For service, select &amp;quot;HTTP&amp;quot; and enter the local service address and port (e.g., jellyfin:8096)&lt;/li&gt;
&lt;li&gt;Repeat for each service you want to expose&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optional: Add authentication&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the Cloudflare dashboard, under the &amp;quot;Public Hostname&amp;quot; settings, you can enable &amp;quot;Zero Trust Policy&amp;quot;&lt;/li&gt;
&lt;li&gt;Configure authentication methods (Google, GitHub, email one-time passwords, etc.)&lt;/li&gt;
&lt;li&gt;Set up custom policies for who can access each service&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&quot;setting-up-essential-self-hosted-services&quot;&gt;Setting Up Essential Self-Hosted Services&lt;/h2&gt;
&lt;h3 id=&quot;create-a-complete-docker-compose-stack&quot;&gt;Create a Complete Docker Compose Stack&lt;/h3&gt;
&lt;p&gt;Create a new docker-compose file:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;nano ~/docker/compose/services.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add the following content:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &apos;3&apos;
services:
  # Network-wide ad blocking
  adguard:
    container_name: adguard
    image: adguard/adguardhome:latest
    restart: unless-stopped
    volumes:
      - ~/docker/configs/adguard:/opt/adguardhome/conf
      - ~/docker/data/adguard:/opt/adguardhome/work
    ports:
      - 3000:3000  # Admin Panel
      - 53:53/tcp  # DNS
      - 53:53/udp  # DNS
      - 784:784/udp # DNS-over-QUIC
      - 853:853/tcp # DNS-over-TLS
      - 443:443/udp # DNS-over-HTTPS
    cap_add:
      - NET_ADMIN
    networks:
      - home_network

  # Service monitoring
  uptime-kuma:
    container_name: uptime-kuma
    image: louislam/uptime-kuma:latest
    restart: unless-stopped
    volumes:
      - ~/docker/data/uptime-kuma:/app/data
    ports:
      - 3001:3001
    networks:
      - home_network
  
  # Media server
  jellyfin:
    container_name: jellyfin
    image: jellyfin/jellyfin:latest
    restart: unless-stopped
    volumes:
      - ~/docker/configs/jellyfin:/config
      - /mnt/media:/media
    ports:
      - 8096:8096
    networks:
      - home_network
    environment:
      - JELLYFIN_PublishedServerUrl=jellyfin.yourdomain.com

  # Personal cloud storage
  nextcloud:
    container_name: nextcloud
    image: nextcloud:latest
    restart: unless-stopped
    volumes:
      - ~/docker/data/nextcloud:/var/www/html
    ports:
      - 8080:80
    depends_on:
      - nextcloud-db
    networks:
      - home_network
    environment:
      - MYSQL_HOST=nextcloud-db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=secure_password_here

  # Database for Nextcloud
  nextcloud-db:
    container_name: nextcloud-db
    image: mariadb:latest
    restart: unless-stopped
    volumes:
      - ~/docker/data/nextcloud-db:/var/lib/mysql
    networks:
      - home_network
    environment:
      - MYSQL_ROOT_PASSWORD=very_secure_root_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=secure_password_here
      
  # Workflow automation
  n8n:
    container_name: n8n
    image: n8nio/n8n:latest
    restart: unless-stopped
    ports:
      - 5678:5678
    volumes:
      - ~/docker/data/n8n:/home/node/.n8n
    networks:
      - home_network
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=secure_password_here

  # Password manager
  vaultwarden:
    container_name: vaultwarden
    image: vaultwarden/server:latest
    restart: unless-stopped
    volumes:
      - ~/docker/data/vaultwarden:/data
    ports:
      - 8081:80
    networks:
      - home_network

networks:
  home_network:
    driver: bridge&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Start all services:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/docker/compose
docker compose -f services.yml up -d&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;setting-up-a-homer-dashboard&quot;&gt;Setting Up a Homer Dashboard&lt;/h3&gt;
&lt;p&gt;Homer provides a clean, customizable dashboard for all your self-hosted services.&lt;/p&gt;
&lt;p&gt;Create a docker-compose file for Homer:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;nano ~/docker/compose/homer.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add the following content:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &apos;3&apos;
services:
  homer:
    container_name: homer
    image: b4bz/homer:latest
    restart: unless-stopped
    volumes:
      - ~/docker/configs/homer:/www/assets
    ports:
      - 8082:8080
    networks:
      - home_network

networks:
  home_network:
    external: true&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Start Homer:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/docker/compose
docker compose -f homer.yml up -d&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Create a basic configuration:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; -p ~/docker/configs/homer
nano ~/docker/configs/homer/config.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add this sample configuration:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;title: &quot;Home Server Dashboard&quot;
subtitle: &quot;Your Self-Hosted Services&quot;
logo: &quot;assets/icons/logo.png&quot;
header: true
footer: &apos;&lt;p&gt;Created with &lt;span class=&quot;has-text-danger&quot;&gt;❤️&lt;/span&gt; with Homer&lt;/p&gt;&apos;

# Links to services
services:
  - name: &quot;Media&quot;
    icon: &quot;fas fa-play-circle&quot;
    items:
      - name: &quot;Jellyfin&quot;
        logo: &quot;assets/icons/jellyfin.png&quot;
        subtitle: &quot;Media Server&quot;
        tag: &quot;media&quot;
        url: &quot;http://jellyfin.home.internal&quot;
        target: &quot;_blank&quot;
  
  - name: &quot;Storage&quot;
    icon: &quot;fas fa-database&quot;
    items:
      - name: &quot;Nextcloud&quot;
        logo: &quot;assets/icons/nextcloud.png&quot;
        subtitle: &quot;File Storage&quot;
        tag: &quot;storage&quot;
        url: &quot;http://nextcloud.home.internal&quot;
        target: &quot;_blank&quot;
  
  - name: &quot;System&quot;
    icon: &quot;fas fa-cogs&quot;
    items:
      - name: &quot;Portainer&quot;
        logo: &quot;assets/icons/portainer.png&quot;
        subtitle: &quot;Docker Management&quot;
        tag: &quot;system&quot;
        url: &quot;http://portainer.home.internal&quot;
        target: &quot;_blank&quot;
      - name: &quot;AdGuard Home&quot;
        logo: &quot;assets/icons/adguard.png&quot;
        subtitle: &quot;Ad Blocking&quot;
        tag: &quot;system&quot;
        url: &quot;http://adguard.home.internal&quot;
        target: &quot;_blank&quot;
  
  - name: &quot;Automation&quot;
    icon: &quot;fas fa-robot&quot;
    items:
      - name: &quot;n8n&quot;
        logo: &quot;assets/icons/n8n.png&quot;
        subtitle: &quot;Workflow Automation&quot;
        tag: &quot;automation&quot;
        url: &quot;http://n8n.home.internal&quot;
        target: &quot;_blank&quot;&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Create a directory for custom icons:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; -p ~/docker/configs/homer/icons&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;You can download icons for your services and place them in this directory.&lt;/p&gt;
&lt;h3 id=&quot;setting-up-nginx-proxy-manager-for-local-domain-names&quot;&gt;Setting Up Nginx Proxy Manager for Local Domain Names&lt;/h3&gt;
&lt;p&gt;To access your services with nice local URLs like &lt;code&gt;portainer.home.internal&lt;/code&gt;:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;nano ~/docker/compose/nginx-proxy.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Add the following content:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &apos;3&apos;
services:
  nginx-proxy-manager:
    container_name: nginx-proxy-manager
    image: &apos;jc21/nginx-proxy-manager:latest&apos;
    restart: unless-stopped
    ports:
      - &apos;80:80&apos;
      - &apos;443:443&apos;
      - &apos;81:81&apos;
    volumes:
      - ~/docker/data/nginx-proxy-manager/data:/data
      - ~/docker/data/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
    networks:
      - home_network

networks:
  home_network:
    external: true&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Start Nginx Proxy Manager:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/docker/compose
docker compose -f nginx-proxy.yml up -d&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Access the admin interface at &lt;code&gt;http://your-pi-ip:81&lt;/code&gt; and set up proxy hosts for each service.&lt;/p&gt;
&lt;p&gt;For each service, add a proxy host with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Domain name: &lt;code&gt;service.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Forward hostname/IP: The container name or IP&lt;/li&gt;
&lt;li&gt;Forward port: The internal port of the service&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To use &lt;code&gt;.home.internal&lt;/code&gt; domains on your devices, either:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add entries to your hosts file on each device&lt;/li&gt;
&lt;li&gt;Configure AdGuard Home to handle local DNS resolution (recommended)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;accessing-your-services&quot;&gt;Accessing Your Services&lt;/h3&gt;
&lt;h3 id=&quot;on-your-local-network&quot;&gt;On Your Local Network&lt;/h3&gt;
&lt;p&gt;Using nice local domain names:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Homer Dashboard: &lt;code&gt;http://homer.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Portainer: &lt;code&gt;http://portainer.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Jellyfin: &lt;code&gt;http://jellyfin.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nextcloud: &lt;code&gt;http://nextcloud.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;n8n: &lt;code&gt;http://n8n.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;AdGuard Home: &lt;code&gt;http://adguard.home.internal&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Or using IP address:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Homer Dashboard: &lt;code&gt;http://your-pi-ip:8082&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Portainer: &lt;code&gt;http://your-pi-ip:9000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Jellyfin: &lt;code&gt;http://your-pi-ip:8096&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nextcloud: &lt;code&gt;http://your-pi-ip:8080&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;n8n: &lt;code&gt;http://your-pi-ip:5678&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;AdGuard Home: &lt;code&gt;http://your-pi-ip:3000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;remote-access-with-tailscale&quot;&gt;Remote Access with Tailscale&lt;/h3&gt;
&lt;p&gt;When away from home, connect to Tailscale and access services using the same local domain names or IP addresses.&lt;/p&gt;
&lt;h3 id=&quot;remote-access-with-cloudflare-tunnel&quot;&gt;Remote Access with Cloudflare Tunnel&lt;/h3&gt;
&lt;p&gt;Access through your custom domains from anywhere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jellyfin: &lt;code&gt;https://jellyfin.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Portainer: &lt;code&gt;https://portainer.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Nextcloud: &lt;code&gt;https://nextcloud.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;n8n: &lt;code&gt;https://n8n.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Homer Dashboard: &lt;code&gt;https://homer.yourdomain.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;advanced-security-enhancements&quot;&gt;Advanced Security Enhancements&lt;/h2&gt;
&lt;h3 id=&quot;set-up-service-specific-networks&quot;&gt;Set Up Service-Specific Networks&lt;/h3&gt;
&lt;p&gt;Modify your docker-compose file to use specific networks for different types of services:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;networks:
  frontend_network:
    driver: bridge
  backend_network:
    driver: bridge
  database_network:
    driver: bridge&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Then assign services to appropriate networks:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;jellyfin:
  networks:
    - frontend_network
    
nextcloud:
  networks:
    - frontend_network
    - backend_network
    
nextcloud-db:
  networks:
    - database_network
    - backend_network&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;container-hardening&quot;&gt;Container Hardening&lt;/h3&gt;
&lt;p&gt;Add security constraints to your containers:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;yourservice:
  security_opt:
    - no-new-privileges:true
  read_only: true
  tmpfs:
    - /tmp
  restart: unless-stopped&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;implement-traefik-as-a-reverse-proxy-optional&quot;&gt;Implement Traefik as a Reverse Proxy (Optional)&lt;/h3&gt;
&lt;p&gt;For more advanced configurations, implement Traefik to handle routing and SSL:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;traefik:
  container_name: traefik
  image: traefik:latest
  restart: unless-stopped
  ports:
    - 80:80
    - 443:443
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro
    - ~/docker/configs/traefik:/etc/traefik
  command:
    - --providers.docker=true
    - --providers.docker.exposedbydefault=false
    - --entrypoints.web.address=:80
    - --entrypoints.websecure.address=:443
    - --certificatesresolvers.myresolver.acme.tlschallenge=true
    - --certificatesresolvers.myresolver.acme.email=your@email.com
    - --certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme.json&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;hr&gt;
&lt;h2 id=&quot;troubleshooting-common-issues&quot;&gt;Troubleshooting Common Issues&lt;/h2&gt;
&lt;h3 id=&quot;network-connectivity-issues&quot;&gt;Network Connectivity Issues&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Possible Solutions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Can&amp;#39;t SSH into server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check IP address is correct&lt;br&gt;• Verify hostname resolution works&lt;br&gt;• Ensure SSH service is running&lt;br&gt;• Check firewall settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Can&amp;#39;t access web UIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Verify correct ports are open in UFW&lt;br&gt;• Check Docker container is running&lt;br&gt;• Ensure service is bound to correct network interface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DNS not working with AdGuard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check port 53 is not in use by systemd-resolved&lt;br&gt;• Verify network configuration points to AdGuard&lt;br&gt;• Check AdGuard logs for errors&lt;br&gt;• Try &lt;code&gt;sudo systemctl stop systemd-resolved&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;docker-issues&quot;&gt;Docker Issues&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Possible Solutions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container won&amp;#39;t start&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check logs: &lt;code&gt;docker logs container_name&lt;/code&gt;&lt;br&gt;• Verify port conflicts: &lt;code&gt;netstat -tulpn&lt;/code&gt;&lt;br&gt;• Check volume permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Permission errors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check UID/GID mappings&lt;br&gt;• Fix permissions: &lt;code&gt;chown -R user:group /path/to/volume&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resource limitations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check resource usage: &lt;code&gt;docker stats&lt;/code&gt;&lt;br&gt;• Add memory limits to containers&lt;br&gt;• Monitor with &lt;code&gt;htop&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;cloudflare-tunnel-issues&quot;&gt;Cloudflare Tunnel Issues&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Possible Solutions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tunnel not connecting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check cloudflared logs: &lt;code&gt;sudo journalctl -u cloudflared&lt;/code&gt;&lt;br&gt;• Verify credentials file exists&lt;br&gt;• Ensure tunnel ID matches in config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cannot access services&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Check DNS records in Cloudflare dashboard&lt;br&gt;• Verify service is running on specified port&lt;br&gt;• Ensure your Access policies are configured correctly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;maintenance-checklist&quot;&gt;Maintenance Checklist&lt;/h2&gt;
&lt;p&gt;To keep your home server running smoothly, perform these maintenance tasks regularly:&lt;/p&gt;
&lt;h3 id=&quot;weekly-tasks&quot;&gt;Weekly Tasks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Check disk space: &lt;code&gt;df -h&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Update containers: &lt;code&gt;docker compose pull &amp;amp;&amp;amp; docker compose up -d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Review logs for errors: &lt;code&gt;docker logs --since 24h container_name&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;monthly-tasks&quot;&gt;Monthly Tasks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Update host OS: &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Check for unused containers/images: &lt;code&gt;docker system prune&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Review backup integrity&lt;/li&gt;
&lt;li&gt;Check UPS battery status (if applicable)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quarterly-tasks&quot;&gt;Quarterly Tasks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Change passwords for critical services&lt;/li&gt;
&lt;li&gt;Review port forwarding/firewall rules&lt;/li&gt;
&lt;li&gt;Check hardware (dust, connections, etc.)&lt;/li&gt;
&lt;li&gt;Update documentation of your setup&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;community-resources&quot;&gt;Community Resources&lt;/h2&gt;
&lt;p&gt;Get help and inspiration from these community resources:&lt;/p&gt;
&lt;h3 id=&quot;forums--communities&quot;&gt;Forums &amp;amp; Communities&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/selfhosted/&quot;&gt;r/selfhosted&lt;/a&gt; - Reddit&amp;#39;s self-hosting community&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/homelab/&quot;&gt;r/homelab&lt;/a&gt; - More advanced home server setups&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://community.home-assistant.io/&quot;&gt;Home Assistant Community&lt;/a&gt; - Smart home focused&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forum.jellyfin.org/&quot;&gt;Jellyfin Forums&lt;/a&gt; - Media server discussions&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.truenas.com/community/&quot;&gt;TrueNAS Forum&lt;/a&gt; - Storage-focused discussions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;discord-servers&quot;&gt;Discord Servers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://discord.gg/homelab&quot;&gt;Homelab&lt;/a&gt; - Home lab discussions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;youtube-channels&quot;&gt;YouTube Channels&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/TechnoTimLive&quot;&gt;TechnoTim&lt;/a&gt; - Great server tutorials&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/DBTechYT&quot;&gt;DB Tech&lt;/a&gt; - Docker-focused tutorials&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/TheDigitalLifeTech&quot;&gt;The Digital Life&lt;/a&gt; - Self-hosting guides&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;whats-next&quot;&gt;What&amp;#39;s Next?&lt;/h2&gt;
&lt;p&gt;You now have a solid foundation for running your own secure &lt;strong&gt;private cloud&lt;/strong&gt; using zero trust principles. &lt;/p&gt;
&lt;p&gt;Here are some advanced projects to tackle next:&lt;/p&gt;
&lt;h3 id=&quot;advanced-projects&quot;&gt;Advanced Projects&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automated Backups&lt;/strong&gt;: Set up Restic or Duplicati to automatically backup important data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Analytics&lt;/strong&gt;: Monitor your network with InfluxDB + Grafana for beautiful dashboards&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Home Automation&lt;/strong&gt;: Connect Home Assistant to your lights, sensors, and more&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD Pipeline&lt;/strong&gt;: Set up Gitea + Drone CI for your personal development projects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extended Storage&lt;/strong&gt;: Build a proper NAS with TrueNAS or Unraid&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Your zero trust home server is more than just a tech project—it&amp;#39;s a statement about data ownership and privacy. With Cloudflare Tunnel and Tailscale, you can access your services securely from anywhere without compromising your home network security.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Last updated: April 2025&lt;/em&gt;&lt;/p&gt;
]]&gt;</content:encoded><language>en-us</language><category>Technology</category><category>Security</category></item><item><title>Hello World : Family Edition</title><link>https://dalejohndunlop.com/blog/99/</link><guid isPermaLink="true">https://dalejohndunlop.com/blog/99/</guid><pubDate>Sat, 29 Mar 2025 19:22:29 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h2 id=&quot;hello-world--family-edition&quot;&gt;Hello World : Family Edition&lt;/h2&gt;
&lt;p&gt;I&amp;#39;ve always been into tinkering with tech and problem-solving, but actually diving deep into developing didn&amp;#39;t happen until recently. The real push came from a personal project: setting up my own home server. I wanted to build and host my own microservices for all sorts of tasks — media management for our family photos and videos, a central logging solution to keep track of events on our network, some automation tools to streamline home chores — and even create my own website. To make all that happen, I realized I needed to sharpen my coding skills (and learn a bunch about servers too!). Setting up that home server was both exciting and intimidating. I found myself learning everything from basic Linux commands to a bit of networking. I use Portainer (its all containerised with Docker) to manage those microservices. There were moments I felt stuck or overwhelmed, especially when a configuration wouldn&amp;#39;t work or a service wouldn&amp;#39;t talk to another. But each time I solved a problem, it was incredibly rewarding. That little home server became my coding playground and the spark that ignited my programming journey.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The most challenging bugs I solve aren&amp;#39;t in my code - it&amp;#39;s figuring out how to balance my passion for building and learning with family life. Both need debugging.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;what-my-day-looks-like&quot;&gt;What my day looks like&lt;/h2&gt;
&lt;p&gt;So how do I actually squeeze coding into a busy day with two kids? It definitely takes planning, flexibility, and a good sense of humour. Here&amp;#39;s what a typical day might look like for me:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Early Morning:&lt;/strong&gt; I try to wake up before the kids do to grab a quick coding session (or at least read about code) while sipping my first cup of coffee. This quiet time doesn&amp;#39;t always happen—sometimes I hit snooze, or one of the kids decides 6 AM is playtime—but when it does, it gives me a head start on the day and a little personal victory right off the bat.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Daytime:&lt;/strong&gt; Once the kids are awake, the house bursts into activity. From making breakfast and doing school drop-offs to focusing on my day job (and countless snack requests in between), my coding brain goes on standby during these hours. If I&amp;#39;m lucky and the stars align (hello, nap time or a generous screen-time break), I might steal a few minutes to brainstorm a feature or jot down a solution that popped into my head. But generally, daylight hours are family and work first, dev later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Evening:&lt;/strong&gt; After dinner, it&amp;#39;s family time and the kids&amp;#39; bedtime routine. Storybooks, bath time, and goodnight hugs come first—code can wait. By the time the little ones are tucked in, I&amp;#39;m usually pretty tired. Some nights, I&amp;#39;ll admit, I collapse on the couch and my plans get pushed aside. Other nights, though, I&amp;#39;m still excited about what I&amp;#39;m building, and that excitement gives me a second wind.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Late Night (Building Time):&lt;/strong&gt; This is when I dive into code. The house is finally quiet, and I can truly concentrate. I often spend an hour or two writing code, debugging a tricky issue, or learning something new online. It&amp;#39;s my dedicated me-time to immerse myself in programming. I do have to be careful not to lose track of time—those early school mornings come around fast, and more than once I&amp;#39;ve looked up to see it&amp;#39;s past midnight!&lt;/p&gt;
&lt;h2 id=&quot;my-computer-setup&quot;&gt;My Computer Setup&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/setup_1_8e8e10f223.jpeg&quot;&gt;https://strapi.my-home-portal.com/uploads/setup_1_8e8e10f223.jpeg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;My main workspace where I spend most of my time&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/setup_2_59a96ea7ab.jpeg&quot;&gt;https://strapi.my-home-portal.com/uploads/setup_2_59a96ea7ab.jpeg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I&amp;#39;ve got a small home office setup—nothing too fancy, but it&amp;#39;s my space.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;how-i-stay-motivated&quot;&gt;How I Stay Motivated&lt;/h2&gt;
&lt;p&gt;Some days, sitting down to code feels impossible. I&amp;#39;ll finally get a quiet moment, open my laptop, and then… my brain just refuses to function. It&amp;#39;s frustrating, but I&amp;#39;ve learned that motivation isn&amp;#39;t about feeling inspired every day—it&amp;#39;s about showing up, even when it&amp;#39;s hard.&lt;/p&gt;
&lt;p&gt;Here are a few things that keep me going:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Building things I actually use. Every project I work on serves a real purpose in my home—whether it&amp;#39;s automating tasks, improving security, or just making life a little easier.&lt;/li&gt;
&lt;li&gt;Small wins. Even if I can only fix one bug or add one new feature, that&amp;#39;s still progress. And progress, no matter how small, keeps me moving forward.&lt;/li&gt;
&lt;li&gt;Community &amp;amp; learning. I stay connected with other tech enthusiasts through forums, blogs, and Discord groups. Seeing what others are building inspires me to keep pushing my own skills further.&lt;/li&gt;
&lt;li&gt;Taking breaks. When I feel stuck, I step away. A quick gaming session or even just a walk outside helps reset my mind so I can come back with fresh energy.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;little-features-with-big-meaning&quot;&gt;Little Features with Big Meaning&lt;/h2&gt;
&lt;p&gt;One of my favourite small projects was a simple color picker I built for my website. Originally, it was just for me—I wanted to play around with CSS variables and theming. But one day, my four-year-old saw me working on it and said, &amp;quot;Aw, Daddy, I want it to be pink!&amp;quot;&lt;/p&gt;
&lt;p&gt;Instead of just setting it to pink, I thought, why not let visitors pick their own colors?&lt;/p&gt;
&lt;p&gt;What made this project special:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It made my daughter feel like she was part of it.&lt;/li&gt;
&lt;li&gt;I got hands-on experience with dynamic theming in CSS.&lt;/li&gt;
&lt;li&gt;It added a fun, interactive touch to my site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, every time she watches me work on my site, she clicks through the colors, &amp;quot;helping&amp;quot; me pick a new theme. It&amp;#39;s a small, simple feature—but it reminds me why I love coding.&lt;/p&gt;
&lt;h2 id=&quot;current-projects&quot;&gt;Current Projects&lt;/h2&gt;
&lt;p&gt;I always have a few projects on the go, but right now, I&amp;#39;m focused on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rebuilding my Cloudflare homepage, I want it to be cleaner, faster, and easier to manage.&lt;/li&gt;
&lt;li&gt;Improving my home server automation, Automating more tasks so I can spend less time maintaining things and more time building.&lt;/li&gt;
&lt;li&gt;Learning n8n.io for workflows, Automating integrations between services I use, like pulling logs from my home server and sending alerts to Telegram.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/website_0bada8f35d.png&quot;&gt;https://strapi.my-home-portal.com/uploads/website_0bada8f35d.png&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;My personal website - built using Bootstrap framework and AI assistance through Cursor IDE&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;tools-i-use&quot;&gt;Tools I Use&lt;/h2&gt;
&lt;p&gt;Every coder has their favourite tools—here are mine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT &amp;amp; Cursor IDE – AI-assisted coding has been a game-changer for learning and debugging.&lt;/li&gt;
&lt;li&gt;Daily.dev – My go-to source for developer news.&lt;/li&gt;
&lt;li&gt;Docker &amp;amp; Kubernetes – Managing microservices on my home server efficiently.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;biggest-challenges&quot;&gt;Biggest Challenges&lt;/h2&gt;
&lt;p&gt;The hardest part isn&amp;#39;t the coding—it&amp;#39;s the constant context switching.&lt;/p&gt;
&lt;p&gt;One moment, I&amp;#39;m troubleshooting a broken API on my home server, and the next, I&amp;#39;m making dinner or looking for a missing toy. Just when I get into deep focus mode, I might hear a shout from the other room: &amp;quot;Dad! I need help!&amp;quot;&lt;/p&gt;
&lt;p&gt;Then there&amp;#39;s the guilt. When I&amp;#39;m coding, I feel like I should be spending more time with the kids. When I&amp;#39;m with the kids, I&amp;#39;m thinking about the project I want to finish. It&amp;#39;s a constant balancing act, and I haven&amp;#39;t mastered it yet. But I&amp;#39;m working on it.&lt;/p&gt;
&lt;h2 id=&quot;whats-next&quot;&gt;What&amp;#39;s Next?&lt;/h2&gt;
&lt;p&gt;I&amp;#39;m taking it one step at a time. My goal isn&amp;#39;t to become a developer overnight—that&amp;#39;s just not realistic with family life. Instead, I&amp;#39;m focusing on steady progress.&lt;/p&gt;
&lt;p&gt;One day, I&amp;#39;d love to build something useful, especially in security, but I also want to make sure it&amp;#39;s fun to work on. After all, if I don&amp;#39;t enjoy the journey, what&amp;#39;s the point?&lt;/p&gt;
&lt;h3 id=&quot;want-to-share-your-story&quot;&gt;Want to Share Your Story?&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;If you&amp;#39;re also balancing coding and family life, I&amp;#39;d love to hear your story. How do you make it work?&lt;/em&gt;&lt;/p&gt;
]]&gt;</content:encoded><language>en-us</language><category>Technology</category><category>Security</category></item><item><title>Automating Your Home with n8n</title><link>https://dalejohndunlop.com/blog/97/</link><guid isPermaLink="true">https://dalejohndunlop.com/blog/97/</guid><pubDate>Sat, 29 Mar 2025 19:17:41 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;automating-your-home-with-n8n&quot;&gt;Automating Your Home with n8n&lt;/h1&gt;
&lt;p&gt;I&amp;#39;ve been exploring different ways to streamline my home server setup, and one tool that&amp;#39;s been a game-changer is n8n. If you&amp;#39;re like me—juggling family life while trying to optimise your home tech—this might be exactly what you need.&lt;/p&gt;
&lt;h2 id=&quot;what-is-n8n&quot;&gt;What is n8n?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://n8n.io/&quot;&gt;n8n&lt;/a&gt;  is a workflow automation tool. Think of it as the glue that connects different services and applications. It&amp;#39;s similar to tools like Zapier or Make but with one massive advantage: you can self-host it.&lt;/p&gt;
&lt;p&gt;This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your data stays on your own server&lt;/li&gt;
&lt;li&gt;No monthly subscription fees&lt;/li&gt;
&lt;li&gt;Complete control over your workflows&lt;/li&gt;
&lt;li&gt;The ability to connect to local services on your network&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For into home automation, these benefits are huge. I can create workflows that connect my home server alerts to my phone, automate file backups for family photos.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/intergrations_e3dda931cd.png&quot;&gt;https://strapi.my-home-portal.com/uploads/intergrations_e3dda931cd.png&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The ability to connect different services without relying on cloud providers gives me peace of mind about where our family data is stored and processed.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;why-i-chose-to-self-host-n8n&quot;&gt;Why I Chose to Self-Host n8n&lt;/h2&gt;
&lt;p&gt;There are plenty of automation services out there, but most require you to send your data through their servers. As someone who values control over my infrastructure, I prefer keeping things local when possible.&lt;/p&gt;
&lt;p&gt;Self-hosting n8n gives me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complete data ownership and privacy&lt;/li&gt;
&lt;li&gt;Integration with my other self-hosted services&lt;/li&gt;
&lt;li&gt;A chance to tinker and learn (during those precious late-night coding sessions)&lt;/li&gt;
&lt;li&gt;No limits on the number of workflows I can create&lt;/li&gt;
&lt;li&gt;Freedom from subscription fees&lt;/li&gt;
&lt;li&gt;The ability to customize and extend as needed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The self-hosted approach fits perfectly with my home server philosophy: why pay for a service when you can run it yourself and learn something in the process?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/cover_a4acfe1747.png&quot;&gt;https://strapi.my-home-portal.com/uploads/cover_a4acfe1747.png&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;setting-up-n8n-with-docker-compose&quot;&gt;Setting Up n8n with Docker Compose&lt;/h1&gt;
&lt;p&gt;Let me walk you through how I set up n8n on my home server. It&amp;#39;s surprisingly straightforward, especially if you&amp;#39;re already using Docker.&lt;/p&gt;
&lt;p&gt;Prerequisites&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A server running Docker and Docker Compose&lt;/li&gt;
&lt;li&gt;Basic understanding of networking (nothing too complex)&lt;/li&gt;
&lt;li&gt;A few minutes of quiet time (the hardest part to find!)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-1-create-your-docker-compose-file&quot;&gt;Step 1: Create Your Docker Compose File&lt;/h3&gt;
&lt;p&gt;First, create a new directory for your n8n configuration:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/n8n
&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; ~/n8n&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Then, create a docker-compose.yml file:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;nano docker-compose.yml&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;Copy and paste this configuration:&lt;/p&gt;
&lt;pre data-language=&quot;yaml&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-yaml&quot;&gt;version: &quot;3&quot;
services:
  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - 5678:5678
    environment:
      - N8N_SECURE_COOKIE=false
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=YourUsername
      - N8N_BASIC_AUTH_PASSWORD=YourStrongPassword
      - WEBHOOK_URL=https://your-cloudflare-tunnel-url.com
    volumes:
      - ~/Documents/n8n/n8n_data:/home/node/.n8n
    networks:
      - my_custom_network

networks:
  my_custom_network:
    external: true&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;step-2-customize-your-configuration&quot;&gt;Step 2: Customize Your Configuration&lt;/h3&gt;
&lt;p&gt;Here&amp;#39;s what each part of the configuration does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;image: n8nio/n8n:latest&lt;/strong&gt; - Uses the latest version of n8n&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;restart: unless-stopped&lt;/strong&gt; - Makes sure n8n starts after a reboot&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ports: - &amp;quot;5678:5678&amp;quot;&lt;/strong&gt; - The default port for n8n&amp;#39;s web interface&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;N8N_BASIC_AUTH_ACTIVE&lt;/strong&gt; - Enables password protection&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;N8N_BASIC_AUTH_USER&lt;/strong&gt; and &lt;strong&gt;N8N_BASIC_AUTH_PASSWORD&lt;/strong&gt; - Your login credentials&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WEBHOOK_URL&lt;/strong&gt; - If you&amp;#39;re using Cloudflare Tunnel to access n8n remotely, set this to your tunnel URL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;volumes&lt;/strong&gt; - Maps a local folder to store your workflows and data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;networks&lt;/strong&gt; - Connects to your existing Docker network (if you have one)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Make sure to replace&lt;/em&gt; &lt;strong&gt;YourUsername&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;YourStrongPassword&lt;/strong&gt; &lt;em&gt;with actual values. This is especially important if you plan to access n8n from outside your home network.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;step-3-create-the-data-directory&quot;&gt;Step 3: Create the Data Directory&lt;/h3&gt;
&lt;p&gt;Before starting the container, create the data directory:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;&lt;span class=&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-string&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&lt;span class=&quot;hljs-string&quot;&gt;&quot;hljs-built_in&quot;&lt;/span&gt;&lt;/span&gt;&gt;&lt;span class=&lt;span class=&quot;hljs-built_in&quot;&gt;mkdir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; -p ~/Documents/n8n/n8n_data&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;h3 id=&quot;step-4-launch-n8n&quot;&gt;Step 4: Launch n8n&lt;/h3&gt;
&lt;p&gt;Now, start up n8n with:&lt;/p&gt;
&lt;pre data-language=&quot;bash&quot; class=&quot;code-wrapper&quot;&gt;
            &lt;code class=&quot;hljs language-bash&quot;&gt;docker-compose up -d&lt;/code&gt;
            &lt;div class=&quot;code-footer&quot;&gt;
              &lt;button class=&quot;copy-button&quot; aria-label=&quot;Copy code&quot;&gt;
                &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;
                  &lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;
                  &lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;
                &lt;/svg&gt;
              &lt;/button&gt;
            &lt;/div&gt;
          &lt;/pre&gt;&lt;p&gt;The -d flag runs it in detached mode, so it continues running in the background.&lt;/p&gt;
&lt;h3 id=&quot;step-5-access-the-n8n-dashboard&quot;&gt;Step 5: Access the n8n Dashboard&lt;/h3&gt;
&lt;p&gt;Once the container is running, you can access the n8n dashboard by opening:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://your-server-ip:5678&quot;&gt;http://your-server-ip:5678&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re running it on the same machine, just use:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:5678&quot;&gt;http://localhost:5678&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You&amp;#39;ll be prompted for the username and password you set in the docker-compose file.&lt;/p&gt;
&lt;p&gt;Setting Up Remote Access (Optional)&lt;/p&gt;
&lt;p&gt;If you want to access n8n from outside your home network, I recommend using Cloudflare Tunnel (formerly Argo Tunnel). It&amp;#39;s free, secure, and doesn&amp;#39;t require opening ports on your router.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;WEBHOOK_URL&lt;/strong&gt; environment variable in the docker-compose file should point to your Cloudflare Tunnel URL so that webhooks work properly when triggered from external services.&lt;/p&gt;
&lt;h2 id=&quot;my-first-n8n-workflow-websecscan-security-auditor&quot;&gt;My First n8n Workflow: WebSecScan Security Auditor&lt;/h2&gt;
&lt;p&gt;One of my favorite workflows I&amp;#39;ve implemented with n8n is an AI-powered website security auditor called WebSecScan. It&amp;#39;s a powerful tool that provides comprehensive security analysis for any website.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s what it does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Performs dual-layer security analysis using OpenAI models to detect vulnerabilities and misconfigurations&lt;/li&gt;
&lt;li&gt;Analyzes HTTP headers, CORS policies, CSP implementation, and cookie security&lt;/li&gt;
&lt;li&gt;Identifies potential XSS vectors, information disclosure risks, and client-side weaknesses&lt;/li&gt;
&lt;li&gt;Automatically calculates a security grade (A+ to F) based on findings severity&lt;/li&gt;
&lt;li&gt;Generates a professional HTML report and delivers it via email&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best part? The entire process is non-invasive, performing analysis without active scanning or exploitation attempts.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://strapi.my-home-portal.com/uploads/website_Security_Auditor_ef3723d629.png&quot;&gt;https://strapi.my-home-portal.com/uploads/website_Security_Auditor_ef3723d629.png&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://n8n.io/workflows/3314-websecscan-ai-powered-website-security-auditor/&quot;&gt;WebSecScan: AI-Powered Website Security Auditor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Setting this up was surprisingly straightforward. The workflow uses a multi-agent architecture with two specialized OpenAI instances running custom prompts tailored for security analysis. When someone submits a URL through the form, the workflow springs into action, generating a detailed report within minutes.&lt;/p&gt;
&lt;p&gt;What I love about this implementation is how it demonstrates n8n&amp;#39;s flexibility. By combining AI services with email delivery and custom HTML generation, I&amp;#39;ve created something truly useful that would typically require a dedicated SaaS subscription.&lt;/p&gt;
&lt;h3 id=&quot;tips-for-setting-up-n8n&quot;&gt;Tips for Setting Up n8n&lt;/h3&gt;
&lt;p&gt;If you&amp;#39;re just getting started with n8n, here are a few recommendations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Start simple&lt;/strong&gt;: Begin with basic workflows before tackling complex automations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the schedule feature&lt;/strong&gt;: Automate recurring tasks to run at optimal times&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Leverage the community&lt;/strong&gt;: Browse the n8n workflow templates for inspiration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document as you go&lt;/strong&gt;: Add notes to your nodes to remember your logic months later&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test incrementally&lt;/strong&gt;: Build and test your workflow in small chunks to easily identify issues&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Setting up n8n has been one of the most satisfying additions to my home server setup. It strikes the perfect balance between being powerful enough for complex automations while remaining approachable for those late-night coding sessions when my brain is already half asleep.&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re into home automation and self-hosting, I highly recommend giving n8n a try. The initial setup is quick, and the time you&amp;#39;ll save through automation is invaluable—especially when you&amp;#39;re trying to balance tech projects with other responsibilities.&lt;/p&gt;
&lt;p&gt;Have you tried n8n or similar automation tools? What workflows have you created to make your digital life easier? I&amp;#39;d love to hear your experiences!&lt;/p&gt;
&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.n8n.io/&quot;&gt;Official n8n Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/n8n-io/n8n&quot;&gt;n8n GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://community.n8n.io/&quot;&gt;n8n Community Forum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://n8n.io/workflows/3314-websecscan-ai-powered-website-security-auditor/&quot;&gt;WebSecScan Workflow Template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]&gt;</content:encoded><language>en-us</language><category>Technology</category><category>Security</category></item></channel></rss>