<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hideki Igarashi</title>
    <description>The latest articles on DEV Community by Hideki Igarashi (@hideki).</description>
    <link>https://dev.to/hideki</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F42385%2F4863d13e-5034-4a97-b62e-92614fb93ca6.png</url>
      <title>DEV Community: Hideki Igarashi</title>
      <link>https://dev.to/hideki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hideki"/>
    <language>en</language>
    <item>
      <title>Build and push a Docker/OCI image with kaniko + GitHub Packages</title>
      <dc:creator>Hideki Igarashi</dc:creator>
      <pubDate>Wed, 04 Dec 2019 03:41:08 +0000</pubDate>
      <link>https://dev.to/hideki/build-and-push-a-docker-oci-image-with-kaniko-github-packages-ee</link>
      <guid>https://dev.to/hideki/build-and-push-a-docker-oci-image-with-kaniko-github-packages-ee</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/features/packages"&gt;GitHub Packages&lt;/a&gt; provides a Docker container management platform.&lt;/p&gt;

&lt;p&gt;This article introduces how to push an image using it as a repository of &lt;a href="https://github.com/GoogleContainerTools/kaniko"&gt;kaniko&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;kaniko is a tool for Kubernetes, but you can use it without Kubernetes.&lt;/p&gt;

&lt;p&gt;By using kaniko, there is a benefit of using the cache with GitHub Packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push image from the local environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Generate a personal access token
&lt;/h3&gt;

&lt;p&gt;Generate a personal access token to access the registry in your &lt;a href="https://github.com/settings/tokens/new?scopes=repo,write:packages,read:packages,delete:packages"&gt;GitHub settings&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The token needs the following scopes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repo&lt;/li&gt;
&lt;li&gt;write:packages&lt;/li&gt;
&lt;li&gt;read:packages&lt;/li&gt;
&lt;li&gt;delete:packages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create a config.json
&lt;/h3&gt;

&lt;p&gt;Get your GitHub username and token encoded in base64:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; username:access_token | &lt;span class="nb"&gt;base64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;config.json&lt;/code&gt; file with GitHub package registry hostname and the previous generated base64 string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"auths"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"docker.pkg.github.com"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"auth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"xxxxxxxxxxxxxxxxx"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Run kaniko
&lt;/h3&gt;

&lt;p&gt;Run kaniko with the &lt;code&gt;config.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, put the &lt;code&gt;Dockerfile&lt;/code&gt; you want to build in the same directory.&lt;/p&gt;

&lt;p&gt;The command to execute is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/workspace &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/config.json:/kaniko/.docker/config.json:ro &lt;span class="se"&gt;\&lt;/span&gt;
  gcr.io/kaniko-project/executor:latest &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--context&lt;/span&gt; &lt;span class="nb"&gt;dir&lt;/span&gt;:///workspace/ &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dockerfile&lt;/span&gt; Dockerfile &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--destination&lt;/span&gt; docker.pkg.github.com/&amp;lt;org&amp;gt;/&amp;lt;repos&amp;gt;/&amp;lt;image&amp;gt;:&amp;lt;tag&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--cache&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--cache-repo&lt;/span&gt; docker.pkg.github.com/&amp;lt;org&amp;gt;/&amp;lt;repos&amp;gt;/&amp;lt;image&amp;gt;-cache
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The cache repository is separate from the destination because GitHub Packages does not support &lt;code&gt;&amp;lt;org&amp;gt;/&amp;lt;repos&amp;gt;/&amp;lt;image&amp;gt;/cache&lt;/code&gt; style.&lt;/p&gt;

&lt;h2&gt;
  
  
  Push image from GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Full example: &lt;a href="https://github.com/ganta/example-kaniko-with-github-packages"&gt;https://github.com/ganta/example-kaniko-with-github-packages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, the workflow runs under the following conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When pushed to a branch except for the master, build an image&lt;/li&gt;
&lt;li&gt;When pushed to the master branch, add the latest tag and push the image&lt;/li&gt;
&lt;li&gt;When you push a tag in the version number format, add the tag of that number and push the image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create two workflows to build and push.&lt;/p&gt;

&lt;p&gt;To run the build workflow on a branch excluding master (&lt;code&gt;.github/workflows/build.yml&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches-ignore&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To run the push workflow on the master branch or a version number format tag (&lt;code&gt;.github/workflows/push.yml&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[0-9]+.[0-9]+.[0-9]+'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[0-9]+.[0-9]+.[0-9]+-*'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Add a step to generate &lt;code&gt;config.json&lt;/code&gt; to pass GitHub Packages authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate a config.json&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cat &amp;lt;&amp;lt;JSON &amp;gt; config.json&lt;/span&gt;
          &lt;span class="s"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"auths": {&lt;/span&gt;
              &lt;span class="s"&gt;"docker.pkg.github.com": {&lt;/span&gt;
                &lt;span class="s"&gt;"auth": "$(echo -n :${{ secrets.GITHUB_TOKEN }} | base64)"&lt;/span&gt;
              &lt;span class="s"&gt;}&lt;/span&gt;
            &lt;span class="s"&gt;}&lt;/span&gt;
          &lt;span class="s"&gt;}&lt;/span&gt;
          &lt;span class="s"&gt;JSON&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When using &lt;code&gt;secrets.GITHUB_TOKEN&lt;/code&gt;, the user name is not required.&lt;/p&gt;

&lt;p&gt;The execution method of kaniko is the same as when executing locally.&lt;/p&gt;

&lt;p&gt;For builds, use the &lt;code&gt;--no-push&lt;/code&gt; option instead of the&lt;code&gt;--destination&lt;/code&gt; option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build an image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker run \&lt;/span&gt;
            &lt;span class="s"&gt;-v $(pwd):/workspace \&lt;/span&gt;
            &lt;span class="s"&gt;-v $(pwd)/config.json:/kaniko/.docker/config.json:ro \&lt;/span&gt;
            &lt;span class="s"&gt;gcr.io/kaniko-project/executor:latest \&lt;/span&gt;
              &lt;span class="s"&gt;--context dir:///workspace/ \&lt;/span&gt;
              &lt;span class="s"&gt;--dockerfile Dockerfile \&lt;/span&gt;
              &lt;span class="s"&gt;--cache=true \&lt;/span&gt;
              &lt;span class="s"&gt;--cache-repo docker.pkg.github.com/${GITHUB_REPOSITORY}/${IMAGE_NAME}-cache \&lt;/span&gt;
              &lt;span class="s"&gt;--no-push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the case of a push, you can get the tag to attach to the image from the &lt;code&gt;GITHUB_REF&lt;/code&gt; environment variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push an image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;tag=${GITHUB_REF##*/}&lt;/span&gt;

          &lt;span class="s"&gt;if [[ ${tag} == master ]]&lt;/span&gt;
          &lt;span class="s"&gt;then&lt;/span&gt;
            &lt;span class="s"&gt;tag="latest"&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
          &lt;span class="s"&gt;echo "tag: ${tag}"&lt;/span&gt;

          &lt;span class="s"&gt;docker run \&lt;/span&gt;
            &lt;span class="s"&gt;-v $(pwd):/workspace \&lt;/span&gt;
            &lt;span class="s"&gt;-v $(pwd)/config.json:/kaniko/.docker/config.json:ro \&lt;/span&gt;
            &lt;span class="s"&gt;gcr.io/kaniko-project/executor:latest \&lt;/span&gt;
              &lt;span class="s"&gt;--context dir:///workspace/ \&lt;/span&gt;
              &lt;span class="s"&gt;--dockerfile Dockerfile \&lt;/span&gt;
              &lt;span class="s"&gt;--destination docker.pkg.github.com/${GITHUB_REPOSITORY}/${IMAGE_NAME}:${tag} \&lt;/span&gt;
              &lt;span class="s"&gt;--cache=true \&lt;/span&gt;
              &lt;span class="s"&gt;--cache-repo docker.pkg.github.com/${GITHUB_REPOSITORY}/${IMAGE_NAME}-cache&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this way, you can smoothly run kaniko with GitHub Packages.&lt;/p&gt;

&lt;p&gt;Also, you can use &lt;code&gt;secrets.GITHUB_TOKEN&lt;/code&gt; in GitHub Actions, so you don't have to struggle with authentication.&lt;/p&gt;

&lt;p&gt;Even if you are not in Kubernetes, you can benefit from caching by using kaniko instead of &lt;code&gt;docker build&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>github</category>
      <category>kaniko</category>
    </item>
  </channel>
</rss>
