How to configure Headscale and Traefik to proxy any service

<h2 id=requirements>Requirements:</h2><ul><li>a linux server with a public IPv4 address</li><li>docker and docker compose installed</li><li>a domain/subdomain with a A DNS record pointing to your IP</li></ul><p>I will use <strong>example.com</strong> as the domain name in this example, please replace it with your domain/subdomain.</p><h2 id=traefik>Traefik</h2><p>Ssh to your public server where you want to host your vpn, make a folder called <code>traefik</code> with the following files: <code>mkdir traefik && cd traefik</code></p><h3 id=1-an-empty-letsencrypt-folder-mkdir-letsencrypt>1. An empty <code>letsencrypt</code> folder: <code>mkdir letsencrypt</code></h3><h3 id=2-an-empty-file-touch-dynamicyml-for-future-expansion>2. An empty file <code>touch dynamic.yml</code> (for future expansion)</h3><h3 id=3-the-static-config-nano-staticyml>3. The static config: <code>nano static.yml</code></h3><div class=highlight><pre tabindex=0 style=color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yaml data-lang=yaml><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 1</span><span><span style=color:#6ab825;font-weight:700>api</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 2</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>insecure</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 3</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>dashboard</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 4</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 5</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>providers</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 6</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>docker</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 7</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>exposedByDefault</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 8</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 9</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>entryPoints</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">10</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>web</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">11</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>address</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;:80&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">12</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>http2</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">13</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>maxConcurrentStreams</span>:<span style=color:#666> </span><span style=color:#3677a9>250</span><span style=color:#666> </span><span style=color:#999;font-style:italic># fix for network error on the proxy to my immich instance</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">14</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>http3</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">15</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>advertisedPort</span>:<span style=color:#666> </span><span style=color:#3677a9>443</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">16</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># http:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">17</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># redirections:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">18</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># entryPoint:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">19</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># to: websecure</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">20</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># scheme: https</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">21</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>forwardedHeaders</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">22</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>trustedIPs</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">23</span><span><span style=color:#666> </span>- <span style=color:#3677a9>10.0.0.0</span>/8<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">24</span><span><span style=color:#666> </span>- <span style=color:#3677a9>172.16.0.0</span>/12<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">25</span><span><span style=color:#666> </span>- <span style=color:#3677a9>192.168.0.0</span>/16<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">26</span><span><span style=color:#666> </span>- fc00::/7<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">27</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>proxyProtocol</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">28</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>trustedIPs</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">29</span><span><span style=color:#666> </span>- <span style=color:#3677a9>10.0.0.0</span>/8<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">30</span><span><span style=color:#666> </span>- <span style=color:#3677a9>172.16.0.0</span>/12<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">31</span><span><span style=color:#666> </span>- <span style=color:#3677a9>192.168.0.0</span>/16<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">32</span><span><span style=color:#666> </span>- fc00::/7<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">33</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>websecure</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">34</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>address</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;:443&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">35</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>http2</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">36</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>maxConcurrentStreams</span>:<span style=color:#666> </span><span style=color:#3677a9>250</span><span style=color:#666> </span><span style=color:#999;font-style:italic># fix for network error on the proxy to my immich instance</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">37</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>http3</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">38</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>advertisedPort</span>:<span style=color:#666> </span><span style=color:#3677a9>443</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">39</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>forwardedHeaders</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">40</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>trustedIPs</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">41</span><span><span style=color:#666> </span>- <span style=color:#3677a9>10.0.0.0</span>/8<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">42</span><span><span style=color:#666> </span>- <span style=color:#3677a9>172.16.0.0</span>/12<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">43</span><span><span style=color:#666> </span>- <span style=color:#3677a9>192.168.0.0</span>/16<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">44</span><span><span style=color:#666> </span>- fc00::/7<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">45</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>proxyProtocol</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">46</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>trustedIPs</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">47</span><span><span style=color:#666> </span>- <span style=color:#3677a9>10.0.0.0</span>/8<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">48</span><span><span style=color:#666> </span>- <span style=color:#3677a9>172.16.0.0</span>/12<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">49</span><span><span style=color:#666> </span>- <span style=color:#3677a9>192.168.0.0</span>/16<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">50</span><span><span style=color:#666> </span>- fc00::/7<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">51</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">52</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>certificatesResolvers</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">53</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>myresolver</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">54</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>acme</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">55</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>email</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;your-email-goes-here@tutorial.example&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">56</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>storage</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;/letsencrypt/acme.json&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">57</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>httpChallenge</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">58</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>entryPoint</span>:<span style=color:#666> </span>web<span style=color:#666> </span></span></span></code></pre></div><blockquote><p>Replace <code>your-email-goes-here@tutorial.example</code> with your email address. Let&rsquo;s Encrypt send you notifications when your ssl certificate expires.</p></blockquote><h3 id=4-the-docker-compose-config-nano-composeyml>4. The docker compose config: <code>nano compose.yml</code></h3><div class=highlight><pre tabindex=0 style=color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yaml data-lang=yaml><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 1</span><span><span style=color:#6ab825;font-weight:700>services</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 2</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 3</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>traefik</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 4</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>image</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;traefik:v3.2&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 5</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>container_name</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;traefik&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 6</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>restart</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;always&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 7</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>ports</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 8</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;80:80&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 9</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;443:443&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">10</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>networks</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">11</span><span><span style=color:#666> </span>- pub<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">12</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>volumes</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">13</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;./letsencrypt:/letsencrypt&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">14</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;/var/run/docker.sock:/var/run/docker.sock:ro&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">15</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;./static.yml:/etc/traefik/traefik.yml:ro&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">16</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;./dynamic.yml:/etc/traefik/dynamic.yaml:ro&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">17</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>labels</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">18</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.enable=true&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">19</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.dashboard.rule=Host(`example.com`) &amp;&amp; (PathPrefix(`/dashboard`) || PathPrefix(`/api/overview`) || PathPrefix(`/api/version`) || PathPrefix(`/api/http`) || PathPrefix(`/api/entrypoints`) || PathPrefix(`/api/tcp`) || PathPrefix(`/api/udp`))&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">20</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.dashboard.entrypoints=websecure&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">21</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.dashboard.tls.certresolver=myresolver&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">22</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.dashboard.service=api@internal&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">23</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># # if you want to password protect your traefik dashboard uncomment the following and change the user:pass</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">24</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic>#- &#34;traefik.http.routers.dashboard.middlewares=auth&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">25</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic>#- &#34;traefik.http.middlewares.auth.basicauth.users=&#34; # to create user and pass: bash -c &#39;echo $(htpasswd -nB admin) | sed -e s/\\$/\\$\\$/g&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">26</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">27</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>networks</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">28</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>pub</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">29</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>external</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span></code></pre></div><p>Create the <code>pub</code> network first using the command <code>docker network create pub</code></p><p>Now we can start the traefik instance: <code>docker compose up -d</code></p><h2 id=headscale>HeadScale</h2><p>Let&rsquo;s make a separate folder for headscale: <code>cd .. && mkdir headscale</code></p><h3 id=1-2-empty-folders-mkdir-data--mkdir-tailscale-client>1. 2 empty folders: <code>mkdir data && mkdir tailscale-client</code></h3><h3 id=2-the-headscale-config-nano-configyml>2. The headscale config: <code>nano config.yml</code></h3><div class=highlight><pre tabindex=0 style=color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yaml data-lang=yaml><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 1</span><span><span style=color:#447fcf;text-decoration:underline>---</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 2</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># The url clients will connect to.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 3</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>server_url</span>:<span style=color:#666> </span>https://example.com<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 4</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 5</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Address to listen to / bind to on the server</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 6</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>listen_addr</span>:<span style=color:#666> </span><span style=color:#3677a9>0.0.0.0</span>:<span style=color:#3677a9>8080</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 7</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 8</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Address to listen to /metrics, you may want</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 9</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>metrics_listen_addr</span>:<span style=color:#666> </span><span style=color:#3677a9>127.0.0.1</span>:<span style=color:#3677a9>9090</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 10</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 11</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Address to listen for gRPC.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 12</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>grpc_listen_addr</span>:<span style=color:#666> </span><span style=color:#3677a9>127.0.0.1</span>:<span style=color:#3677a9>50443</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 13</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 14</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Allow the gRPC admin interface to run in INSECURE mode.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 15</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>grpc_allow_insecure</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 16</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 17</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>noise</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 18</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># The Noise private key is used to encrypt the traffic</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 19</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>private_key_path</span>:<span style=color:#666> </span>/var/lib/headscale/noise_private.key<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 20</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 21</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># List of IP prefixes to allocate tailaddresses from.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 22</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Each prefix consists of either an IPv4 or IPv6 address,</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 23</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>prefixes</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 24</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>v6</span>:<span style=color:#666> </span>fd7a:115c:a1e0::/48<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 25</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>v4</span>:<span style=color:#666> </span><span style=color:#3677a9>100.64.0.0</span>/10<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 26</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Strategy used for allocation of IPs to nodes, available options:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 27</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - sequential (default): assigns the next free IP from the previous given IP.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 28</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - random: assigns the next free IP from a pseudo-random IP generator (crypto/rand).</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 29</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>allocation</span>:<span style=color:#666> </span>sequential<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 30</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 31</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># DERP is a relay system that Tailscale uses when a direct connection cannot be established.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 32</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>derp</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 33</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>server</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 34</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>enabled</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 35</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Region ID to use for the embedded DERP server.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 36</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>region_id</span>:<span style=color:#666> </span><span style=color:#3677a9>999</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 37</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>region_code</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;headscale&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 38</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>region_name</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;Headscale Embedded DERP&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 39</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Listens over UDP at the configured address for STUN connections - to help with NAT traversal.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 40</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>stun_listen_addr</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;0.0.0.0:3478&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 41</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Private key used to encrypt the traffic between headscale DERP and Tailscale clients.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 42</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>private_key_path</span>:<span style=color:#666> </span>/var/lib/headscale/derp_server_private.key<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 43</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># This flag can be used, so the DERP map entry for the embedded DERP server is not written automatically,</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 44</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>automatically_add_embedded_derp_region</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 45</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># For better connection stability (especially when using an Exit-Node and DNS is not working),</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 46</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>ipv4</span>:<span style=color:#666> </span><span style=color:#3677a9>1.2.3.4</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 47</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>ipv6</span>:<span style=color:#666> </span><span style=color:#3677a9>2001</span>:db8::1<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 48</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># List of externally available DERP maps encoded in JSON</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 49</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>urls</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 50</span><span><span style=color:#666> </span>- https://controlplane.tailscale.com/derpmap/default<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 51</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Locally available DERP map files encoded in YAML</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 52</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>paths</span>:<span style=color:#666> </span>[]<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 53</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># If enabled, a worker will be set up to periodically refresh the given sources and update the derpmap</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 54</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>auto_update_enabled</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 55</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># How often should we check for DERP updates?</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 56</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>update_frequency</span>:<span style=color:#666> </span>24h<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 57</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Disables the automatic check for headscale updates on startup</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 58</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>disable_check_updates</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 59</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Time before an inactive ephemeral node is deleted?</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 60</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>ephemeral_node_inactivity_timeout</span>:<span style=color:#666> </span>30m<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 61</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>database</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 62</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>type</span>:<span style=color:#666> </span>sqlite<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 63</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Enable debug mode. This setting requires the log.level to be set to &#34;debug&#34; or &#34;trace&#34;.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 64</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>debug</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 65</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>gorm</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 66</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>prepare_stmt</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 67</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>parameterized_queries</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 68</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>skip_err_record_not_found</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 69</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>slow_threshold</span>:<span style=color:#666> </span><span style=color:#3677a9>1000</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 70</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>sqlite</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 71</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>path</span>:<span style=color:#666> </span>/var/lib/headscale/db.sqlite<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 72</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>write_ahead_log</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 73</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 74</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic>### TLS configuration Let&#39;s encrypt / ACME</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 75</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>acme_url</span>:<span style=color:#666> </span>https://acme-v02.api.letsencrypt.org/directory<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 76</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>acme_email</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;your-email-goes-here@tutorial.example&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 77</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>tls_letsencrypt_hostname</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 78</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Path to store certificates and metadata needed by letsencrypt</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 79</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>tls_letsencrypt_cache_dir</span>:<span style=color:#666> </span>/var/lib/headscale/cache<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 80</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 81</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Type of ACME challenge to use, currently supported types: HTTP-01 or TLS-ALPN-01</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 82</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>tls_letsencrypt_challenge_type</span>:<span style=color:#666> </span>HTTP-01<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 83</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># When HTTP-01 challenge is chosen, letsencrypt must set up a verification endpoint, and it will be listening on:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 84</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>tls_letsencrypt_listen</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;:http&#34;</span><span style=color:#666> </span><span style=color:#999;font-style:italic># :http = port 80</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 85</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>tls_cert_path</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 86</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>tls_key_path</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 87</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 88</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>log</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 89</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>format</span>:<span style=color:#666> </span>text<span style=color:#666> </span><span style=color:#999;font-style:italic># text or json</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 90</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>level</span>:<span style=color:#666> </span>info<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 91</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 92</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>policy</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 93</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>mode</span>:<span style=color:#666> </span>file<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 94</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>path</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 95</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 96</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>dns</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 97</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>magic_dns</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 98</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Defines the base domain to create the hostnames for MagicDNS.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 99</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>base_domain</span>:<span style=color:#666> </span>head.local<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">100</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>nameservers</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">101</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>global</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">102</span><span><span style=color:#666> </span>- <span style=color:#3677a9>1.1.1.1</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">103</span><span><span style=color:#666> </span>- <span style=color:#3677a9>1.0.0.1</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">104</span><span><span style=color:#666> </span>- <span style=color:#3677a9>2606</span>:<span style=color:#3677a9>4700</span>:<span style=color:#3677a9>4700</span>::<span style=color:#3677a9>1111</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">105</span><span><span style=color:#666> </span>- <span style=color:#3677a9>2606</span>:<span style=color:#3677a9>4700</span>:<span style=color:#3677a9>4700</span>::<span style=color:#3677a9>1001</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">106</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>split</span>:<span style=color:#666> </span>{}<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">107</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>search_domains</span>:<span style=color:#666> </span>[]<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">108</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Extra DNS records</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">109</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>extra_records</span>:<span style=color:#666> </span>[]<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">110</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">111</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>unix_socket</span>:<span style=color:#666> </span>/var/run/headscale/headscale.sock<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">112</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>unix_socket_permission</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;0770&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">113</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>logtail</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">114</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># Enable logtail for this headscales clients.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">115</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>enabled</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">116</span><span><span style=color:#666></span><span style=color:#999;font-style:italic># Enabling this option makes devices prefer a random port for WireGuard traffic over the default static port 41641.</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">117</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>randomize_client_port</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>false</span><span style=color:#666> </span></span></span></code></pre></div><blockquote><p>It&rsquo;s the default config, I removed some comments and replaced <code>server_url</code>, <code>acme_email</code> and the <code>base_domain</code> from dns section. This last config is the Magic DNS that headscale uses to create a DNS entry for every device you connect to your tailscale vpn.</p></blockquote><h3 id=3-the-docker-compose-config-nano-composeyml>3. The docker compose config: <code>nano compose.yml</code></h3><div class=highlight><pre tabindex=0 style=color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yaml data-lang=yaml><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 1</span><span><span style=color:#6ab825;font-weight:700>services</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 2</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 3</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>headscale</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 4</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>container_name</span>:<span style=color:#666> </span>headscale<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 5</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>image</span>:<span style=color:#666> </span>headscale/headscale<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 6</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>command</span>:<span style=color:#666> </span>serve<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 7</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>restart</span>:<span style=color:#666> </span>always<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 8</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>ports</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 9</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;8080:8080&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">10</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>networks</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">11</span><span><span style=color:#666> </span>- pub<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">12</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>volumes</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">13</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;./data:/var/lib/headscale&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">14</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;./config.yml:/etc/headscale/config.yaml&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">15</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>cap_add</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">16</span><span><span style=color:#666> </span>- NET_ADMIN<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">17</span><span><span style=color:#666> </span>- SYS_MODULE<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">18</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>sysctls</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">19</span><span><span style=color:#666> </span>- net.ipv4.ip_forward=1<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">20</span><span><span style=color:#666> </span>- net.ipv4.conf.all.src_valid_mark=1<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">21</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>labels</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">22</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.enable=true&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">23</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.headscale.rule=Host(`example.com`)&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">24</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.headscale.entrypoints=websecure&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">25</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.headscale.tls.certresolver=myresolver&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">26</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.services.headscale.loadbalancer.server.port=8080&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">27</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">28</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>headplane</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">29</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>container_name</span>:<span style=color:#666> </span>headplane<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">30</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>image</span>:<span style=color:#666> </span>ghcr.io/tale/headplane:0.3.2<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">31</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>restart</span>:<span style=color:#666> </span>unless-stopped<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">32</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>ports</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">33</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#39;3000:3000&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">34</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>networks</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">35</span><span><span style=color:#666> </span>- pub<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">36</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>depends_on</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">37</span><span><span style=color:#666> </span>- headscale<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">38</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>volumes</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">39</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;./config.yml:/etc/headscale/config.yaml&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">40</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>environment</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">41</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>HEADSCALE_URL</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#39;http://headscale:8080&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">42</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>API_KEY</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">43</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>CONFIG_FILE</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#34;/etc/headscale/config.yaml&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">44</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>COOKIE_SECRET</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#39;put-some-random-string-here-32j564b64kl6n34lk&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">45</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>DISABLE_API_KEY_LOGIN</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#39;true&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">46</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>COOKIE_SECURE</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#39;false&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">47</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>HOST</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#39;0.0.0.0&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">48</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>PORT</span>:<span style=color:#666> </span><span style=color:#ed9d13>&#39;3000&#39;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">49</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>labels</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">50</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.enable=true&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">51</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.headplane.rule=Host(`example.com`) &amp;&amp; PathPrefix(`/admin`)&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">52</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.headplane.entrypoints=websecure&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">53</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.routers.headplane.tls.certresolver=myresolver&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">54</span><span><span style=color:#666> </span>- <span style=color:#ed9d13>&#34;traefik.http.services.headplane.loadbalancer.server.port=3000&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">55</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic>#- &#34;traefik.http.routers.headplane.middlewares=auth&#34; # uncomment this only if you generated a password in traefik step 4</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">56</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">57</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># client:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">58</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># container_name: tailscale-client</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">59</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># image: tailscale/tailscale</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">60</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># restart: unless-stopped</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">61</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># environment:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">62</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - &#34;TS_AUTHKEY=&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">63</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - &#34;TS_STATE_DIR=/var/lib/tailscale&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">64</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - &#34;TS_USERSPACE=false&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">65</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - &#34;TS_EXTRA_ARGS=--login-server=https://example.com --advertise-exit-node --hostname=server-client --shields-up=false&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">66</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># networks:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">67</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - pub</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">68</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># volumes:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">69</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - &#34;./tailscale-client:/var/lib/tailscale&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">70</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - &#34;/dev/net/tun:/dev/net/tun&#34;</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">71</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># cap_add:</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">72</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - net_admin</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">73</span><span><span style=color:#666> </span><span style=color:#999;font-style:italic># - sys_module</span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">74</span><span><span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">75</span><span><span style=color:#666></span><span style=color:#6ab825;font-weight:700>networks</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">76</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>pub</span>:<span style=color:#666> </span></span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">77</span><span><span style=color:#666> </span><span style=color:#6ab825;font-weight:700>external</span>:<span style=color:#666> </span><span style=color:#6ab825;font-weight:700>true</span><span style=color:#666> </span></span></span></code></pre></div><p>We can start headscale now: <code>docker compose up -d</code></p><hr width=100% id=EOF><p style=color:#777>Last modified on 2025-01-25</p>