<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Registry on blog.iankulin.com</title><link>https://blog.iankulin.com/tags/registry/</link><description>Recent content in Registry on blog.iankulin.com</description><generator>Hugo</generator><language>en-AU</language><lastBuildDate>Mon, 25 Mar 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.iankulin.com/tags/registry/index.xml" rel="self" type="application/rss+xml"/><item><title>Hosting Your Own Docker Registry</title><link>https://blog.iankulin.com/hosting-your-own-docker-registry/</link><pubDate>Mon, 25 Mar 2024 00:00:00 +0000</pubDate><guid>https://blog.iankulin.com/hosting-your-own-docker-registry/</guid><description>&lt;p&gt;&lt;a href="https://unsplash.com/photos/architectural-photography-of-cargo-containers-stack-hP4ZiN1_kdk?utm_content=creditShareLink&amp;utm_medium=referral&amp;utm_source=unsplash"&gt;&lt;img src="https://blog.iankulin.com/images/tri-eptaroka-mardiana-hp4zin1_kdk-unsplash.jpg" width="640" alt="Photo by Tri Eptaroka Mardianam on Unsplash
"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Docker &lt;a href="https://docs.docker.com/subscription/core-subscription/details/"&gt;Personal (ie free tier) plan&lt;/a&gt; currently allows one private repository, but even if you want to pay for the next level where you can have unlimited repositories, you may still want to host your own private registry - it&amp;rsquo;s going to be quicker inside your network, and you won&amp;rsquo;t run up against Docker&amp;rsquo;s pull/push limits if you are hammering it with your CI/CD system.&lt;/p&gt;
&lt;p&gt;There are fancier tools, but in this post we&amp;rsquo;ll look at the basics of how to use the official registry app from Docker.&lt;/p&gt;
&lt;h3 id="initial-setup"&gt;Initial Setup&lt;/h3&gt;
&lt;p&gt;The &lt;a href="https://hub.docker.com/_/registry"&gt;registry app&lt;/a&gt; is (unsurprisingly) dockerised. So I&amp;rsquo;ve created a directory for the &lt;code&gt;docker-compose.yml&lt;/code&gt; file, and a &lt;code&gt;data&lt;/code&gt; sub directory.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-7.50.43-am.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;And the yaml.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;services: registry: image: registry:2 container_name: registry restart: unless-stopped ports: - &amp;#34;5000:5000&amp;#34; environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - ./data:/data
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;docker compose up&lt;/code&gt;, and bingo. Our registry is live.&lt;/p&gt;
&lt;h3 id="creating-an-image"&gt;Creating an image&lt;/h3&gt;
&lt;p&gt;Now our registry is up, let&amp;rsquo;s jump over to another machine, and create an image to store in it. I&amp;rsquo;m only going to minimally explain this, since if you&amp;rsquo;re interested in your own registry, you&amp;rsquo;ve probably been down this path.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-1.24.50-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FROM busyboxRUN mkdir /appCOPY script.sh /app/script.shWORKDIR /appRUN chmod +x script.shCMD [&amp;#34;./script.sh&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;script.sh&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#5e81ac;font-style:italic"&gt;#!/bin/shecho &amp;#34;Hello from Docker!&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So basically, this image contains a small Linux distro, and all it does is run a script that outputs &amp;ldquo;Hello from Docker!&amp;rdquo; to the console. We can build our image by switching into the directory with the &lt;code&gt;dockerfile&lt;/code&gt; and running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo docker build -t hello-docker .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-1.37.15-pm.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;If you want to run it to check my docker skills, use&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo docker run hello-docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="pushing--insecure"&gt;Pushing &amp;amp; Insecure&lt;/h3&gt;
&lt;p&gt;Now I want to push the image we&amp;rsquo;ve created to the new registry we set up earlier, but we&amp;rsquo;re going to run into a problem.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m using two Debian virtual machines (LXCs actually) both on my homelab network. They&amp;rsquo;ve been named with Tailscale to make things clearer in the screenshots. (If you&amp;rsquo;re following along you&amp;rsquo;ll probably be using IP addresses). Importantly, there are no TLS certificates, self-signed or otherwise.&lt;/p&gt;
&lt;p&gt;First we need to tag our image to include the registry name:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo docker tag hello-docker:latest ct390-docker-reg:5000/hello-docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-1.53.18-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;And we&amp;rsquo;ll try to push it up to our registry with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker push ct390-docker-reg:5000/hello-docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-2.35.40-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s happening is that Docker would (quite reasonably) prefer to only work over secure connections. We can override this on this machine for today&amp;rsquo;s demo purposes by adding an exception for our self-hosted registry. You&amp;rsquo;ll need to create the file &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; and add the registry that&amp;rsquo;s going to be allowed like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ &amp;#34;insecure-registries&amp;#34; : [ &amp;#34;ct390-docker-reg:5000&amp;#34; ]}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we restart docker and retry the push now, it should work:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-2.43.02-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;That looks like it worked. If we wanted to check, we can just hit an endpoint on the registry:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl http://ct390-docker-reg:5000/v2/_catalog
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-2.49.36-pm.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="pulling--insecure"&gt;Pulling &amp;amp; Insecure&lt;/h3&gt;
&lt;p&gt;Of course the ultimate test is going to be to use this image from a third machine, so let&amp;rsquo;s spin one up with a clean docker install with no images and try to run the image we&amp;rsquo;ve just added to our registry.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re going to have the same challenge pulling from a non-TLS registry as we had pushing to it, and the workaround is going to be exactly the same - add the registry to the insecure list in the &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#d8dee9;background-color:#2e3440;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#a3be8c"&gt;&amp;#39;{ &amp;#34;insecure-registries&amp;#34; : [ &amp;#34;ct390-docker-reg:5000&amp;#34; ]}&amp;#39;&lt;/span&gt; &lt;span style="color:#81a1c1"&gt;|&lt;/span&gt; sudo tee &lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;etc&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;docker&lt;span style="color:#81a1c1"&gt;/&lt;/span&gt;daemon&lt;span style="color:#81a1c1"&gt;.&lt;/span&gt;jsonsudo systemctl daemon&lt;span style="color:#81a1c1"&gt;-&lt;/span&gt;reloadsudo systemctl restart docker
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can run it. Since we don&amp;rsquo;t have the image locally yet, docker will pull it down for us from the registry before running it:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.iankulin.com/images/screen-shot-2024-03-23-at-3.19.03-pm.png" alt=""&gt;&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s it. Our own private Docker registry to store our images.&lt;/p&gt;
&lt;h4 id="references"&gt;References&lt;/h4&gt;
&lt;p&gt;In writing this post, I relied on some these resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Digital Ocean - &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-private-docker-registry-on-ubuntu-20-04"&gt;How To Set Up a Private Docker Registry on Ubuntu 20.04&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Baeldung - &lt;a href="https://www.baeldung.com/ops/docker-private-registry"&gt;Configure a Private Docker Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;O&amp;rsquo;Reilly - &lt;a href="https://www.oreilly.com/library/view/kubernetes-in-the/9781492043270/app03.html"&gt;Configuring Docker to Push or Pull from an Insecure Registry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>