<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Docker on Zet’s playground</title>
    <link>https://blog.zet.tw/en/tags/docker/</link>
    <description>Recent content in Docker on Zet’s playground</description>
    <image>
      <title>Zet’s playground</title>
      <url>https://blog.zet.tw/img/blog-cover.png</url>
      <link>https://blog.zet.tw/img/blog-cover.png</link>
    </image>
    <generator>Hugo -- 0.139.0</generator>
    <language>en</language>
    <lastBuildDate>Mon, 07 Nov 2022 00:00:00 +0800</lastBuildDate>
    <atom:link href="https://blog.zet.tw/en/tags/docker/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Using Cloudflare Tunnel for NAT traversal, with Gitea as an example</title>
      <link>https://blog.zet.tw/en/posts/2022-11-07-cloudflare-tunnels-gitea/</link>
      <pubDate>Mon, 07 Nov 2022 00:00:00 +0800</pubDate>
      <guid>https://blog.zet.tw/en/posts/2022-11-07-cloudflare-tunnels-gitea/</guid>
      <description>&lt;p&gt;Often you run many services on your LAN, and when you need to reach them from outside you usually do it with port forwarding. Here I use Cloudflare Tunnel instead — no port forwarding on the router is needed, and you can add two-factor authentication via Email OTP, which improves both convenience and security.&lt;/p&gt;
&lt;p&gt;It works for a NAS, a Git server, a Virtual Machine Manager, and more on your LAN.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Often you run many services on your LAN, and when you need to reach them from outside you usually do it with port forwarding. Here I use Cloudflare Tunnel instead — no port forwarding on the router is needed, and you can add two-factor authentication via Email OTP, which improves both convenience and security.</p>
<p>It works for a NAS, a Git server, a Virtual Machine Manager, and more on your LAN.</p>
<h1 id="gitea">Gitea</h1>
<p>Gitea is much lighter than GitLab. Using mirroring to back up projects on GitHub that might disappear at any time is very handy.</p>
<p>For installing with docker, see <a href="https://docs.gitea.io/en-us/install-with-docker/">https://docs.gitea.io/en-us/install-with-docker/</a>.</p>
<p>Here are some config options I personally use:</p>
<ul>
<li>Let gitea search code easily</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>[indexer]
</span></span><span style="display:flex;"><span>REPO_INDEXER_ENABLED = true
</span></span></code></pre></div><ul>
<li>Customize the URL and listen port shown on the page. For the landing page, if the visitor isn&rsquo;t logged in you can point them straight to the login page on open, instead of Gitea&rsquo;s home page.</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>[server]
</span></span><span style="display:flex;"><span>PROTOCOL         = https
</span></span><span style="display:flex;"><span>DOMAIN           = git.test.tw
</span></span><span style="display:flex;"><span>SSH_DOMAIN       = git-ssh.test.tw
</span></span><span style="display:flex;"><span>SSH_LISTEN_PORT  = 11022
</span></span><span style="display:flex;"><span>HTTP_PORT        = 3000
</span></span><span style="display:flex;"><span>ROOT_URL         = https://git.test.tw
</span></span><span style="display:flex;"><span>ENABLE_GZIP      = true
</span></span><span style="display:flex;"><span>LANDING_PAGE     = login
</span></span></code></pre></div><ul>
<li>Remove the footer info, version and load time from the page</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>[other]
</span></span><span style="display:flex;"><span>SHOW_FOOTER_BRANDING = false
</span></span><span style="display:flex;"><span>SHOW_FOOTER_VERSION = false
</span></span><span style="display:flex;"><span>SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
</span></span></code></pre></div><p>For detailed settings see the
<a href="https://docs.gitea.io/en-us/config-cheat-sheet/">Gitea Configuration Cheat Sheet </a> and customize as you like.</p>
<h1 id="setup-cloudflare-tunnel">Setup Cloudflare Tunnel</h1>
<h2 id="run-cloudflared-service">Run Cloudflared Service</h2>
<p>First you need a domain hosted on Cloudflare. Find Zero Trust in the sidebar.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/cloudflare-dashboard.png" alt=""  />
</p>
<p>Once opened, find Tunnel.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/add-tunnels.png" alt=""  />
</p>
<p>After naming it, you can choose the platform on which to run the tunnel service. I like running it on docker — just paste the command, and you can add <code>--restart=always</code> and <code>-d</code> flags as you prefer.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/docker-tunnel.png" alt=""  />
</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run --restart<span style="color:#f92672">=</span>always -d cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <span style="color:#f92672">[</span>your_token_here<span style="color:#f92672">]</span>
</span></span></code></pre></div><p>For synology, you can specify the command in the advanced settings — just paste in the string after the image.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/synology-cmd.png" alt=""  />
</p>
<p>If it succeeds, you should see the Status on the Tunnels page turn a green <strong>ACTIVE</strong>.</p>
<h2 id="add-tunnel">Add Tunnel</h2>
<p>Fill in the subdomain and pick which service to forward below. There are many protocols to choose from, e.g. https, http, ssh, RDP; the URL after it takes the internal host and port.</p>
<blockquote>
<p>If you want to <code>git ssh clone</code>, choose SSH as the protocol and follow it with ip:port.</p>
</blockquote>
<blockquote>
<p>Note: if you have a private HTTPS certificate, you can select No TLS Verify so Cloudflare Tunnel can connect smoothly.</p>
</blockquote>
<p><img loading="lazy" src="/img/cloudflare-tunnel/add-tunnel.png" alt=""  />
</p>
<p>Once added successfully, you should see a CNAME automatically added to the domain&rsquo;s DNS.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/check-cname.png" alt=""  />
</p>
<p>At this point just try connecting and it should work.</p>
<h2 id="auth">Auth</h2>
<blockquote>
<p>Some services may be inconvenient with Auth attached, so adjust as you see fit. I haven&rsquo;t tested Gitea&rsquo;s web with it — you can experiment; I&rsquo;m not sure whether https clone will have issues.</p>
</blockquote>
<p>With the setup above, http/https services are now reachable from outside. If you want to add another layer of protection, you can use the Access - Application feature: add a <code>Self-hosted</code> Application and set the subdomain.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/applications.png" alt=""  />
</p>
<p>Then add a policy. Under <code>Configure rules</code> you can add the rules you want within this application&rsquo;s scope (subdomain). Choosing email will prompt you for an OTP on the verification page before you can log in; there are also IP range, Country and Token methods — lots of ways to freely combine rules.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/policy.png" alt=""  />
</p>
<p>Finally, when you access it, you should see the page asking for email authentication.</p>
<p><img loading="lazy" src="/img/cloudflare-tunnel/access.png" alt=""  />
</p>
<h2 id="git-ssh">Git ssh</h2>
<p>After the tunnel setup, going into Gitea you should see a clean clone address:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>via https
</span></span><span style="display:flex;"><span>https://git.test.tw/mirror/Windows-Exploit-Suggester.git
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>via ssh
</span></span><span style="display:flex;"><span>git@git-ssh.test.tw:mirror/Windows-Exploit-Suggester.git
</span></span></code></pre></div><p>No more ugly IPs or port numbers.</p>
<p>Note that because SSH is being forwarded, you need some extra config in your local ssh config. On the client machine, install <code>cloudflared</code>, which you can install easily with homebrew or scoop.</p>
<p>Edit <code>~/.ssh/config</code> in your home directory and add a <code>ProxyCommand</code> that chains to <code>cloudflared</code>; then ssh clone will work normally:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-fallback" data-lang="fallback"><span style="display:flex;"><span>Host git.test.com
</span></span><span style="display:flex;"><span>  ProxyCommand cloudflared access ssh --hostname %h
</span></span></code></pre></div><p>If you hit snags along the way, you can also refer to Cloudflare&rsquo;s official docs
<a href="https://developers.cloudflare.com/cloudflare-one/tutorials/gitlab/">Zero Trust GitLab SSH &amp; HTTP
</a></p>
<h1 id="in-the-end">In The End</h1>
<p>Cloudflare Tunnel can forward many internal services without opening port forwarding — a great thing. Paired with the Zero Trust concept to protect your assets, important services on your home NAS can be both protected and conveniently accessible.</p>
<p>There are tons more ways to use it, such as opening a web terminal to access an internal SSH service. See the YouTube video <a href="https://www.youtube.com/watch?v=Z6b3l1z0N7w">HOW TO: Remote access a Raspberry Pi using a Cloudflare tunnel (node-red and ssh).</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Auto-updating docker containers - watchtower</title>
      <link>https://blog.zet.tw/en/posts/2022-11-06-watchtower/</link>
      <pubDate>Sun, 06 Nov 2022 00:00:00 +0800</pubDate>
      <guid>https://blog.zet.tw/en/posts/2022-11-06-watchtower/</guid>
      <description>&lt;p&gt;I run a bunch of docker containers on Synology and on a few servers, and use watchtower to update their images automatically.&lt;/p&gt;
&lt;p&gt;First set the timezone to Taipei:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo timedatectl set-timezone Asia/Taipei
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add the cleanup and schedule flags:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker run -d --restart&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;always &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;--name watchtower &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-v /var/run/docker.sock:/var/run/docker.sock &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;-v /etc/localtime:/etc/localtime:ro &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;containrrr/watchtower &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;--cleanup &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;--schedule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0 0 4 * * *&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More flags can be found here: &lt;a href=&#34;https://containrrr.dev/watchtower/arguments/&#34;&gt;https://containrrr.dev/watchtower/arguments/&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I run a bunch of docker containers on Synology and on a few servers, and use watchtower to update their images automatically.</p>
<p>First set the timezone to Taipei:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo timedatectl set-timezone Asia/Taipei
</span></span></code></pre></div><p>Add the cleanup and schedule flags:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run -d --restart<span style="color:#f92672">=</span>always <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>--name watchtower <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>-v /var/run/docker.sock:/var/run/docker.sock <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>-v /etc/localtime:/etc/localtime:ro <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>containrrr/watchtower <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>--cleanup <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>--schedule <span style="color:#e6db74">&#34;0 0 4 * * *&#34;</span>
</span></span></code></pre></div><p>More flags can be found here: <a href="https://containrrr.dev/watchtower/arguments/">https://containrrr.dev/watchtower/arguments/</a></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
