<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cloud Native | DCMST</title><link>https://portfolio.devcrumbs.com/tag/cloud-native/</link><atom:link href="https://portfolio.devcrumbs.com/tag/cloud-native/index.xml" rel="self" type="application/rss+xml"/><description>Cloud Native</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Tue, 23 Feb 2021 00:00:00 +0000</lastBuildDate><image><url>https://portfolio.devcrumbs.com/media/icon_hu28290437db960aa4e7d19bb9f7230401_6937_512x512_fill_lanczos_center_3.png</url><title>Cloud Native</title><link>https://portfolio.devcrumbs.com/tag/cloud-native/</link></image><item><title>Podman remote client on MacOS using Vagrant</title><link>https://portfolio.devcrumbs.com/podman-macos-vagrant/</link><pubDate>Tue, 23 Feb 2021 00:00:00 +0000</pubDate><guid>https://portfolio.devcrumbs.com/podman-macos-vagrant/</guid><description>&lt;details class="toc-inpage d-print-none " open>
&lt;summary class="font-weight-bold">Table of Contents&lt;/summary>
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#introduction">Introduction&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#brief-architecture">Brief Architecture&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#installation">Installation&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#install-podman-on-macos">Install podman on MacOS&lt;/a>&lt;/li>
&lt;li>&lt;a href="#create-a-new-ssh-keys-on-macos">Create a new ssh-keys on MacOS&lt;/a>&lt;/li>
&lt;li>&lt;a href="#create-a-vagrant-vm">Create a vagrant VM&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#implementation">Implementation&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#copy-ssh-key-from-macos-to-linux-vm">Copy ssh-key from MacOS to Linux VM&lt;/a>&lt;/li>
&lt;li>&lt;a href="#configure-the-linux-vm">Configure the Linux VM&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#using-the-client">Using the client&lt;/a>&lt;/li>
&lt;li>&lt;a href="#next-steps">Next steps&lt;/a>&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/details>
&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>&lt;a href="http://podman.io/" target="_blank" rel="noopener">Podman&lt;/a> is a daemonless, open-source, Linux native tool designed to make it easy to find, run, build, share and deploy applications using
Open Containers Initiative (&lt;a href="https://www.opencontainers.org/" target="_blank" rel="noopener">OCI&lt;/a>) Containers and Container Images.&lt;/p>
&lt;p>That been said, the core of podman only runs in Linux!
To use podman on macOS, we need to implement the &lt;strong>remote client&lt;/strong> to manage container using a Linux as a backend.&lt;/p>
&lt;h3 id="brief-architecture">Brief Architecture&lt;/h3>
&lt;p>The remote client uses a client-server model.
We need Podman installed on a Linux VM that also has the SSH daemon running.
On our MacOS, when you execute a Podman command:&lt;/p>
&lt;ul>
&lt;li>Podman connects to the server via SSH.&lt;/li>
&lt;li>It then connects to the Podman service by using systemd socket activation.&lt;/li>
&lt;li>The Podman commands are executed on the Linux VM.&lt;/li>
&lt;li>From the client&amp;rsquo;s point of view, it seems like Podman runs locally.&lt;/li>
&lt;/ul>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;h3 id="install-podman-on-macos">Install podman on MacOS&lt;/h3>
&lt;p>To install podman remote client on MacOS, we use &lt;a href="https://brew.sh/" target="_blank" rel="noopener">Homebrew&lt;/a>&lt;/p>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ brew install podman
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;h3 id="create-a-new-ssh-keys-on-macos">Create a new ssh-keys on MacOS&lt;/h3>
&lt;p>We will need to connect via ssh to our vagrant VM, in order to do it passwordless, we will create a ssh-key, the commands for that are:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ ssh-keygen -t rsa -b &lt;span class="m">4096&lt;/span> -C &lt;span class="s2">&amp;#34;podman+vagrant&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Generating public/private rsa key pair.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Enter file in which to save the key &lt;span class="o">(&lt;/span>/Users/&amp;lt;USERNAME&amp;gt;/.ssh/id_rsa&lt;span class="o">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Enter passphrase &lt;span class="o">(&lt;/span>empty &lt;span class="k">for&lt;/span> no passphrase&lt;span class="o">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Enter same passphrase again:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Your identification has been saved in /Users/&amp;lt;USERNAME&amp;gt;/.ssh/id_rsa.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Your public key has been saved in /Users/&amp;lt;USERNAME&amp;gt;/.ssh/id_rsa.pub.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">The key fingerprint is:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SHA256:+pGx7Wcn9WdfRYKJrcdMiKEIPKFRW1lQ1MXP/8i0PLA podman+vagrant
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">The key&lt;span class="err">&amp;#39;&lt;/span>s randomart image is:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">+---&lt;span class="o">[&lt;/span>RSA 4096&lt;span class="o">]&lt;/span>----+
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ....&lt;span class="o">=&lt;/span>B+. ooo ..&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> . ++. ..+oo.+ &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> o .. o +oo &lt;span class="o">=&lt;/span>&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> .o+ &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> S ..&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> . &lt;span class="o">=&lt;/span> . . o&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> . + . B oo&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> . o E X o&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> . .+.&lt;span class="o">=&lt;/span> o.&lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">+----&lt;span class="o">[&lt;/span>SHA256&lt;span class="o">]&lt;/span>-----+
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cat /Users/&amp;lt;USERNAME&amp;gt;/.ssh/id_rsa.pub
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ssh-rsa AAAAB3NzaC1y ... &lt;span class="nv">O3JH8w&lt;/span>&lt;span class="o">==&lt;/span> podman+vagrant
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="create-a-vagrant-vm">Create a vagrant VM&lt;/h3>
&lt;p>We will use a Virtual Machine based on &lt;a href="https://getfedora.org/" target="_blank" rel="noopener">Fedora 33&lt;/a>,&lt;/p>
&lt;p>To create the specified Vagrantfile, we need to follow the next steps:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ mkdir my-fedora &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> my-fedora
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ &lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;Vagrant.configure(&amp;#34;&lt;/span>2&lt;span class="s2">&amp;#34;) do |config|
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> config.vm.box = &amp;#34;&lt;/span>generic/fedora33&lt;span class="s2">&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> config.vm.hostname = &amp;#34;&lt;/span>my-fedora&lt;span class="s2">&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> config.vm.provider &amp;#34;&lt;/span>virtualbox&lt;span class="s2">&amp;#34; do |v|
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> v.memory = 1024
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> v.cpus = 1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> end
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">end&amp;#34;&lt;/span> &amp;gt;&amp;gt; Vagrantfile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="implementation">Implementation&lt;/h2>
&lt;p>At this moment we have:&lt;/p>
&lt;ul>
&lt;li>Podman installed&lt;/li>
&lt;li>A ssh-key with no password created&lt;/li>
&lt;li>A VM created with vagrant&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s start our implementation&lt;/p>
&lt;h3 id="copy-ssh-key-from-macos-to-linux-vm">Copy ssh-key from MacOS to Linux VM&lt;/h3>
&lt;p>We use the &lt;code>ssh-copy-id&lt;/code> command, and it will ask us for the vagrant user password. The default one is: &lt;strong>vagrant&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ ssh-copy-id -i id_rsa.pub vagrant@127.0.0.1 -p &lt;span class="m">2222&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/usr/bin/ssh-copy-id: INFO: Source of key&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span> to be installed: &lt;span class="s2">&amp;#34;id_rsa.pub&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>, to filter out any that are already installed
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/usr/bin/ssh-copy-id: INFO: &lt;span class="m">1&lt;/span> key&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span> remain to be installed -- &lt;span class="k">if&lt;/span> you are prompted now it is to install the new keys
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">vagrant@127.0.0.1&lt;span class="s1">&amp;#39;s password:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">Number of key(s) added: 1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">Now try logging into the machine, with: &amp;#34;ssh -p &amp;#39;&lt;/span>2222&lt;span class="s1">&amp;#39; &amp;#39;&lt;/span>vagrant@127.0.0.1&lt;span class="err">&amp;#39;&lt;/span>&lt;span class="s2">&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">and check to make sure that only the key(s) you wanted were added.
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can verify connectivity with the command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ ssh vagrant@127.0.0.1 -p &lt;span class="m">2222&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Last login: Tue Feb &lt;span class="m">23&lt;/span> 07:33:45 &lt;span class="m">2021&lt;/span> from 10.0.2.5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>vagrant@my-fedora ~&lt;span class="o">]&lt;/span>$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="configure-the-linux-vm">Configure the Linux VM&lt;/h3>
&lt;p>On this step we will:&lt;/p>
&lt;ul>
&lt;li>Install the podman package and dependencies&lt;/li>
&lt;li>Enable the podman service&lt;/li>
&lt;li>Enable the sshd service&lt;/li>
&lt;/ul>
&lt;h4 id="installing-podman">Installing podman&lt;/h4>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">sudo dnf --enablerepo&lt;span class="o">=&lt;/span>updates-testing install podman libvarlink-util libvarlink
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;h4 id="enableling-the-podman-service">Enableling the podman service&lt;/h4>
&lt;p>We can enable and start the service permanently, using the following commands:&lt;/p>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ systemctl --user &lt;span class="nb">enable&lt;/span> --now podman
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;p>Also, we will need to enable linger for this user in order for the socket to work when the user is not logged in.&lt;/p>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">sudo loginctl enable-linger &lt;span class="nv">$USER&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;p>You can verify that the socket is listening with a simple Podman command.&lt;/p>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ podman --remote info
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;h4 id="enableling-the-sshd-service">Enableling the sshd service&lt;/h4>
&lt;p>In order for the client to communicate with the server you need to enable and start the SSH daemon on the Linux VM:&lt;/p>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ sudo systemctl &lt;span class="nb">enable&lt;/span> --now sshd
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;h2 id="using-the-client">Using the client&lt;/h2>
&lt;p>The first step in using the Podman remote client is to configure a &lt;strong>connection&lt;/strong>. To do that, we need can add a connection by using the &lt;code>podman system connection add&lt;/code> command.&lt;/p>
&lt;!-- markdownlint-disable commands-show-output -->
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ podman system connection add &amp;lt;CONNECTION-NAME&amp;gt; ssh://vagrant@127.0.0.1:2222 --identity &amp;lt;SSH-KEY&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ podman system connection add my-fedora ssh://vagrant@127.0.0.1:2222 --identity ~/.ssh/id_rsa.pub
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;!-- markdownlint-restore -->
&lt;p>We can verify that the connection is in place with the command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ podman system connection list
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Name Identity URI
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">my-fedora* ~/.ssh/id_rsa.pub ssh://vagrant@127.0.0.1:2222/run/user/1000/podman/podman.sock
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now we can test the connection with the command:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ podman info
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">host:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> arch: amd64
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> buildahVersion: 1.18.0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cgroupManager: systemd
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cgroupVersion: v2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> conmon:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> package: conmon-2.0.21-3.fc33.x86_64
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> path: /usr/bin/conmon
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> version: &lt;span class="s1">&amp;#39;conmon version 2.0.21, commit: 0f53fb68333bdead5fe4dc5175703e22cf9882ab&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cpus: &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> distribution:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> distribution: fedora
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> version: &lt;span class="s2">&amp;#34;33&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> eventLogger: journald
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> hostname: my-fedora
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Also, you can start running podman commands as you run them in docker:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ podman images
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">REPOSITORY TAG IMAGE ID CREATED SIZE
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="next-steps">Next steps&lt;/h2>
&lt;p>At this point we have installed everything that we need to start using podman on our MacOS, but podman only work if the Linux VM is up &amp;amp; running, otherwise you will receive an error similar to this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ podman images
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Error: Cannot connect to the Podman socket, make sure there is a Podman REST API service running.: failed to create sshClient:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Connection to bastion host &lt;span class="o">(&lt;/span>ssh://vagrant@127.0.0.1:2222/run/user/1000/podman/podman.sock&lt;span class="o">)&lt;/span> failed.: dial tcp 127.0.0.1:2222: connect: connection refused
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To avoid that behavior, what I implement is an automator workflow, here are the steps:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Get the vagrant VM id, to do that run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ vagrant global-status
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">id name provider state directory
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">--------------------------------------------------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">894d683 my-fedora virtualbox running ~/vms/my-fedora
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">The above shows information about all known Vagrant environments
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">on this machine. This data is cached and may not be completely
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">up-to-date &lt;span class="o">(&lt;/span>use &lt;span class="s2">&amp;#34;vagrant global-status --prune&amp;#34;&lt;/span> to prune invalid
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entries&lt;span class="o">)&lt;/span>. To interact with any of the machines, you can go to that
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">directory and run Vagrant, or you can use the ID directly with
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Vagrant commands from any directory. For example:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;vagrant destroy 1a2b3c4d&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As you can see we are interested on get the id column, for this example: &lt;strong>894d683&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Now, we need to open &lt;strong>Automator&lt;/strong>, go to &lt;em>Launchpad -&amp;gt; search -&amp;gt; &lt;strong>type&lt;/strong> automator&lt;/em>, do click on the &lt;strong>Automator&lt;/strong> Application&lt;/p>
&lt;figure id="figure-launchpad-automator">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Launchpad &amp;#43; Automator" srcset="
/media/posts/podman-macos-vagrant/launchpad-automator_hub10fc04977027c8a627d4591d43f2044_117882_472f99b504f26e0be7156c95d5e4e80c.webp 400w,
/media/posts/podman-macos-vagrant/launchpad-automator_hub10fc04977027c8a627d4591d43f2044_117882_f96c2f43695360c40f6572355088b89a.webp 760w,
/media/posts/podman-macos-vagrant/launchpad-automator_hub10fc04977027c8a627d4591d43f2044_117882_1200x1200_fit_q90_h2_lanczos_3.webp 1200w"
src="https://portfolio.devcrumbs.com/media/posts/podman-macos-vagrant/launchpad-automator_hub10fc04977027c8a627d4591d43f2044_117882_472f99b504f26e0be7156c95d5e4e80c.webp"
width="760"
height="192"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption>
Launchpad + Automator
&lt;/figcaption>&lt;/figure>
&lt;/li>
&lt;li>
&lt;p>Then, we need to write an automator application, for this example I choose a workflow that it will run the command &lt;code>vagrant up &amp;lt;VM-ID&amp;gt;&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ vagrant up 894d683
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Bringing machine &lt;span class="s1">&amp;#39;my-fedora&amp;#39;&lt;/span> up with &lt;span class="s1">&amp;#39;virtualbox&amp;#39;&lt;/span> provider...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Checking &lt;span class="k">if&lt;/span> box &lt;span class="s1">&amp;#39;generic/fedora33&amp;#39;&lt;/span> version &lt;span class="s1">&amp;#39;3.2.0&amp;#39;&lt;/span> is up to date...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: A newer version of the box &lt;span class="s1">&amp;#39;generic/fedora33&amp;#39;&lt;/span> &lt;span class="k">for&lt;/span> provider &lt;span class="s1">&amp;#39;virtualbox&amp;#39;&lt;/span> &lt;span class="nv">is&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: available! You currently have version &lt;span class="s1">&amp;#39;3.2.0&amp;#39;&lt;/span>. The latest is &lt;span class="nv">version&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: &lt;span class="s1">&amp;#39;3.2.6&amp;#39;&lt;/span>. Run &lt;span class="sb">`&lt;/span>vagrant box update&lt;span class="sb">`&lt;/span> to update.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Clearing any previously &lt;span class="nb">set&lt;/span> forwarded ports...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Clearing any previously &lt;span class="nb">set&lt;/span> network interfaces...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Preparing network interfaces based on configuration...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> default: Adapter 1: &lt;span class="nv">nat&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Forwarding ports...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> default: &lt;span class="m">22&lt;/span> &lt;span class="o">(&lt;/span>guest&lt;span class="o">)&lt;/span> &lt;span class="o">=&lt;/span>&amp;gt; &lt;span class="m">2222&lt;/span> &lt;span class="o">(&lt;/span>host&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>adapter 1&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Running &lt;span class="s1">&amp;#39;pre-boot&amp;#39;&lt;/span> VM customizations...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Booting VM...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Waiting &lt;span class="k">for&lt;/span> machine to boot. This may take a few minutes...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> default: SSH address: 127.0.0.1:2222
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> default: SSH username: vagrant
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> default: SSH auth method: private &lt;span class="nv">key&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Machine booted and ready!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Checking &lt;span class="k">for&lt;/span> guest additions in VM...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Setting hostname...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: Machine already provisioned. Run &lt;span class="sb">`&lt;/span>vagrant provision&lt;span class="sb">`&lt;/span> or use the &lt;span class="sb">`&lt;/span>--provision&lt;span class="sb">`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">==&lt;/span>&amp;gt; default: flag to force provisioning. Provisioners marked to run always will still run.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;figure id="figure-automator-workflow">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Automator Workflow" srcset="
/media/posts/podman-macos-vagrant/automator-workflow_hu33140a01e2d0efe5b3cf5bd03b1b1e32_62578_671db356fae3c1265815bf2799ad1854.webp 400w,
/media/posts/podman-macos-vagrant/automator-workflow_hu33140a01e2d0efe5b3cf5bd03b1b1e32_62578_e6ac44c59df3f4c80279a56e2b283686.webp 760w,
/media/posts/podman-macos-vagrant/automator-workflow_hu33140a01e2d0efe5b3cf5bd03b1b1e32_62578_1200x1200_fit_q90_h2_lanczos_3.webp 1200w"
src="https://portfolio.devcrumbs.com/media/posts/podman-macos-vagrant/automator-workflow_hu33140a01e2d0efe5b3cf5bd03b1b1e32_62578_671db356fae3c1265815bf2799ad1854.webp"
width="760"
height="656"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption>
Automator Workflow
&lt;/figcaption>&lt;/figure>
&lt;/li>
&lt;li>
&lt;p>Save the Workflow and remember the location where you save it.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>The final step is to add the workflow to our &lt;strong>login items&lt;/strong>. Go to &lt;code>Systems Preferences -&amp;gt; Users &amp;amp; Groups -&amp;gt; Login Items&lt;/code> and add the application that you save on the previous step.&lt;/p>
&lt;figure id="figure-login-items">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Login Items Menu" srcset="
/media/posts/podman-macos-vagrant/login-items_hu93dd3ea80c77a356a834b817262b07a9_45716_97e97a0cb8561eab525154b680b6c691.webp 400w,
/media/posts/podman-macos-vagrant/login-items_hu93dd3ea80c77a356a834b817262b07a9_45716_2bd5042113cdd3dca57352115b6c1390.webp 760w,
/media/posts/podman-macos-vagrant/login-items_hu93dd3ea80c77a356a834b817262b07a9_45716_1200x1200_fit_q90_h2_lanczos_3.webp 1200w"
src="https://portfolio.devcrumbs.com/media/posts/podman-macos-vagrant/login-items_hu93dd3ea80c77a356a834b817262b07a9_45716_97e97a0cb8561eab525154b680b6c691.webp"
width="670"
height="418"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption>
Login Items Menu
&lt;/figcaption>&lt;/figure>
&lt;p>And that is all, you will have a fully working podman command on your MacOS.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>References:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Podman MacOS and windows install &lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/li>
&lt;li>Detailed podman installation on MacOS &lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/li>
&lt;li>Automator Configuration &lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>&lt;/li>
&lt;/ul>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://github.com/containers/podman/blob/master/docs/tutorials/mac_win_client.md" target="_blank" rel="noopener">Podman Remote clients for macOS and Windows&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://vikaspogu.dev/posts/podman-macos/" target="_blank" rel="noopener">Installing Podman remote client on macOS using vagrant&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>&lt;a href="https://stackoverflow.com/questions/30680861/how-can-i-automatically-do-vagrant-up-every-time-my-osx-machine-boots" target="_blank" rel="noopener">How can I automatically do vagrant up every time my OSX machine boots?&lt;/a>&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Docker Login the Right Way</title><link>https://portfolio.devcrumbs.com/docker-login-the-right-way/</link><pubDate>Wed, 15 May 2019 00:00:00 +0000</pubDate><guid>https://portfolio.devcrumbs.com/docker-login-the-right-way/</guid><description>&lt;details class="toc-inpage d-print-none " open>
&lt;summary class="font-weight-bold">Table of Contents&lt;/summary>
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#credential-store">Credential Store&lt;/a>&lt;/li>
&lt;li>&lt;a href="#docker-credential-helpers">Docker Credential Helpers&lt;/a>&lt;/li>
&lt;li>&lt;a href="#docker-credential-secret-service">docker-credential-secret service&lt;/a>&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/details>
&lt;h1 id="docker-login-the-right-way">Docker Login the right Way&lt;/h1>
&lt;p>Hi again!&lt;/p>
&lt;p>It is been a while since I wrote something here, as always, there is no much time for a hobby.&lt;/p>
&lt;p>I&amp;rsquo;ve been working for a while with docker, not a production level, but for some applications that I use at work.
And since the &lt;a href="https://www.zdnet.com/article/docker-hub-hack-exposed-data-of-190000-users/" target="_blank" rel="noopener">Docker Hub Data breach&lt;/a>
I put more atention on the security of my data/credentials, so I investigate a little about and found this official
repository &lt;a href="https://github.com/docker/docker-credential-helpers/" target="_blank" rel="noopener">https://github.com/docker/docker-credential-helpers/&lt;/a> from Docker where are the supported credential helpers.&lt;/p>
&lt;h2 id="credential-store">Credential Store&lt;/h2>
&lt;p>Docker keeps our credentials saved on a JSON file located on &lt;code>~/.docker/config.json&lt;/code>,
but unfortunatelly credentials are just encrypted on base64,
here is an &lt;a href="https://fosdem.org/2019/schedule/event/base64_not_encryption/" target="_blank" rel="noopener">articule/video&lt;/a> where there is an explanation for the why it is a bad idea to just use base64 encryption.&lt;/p>
&lt;p>The following is a diagram on how a plain text storage works:&lt;/p>
&lt;figure id="figure-docker-plain-text-storage">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Plain Text Storage" srcset="
/media/posts/docker-login-the-right-way/DockerPlainTextCredentials_hu371181661409e61f690ceccfb695d5d5_82530_0db582c8916ffc5cd1b1225c42276838.webp 400w,
/media/posts/docker-login-the-right-way/DockerPlainTextCredentials_hu371181661409e61f690ceccfb695d5d5_82530_b27b4b3bd220158c0d85a61a2d4ae88b.webp 760w,
/media/posts/docker-login-the-right-way/DockerPlainTextCredentials_hu371181661409e61f690ceccfb695d5d5_82530_1200x1200_fit_q90_h2_lanczos_3.webp 1200w"
src="https://portfolio.devcrumbs.com/media/posts/docker-login-the-right-way/DockerPlainTextCredentials_hu371181661409e61f690ceccfb695d5d5_82530_0db582c8916ffc5cd1b1225c42276838.webp"
width="760"
height="570"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption>
Plain Text Storage
&lt;/figcaption>&lt;/figure>
&lt;p>Here is an example on how &lt;code>~/.docker/config.json&lt;/code> looks like when is using plain text credentials:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">cat ~/.docker/config.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;auths&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;https://index.docker.io/v1/&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;auth&amp;#34;&lt;/span>: &lt;span class="s2">&amp;#34;azRjaDA6c3VwZXJzZWNyZXRwYXNzd29yZAo=&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;quay.io&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;auth&amp;#34;&lt;/span>: &lt;span class="s2">&amp;#34;azRjaDA6c3VwZXJzZWNyZXRwYXNzd29yZAo=&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;HttpHeaders&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;User-Agent&amp;#34;&lt;/span>: &lt;span class="s2">&amp;#34;Docker-Client/18.09.6 (linux)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After a successful &lt;code>docker login&lt;/code> command,
Docker stores a base64 encoded string from the concatenation of the username, a colon, and the password and associates this string to the registry the user is logging into:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ &lt;span class="nb">echo&lt;/span> &lt;span class="nv">azRjaDA6c3VwZXJzZWNyZXRwYXNzd29yZAo&lt;/span>&lt;span class="o">=&lt;/span> &lt;span class="p">|&lt;/span> base64 -d -
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">d-cmst:supersecretpassword
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A &lt;code>docker logout&lt;/code> command removes the entry from the JSON file for the given registry:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">$ docker &lt;span class="nb">logout&lt;/span> quay.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Remove login credentials &lt;span class="k">for&lt;/span> quay.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ cat ~/.docker/config.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;auths&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;https://index.docker.io/v1/&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;auth&amp;#34;&lt;/span>: &lt;span class="s2">&amp;#34;azRjaDA6c3VwZXJzZWNyZXRwYXNzd29yZAo=&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;HttpHeaders&amp;#34;&lt;/span>: &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;User-Agent&amp;#34;&lt;/span>: &lt;span class="s2">&amp;#34;Docker-Client/18.09.6 (linux)&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="docker-credential-helpers">Docker Credential Helpers&lt;/h2>
&lt;p>Since docker version &lt;code>1.11&lt;/code> implements support from an external credential store for registry authentication.
That means we can use a native keychain of the OS. Using an external store is more secure than storing on a &amp;ldquo;plain text&amp;rdquo; Docker configuration file.&lt;/p>
&lt;figure id="figure-docker-secure-storage">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Secure Storage" srcset="
/media/posts/docker-login-the-right-way/DockerSecureCredentials_huadaed0eecd0771dd576c62f4a77f8685_87803_dfab2c86655b67a2dd7b453f742b7daa.webp 400w,
/media/posts/docker-login-the-right-way/DockerSecureCredentials_huadaed0eecd0771dd576c62f4a77f8685_87803_67d1fdd1b117feb8b3cab43352b4a5be.webp 760w,
/media/posts/docker-login-the-right-way/DockerSecureCredentials_huadaed0eecd0771dd576c62f4a77f8685_87803_1200x1200_fit_q90_h2_lanczos_3.webp 1200w"
src="https://portfolio.devcrumbs.com/media/posts/docker-login-the-right-way/DockerSecureCredentials_huadaed0eecd0771dd576c62f4a77f8685_87803_dfab2c86655b67a2dd7b453f742b7daa.webp"
width="760"
height="543"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption>
Secure Storage
&lt;/figcaption>&lt;/figure>
&lt;p>In order to use a external credential store, we need a program to interact with.&lt;/p>
&lt;p>The actual list of &amp;ldquo;official&amp;rdquo; Docker Credential Helper is:&lt;/p>
&lt;ol>
&lt;li>docker-credential-osxkeychain: Provides a helper to use the OS X keychain as credentials store.&lt;/li>
&lt;li>docker-credential-secretservice: Provides a helper to use the D-Bus secret service as credentials store.&lt;/li>
&lt;li>docker-credential-wincred: Provides a helper to use Windows credentials manager as store.&lt;/li>
&lt;li>docker-credential-pass: Provides a helper to use pass as credentials store.&lt;/li>
&lt;/ol>
&lt;h2 id="docker-credential-secret-service">docker-credential-secret service&lt;/h2>
&lt;p>On this post we will explore the docker-credential-secretservice and how to configure it.&lt;/p>
&lt;ol>
&lt;li>
&lt;p>We need to download and install the helper.
You can find the lastest release on &lt;a href="https://github.com/docker/docker-credential-helpers/releases" target="_blank" rel="noopener">https://github.com/docker/docker-credential-helpers/releases&lt;/a>.
Download it, extract it and make it executable.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">wget https://github.com/docker/docker-credential-helpers/releases/download/v0.6.2/docker-credential-secretservice-v0.6.2-amd64.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">tar -xf docker-credential-secretservice-v0.6.2-amd64.tar.gz
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">chmod +x docker-credential-secretservice
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo mv docker-credential-secretservice /usr/local/bin/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Then, we need to specify the credential store in the file &lt;code>~/.docker/config.json&lt;/code> to tell docker to use it.
The value must be the one after the prefix &lt;code>docker-credential-&lt;/code>. In this case:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;credsStore&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;secretservice&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To facilite the configuration and do not make mistakes, you can run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">sed -i &lt;span class="s1">&amp;#39;0,/{/s/{/{\n\t&amp;#34;credsStore&amp;#34;: &amp;#34;secretservice&amp;#34;,/&amp;#39;&lt;/span> ~/.docker/config.json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;p>From now we are uning an external store, so if you are currently logged in, you must run &lt;code>docker logout&lt;/code> to remove the credentials from the file and run &lt;code>docker login&lt;/code> tostart using the new ones.&lt;/p>
&lt;p>Let me know how this works for you.&lt;/p>
&lt;p>&lt;strong>References:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Docker Credential Helpers repository&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/li>
&lt;li>Docker Credential Store Documentation&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>&lt;/li>
&lt;li>Slides about this topic &lt;sup id="fnref:3">&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref">3&lt;/a>&lt;/sup>&lt;/li>
&lt;/ul>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>&lt;a href="https://github.com/docker/docker-credential-helpers" target="_blank" rel="noopener">Docker Credential Helpers&lt;/a>&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:2">
&lt;p>&lt;a href="https://docs.docker.com/engine/reference/commandline/login/#credentials-store" target="_blank" rel="noopener">docker cli documentation&lt;/a>&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;li id="fn:3">
&lt;p>&lt;a href="https://www.slideshare.net/DavidYeung22/can-we-stop-saving-docker-credentials-in-plain-text-now" target="_blank" rel="noopener">Stop saving credential tokens in text files&lt;/a>&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description></item><item><title>Set a hugo blog on Kubernetes</title><link>https://portfolio.devcrumbs.com/blog-hugo-docker-k8s-quay/</link><pubDate>Mon, 18 Jun 2018 00:00:00 +0000</pubDate><guid>https://portfolio.devcrumbs.com/blog-hugo-docker-k8s-quay/</guid><description>&lt;details class="toc-inpage d-print-none " open>
&lt;summary class="font-weight-bold">Table of Contents&lt;/summary>
&lt;nav id="TableOfContents">
&lt;ul>
&lt;li>&lt;a href="#overview">Overview&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#architecture">Architecture&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#containerized">Containerized&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#dockerfile">Dockerfile&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/nav>
&lt;/details>
&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Since last year I been trying to become an SRE (Site Reliability Engineer), so I been involved with some emerging technologies, like ansible, docker and on this time with kubernetes.&lt;/p>
&lt;p>This time, I will try to explain how I containerized my blog using:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.docker.com/" target="_blank" rel="noopener">Docker&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://kubernetes.io/" target="_blank" rel="noopener">Kubernetes&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://quay.io/" target="_blank" rel="noopener">Quay&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com" target="_blank" rel="noopener">Git&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="architecture">Architecture&lt;/h3>
&lt;p>So, I take some ideas from &lt;a href="https://www.civo.com/learn/using-civo-k3s-service-to-host-your-blog-in-hugo-using-github-actions" target="_blank" rel="noopener">here&lt;/a> and I modify them and adapt the architecture described to my options.&lt;/p>
&lt;p>The principal changes that I made are:&lt;/p>
&lt;ul>
&lt;li>My Kubernetes cluster is running on 2 cloud server on Rackspace Public Cloud&lt;/li>
&lt;li>The container registry that I&amp;rsquo;m using is Quay&lt;/li>
&lt;li>Rackspace Public Cloud does not support a Kubernetes LoadBalancer service automatically,
so I simulate that behavior adding a Cloud Load Balancer manually after the Kubernetes service provide me the port.&lt;/li>
&lt;/ul>
&lt;figure id="figure-blog-hugo-architecture">
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Architecture" srcset="
/media/posts/blog-hugo-docker-k8s-quay/architecture_hu8b96b5b52b85b051d387a2869880f3ab_113861_90038fb3c81eb33b4ff587d44167dbfc.webp 400w,
/media/posts/blog-hugo-docker-k8s-quay/architecture_hu8b96b5b52b85b051d387a2869880f3ab_113861_422b03095e3febbbd91dbb98eee4f1ca.webp 760w,
/media/posts/blog-hugo-docker-k8s-quay/architecture_hu8b96b5b52b85b051d387a2869880f3ab_113861_1200x1200_fit_q90_h2_lanczos_3.webp 1200w"
src="https://portfolio.devcrumbs.com/media/posts/blog-hugo-docker-k8s-quay/architecture_hu8b96b5b52b85b051d387a2869880f3ab_113861_90038fb3c81eb33b4ff587d44167dbfc.webp"
width="760"
height="486"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;figcaption>
Architecture
&lt;/figcaption>&lt;/figure>
&lt;h2 id="containerized">Containerized&lt;/h2>
&lt;p>I use &lt;a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo&lt;/a> to deploy my blog, I used to do it as mentioned on &lt;a href="https://d-cmst.io/deployment-hugo-site-git-hooks/" target="_blank" rel="noopener">this&lt;/a> previous post (In Spanish).&lt;/p>
&lt;p>Now, as a part of containerize the blog it make sense to me to create two stages as described &lt;a href="https://www.civo.com/learn/using-civo-k3s-service-to-host-your-blog-in-hugo-using-github-actions" target="_blank" rel="noopener">here&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>The first stage is a defined build environment containing all required build tools (hugo, pygments) and the source of the website (Git repository).&lt;/li>
&lt;li>The second stage is the build artifact (HTML and assets), from the first stage and a webserver to serve the artifact over HTTP.&lt;/li>
&lt;/ul>
&lt;h3 id="dockerfile">Dockerfile&lt;/h3>
&lt;p>Here is the Dockerfile that containerize the blog:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">FROM ubuntu:latest as STAGEONE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># install hugo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ENV &lt;span class="nv">HUGO_VERSION&lt;/span>&lt;span class="o">=&lt;/span>0.41
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ADD https://github.com/gohugoio/hugo/releases/download/v&lt;span class="si">${&lt;/span>&lt;span class="nv">HUGO_VERSION&lt;/span>&lt;span class="si">}&lt;/span>/hugo_&lt;span class="si">${&lt;/span>&lt;span class="nv">HUGO_VERSION&lt;/span>&lt;span class="si">}&lt;/span>_Linux-64bit.tar.gz /tmp/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">RUN tar -xf /tmp/hugo_&lt;span class="si">${&lt;/span>&lt;span class="nv">HUGO_VERSION&lt;/span>&lt;span class="si">}&lt;/span>_Linux-64bit.tar.gz -C /usr/local/bin/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># install syntax highlighting&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">RUN apt-get update
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">RUN apt-get install -y python3-pygments
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># build site&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">COPY &lt;span class="nb">source&lt;/span> /source
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">RUN hugo --source&lt;span class="o">=&lt;/span>/source/ --destination&lt;span class="o">=&lt;/span>/public/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">FROM nginx:stable-alpine
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">RUN apk --update add curl bash
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">RUN rm /etc/nginx/conf.d/default.conf
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">COPY modules/nginx.d-cmst.io.conf /etc/nginx/conf.d/d-cmst.io.conf
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">COPY --from&lt;span class="o">=&lt;/span>STAGEONE /public/ /usr/share/nginx/html/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">EXPOSE &lt;span class="m">80&lt;/span> &lt;span class="m">443&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">MAINTAINER dcmst &amp;lt;dcmst@gmx.com&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="first-stage">First Stage&lt;/h4>
&lt;ul>
&lt;li>Fetch the lastest Ubuntu image and name as &lt;strong>STAGEONE&lt;/strong>&lt;/li>
&lt;li>Install the last available &lt;strong>hugo&lt;/strong> version from source.&lt;/li>
&lt;li>Install &lt;strong>pygments&lt;/strong> library to use it for highlighting.&lt;/li>
&lt;li>Build the site with &lt;strong>hugo&lt;/strong> and the output is set on &lt;strong>/public&lt;/strong> as a build artifact.&lt;/li>
&lt;/ul>
&lt;h4 id="second-stage">Second Stage&lt;/h4>
&lt;ul>
&lt;li>Fetch the lastest stable nginx alpine image.&lt;/li>
&lt;li>Update the image and install some utilities.&lt;/li>
&lt;li>Delete the &lt;strong>default&lt;/strong> nginx configuration file.&lt;/li>
&lt;li>Copy the configuration files needed from the repository root directory.&lt;/li>
&lt;li>Copy the build artifact &lt;strong>/public&lt;/strong> from the previous stage (&lt;strong>STAGEONE&lt;/strong>)&lt;/li>
&lt;/ul></description></item></channel></rss>