<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Artifact Registry &#8211; My Shitty Code</title>
	<atom:link href="https://myshittycode.com/tag/artifact-registry/feed/" rel="self" type="application/rss+xml" />
	<link>https://myshittycode.com</link>
	<description>Embracing the Messiness in Search of Epic Solutions</description>
	<lastBuildDate>Thu, 21 Mar 2024 14:26:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://myshittycode.com/wp-content/uploads/2022/04/cropped-icon-32x32.png</url>
	<title>Artifact Registry &#8211; My Shitty Code</title>
	<link>https://myshittycode.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">205304208</site>	<item>
		<title>Supercharge Docker Build Pipeline by 97%</title>
		<link>https://myshittycode.com/2024/03/21/supercharge-docker-build-pipeline/</link>
					<comments>https://myshittycode.com/2024/03/21/supercharge-docker-build-pipeline/#respond</comments>
		
		<dc:creator><![CDATA[Shitty Author]]></dc:creator>
		<pubDate>Thu, 21 Mar 2024 14:26:02 +0000</pubDate>
				<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Development Tools]]></category>
		<category><![CDATA[Artifact Registry]]></category>
		<category><![CDATA[Cloud Build]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Google Cloud Platform]]></category>
		<guid isPermaLink="false">https://myshittycode.com/?p=2568</guid>

					<description><![CDATA[<p>This tutorial shows how to improve the performance of the remote pipeline that builds a Docker image using docker build, which takes 15 minutes to 20 seconds. Note: Although Google&#8217;s Cloud Build is used here, this solution can be applied in GitHub Actions, Azure Pipeline, or any pipeline-driven Docker builds. The Challenge with Docker Build [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2024/03/21/supercharge-docker-build-pipeline/">Supercharge Docker Build Pipeline by 97%</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><h2>Table of Contents</h2><nav><ul><li><a href="#the-challenge-with-docker-build">The Challenge with Docker Build</a></li><li><a href="#solution">Solution</a><ul><li><a href="#introducing-buildx">Introducing Buildx</a></li><li><a href="#step-1-enable-experimental-mode">Step 1: Enable experimental mode</a></li><li><a href="#step-2-specify-build-driver">Step 2: Specify build driver</a></li><li><a href="#step-3-configure-build-caches">Step 3: Configure build caches</a></li><li><a href="#step-4-putting-everything-together">Step 4: Putting everything together</a></li><li><a href="#step-5-analyze-build-results">Step 5: Analyze build results</a></li><li><a href="#step-6-verify-image-repository">Step 6: Verify image repository</a></li></ul></li></ul></nav></div>



<p>This tutorial shows how to improve the performance of the remote pipeline that builds a Docker image using <strong>docker build</strong>, which takes 15 minutes to 20 seconds.</p>



<p><strong>Note:</strong> Although Google&#8217;s Cloud Build is used here, this solution can be applied in GitHub Actions, Azure Pipeline, or any pipeline-driven Docker builds.</p>



<h2 class="wp-block-heading" id="the-challenge-with-docker-build">The Challenge with Docker Build</h2>



<p>Given the following Google&#8217;s Cloud Build script:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# cloudbuild.yml

steps:
  - name: gcr.io/cloud-builders/docker
    args: &#x5B;&quot;build&quot;, &quot;-t&quot;, &quot;${_NAME}&quot;, &quot;.&quot;]

images:
  - ${_NAME}

substitutions:
  _LOCATION: us-central1
  _REPO: shared
  _IMAGE: chatbot
  _NAME: ${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPO}/${_IMAGE}

options:
  logging: CLOUD_LOGGING_ONLY
  machineType: E2_HIGHCPU_32
  dynamicSubstitutions: true
</pre></div>


<p>When kicking off the build&#8230;</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
gcloud builds submit --config=cloudbuild.yml --project=&#x5B;PROJECT ID]
</pre></div>


<p>&#8230; Docker builds the image successfully and pushes it to the Artifact Registry.</p>



<p>When rerunning the same build multiple times, it takes similar time to run:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="192" src="https://myshittycode.com/wp-content/uploads/2024/03/docker-build-before-1-1024x192.png?x45560" alt="" class="wp-image-2570" srcset="https://myshittycode.com/wp-content/uploads/2024/03/docker-build-before-1-1024x192.png 1024w, https://myshittycode.com/wp-content/uploads/2024/03/docker-build-before-1-300x56.png 300w, https://myshittycode.com/wp-content/uploads/2024/03/docker-build-before-1-768x144.png 768w, https://myshittycode.com/wp-content/uploads/2024/03/docker-build-before-1.png 1346w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>In the example above, building the image with no changes to the Dockerfile takes an average of 15 minutes.</p>



<h2 class="wp-block-heading" id="solution">Solution</h2>



<p>When running the build locally, Docker takes advantage of the layer caching by storing the data in the file system. This results in faster subsequent builds. </p>



<p>However, when using a remote pipeline, the agent assigned to the pipeline job is ephemeral. Hence, Docker must always rebuild all layers, resulting in a long build time. To fix this annoyance, we must instruct Docker to cache the layers elsewhere. </p>



<h3 class="wp-block-heading" id="introducing-buildx">Introducing Buildx</h3>



<p>Docker has a relatively unheard CLI command called Buildx that allows the layers to be cached remotely. <a href="https://docs.docker.com/build/architecture/" target="_blank" rel="noopener">Buildx has been the default build client</a> since Docker Engine 23.0 and Docker Desktop 4.19.</p>



<p>To investigate, run the following commands locally to verify:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [5]; title: ; notranslate">
$ docker --version
Docker version 25.0.3, build 4debf41

$ docker build --help
Usage:  docker buildx build &#x5B;OPTIONS] PATH | URL | -

// TRUNCATED
</pre></div>


<h3 class="wp-block-heading" id="step-1-enable-experimental-mode">Step 1: Enable experimental mode</h3>



<p>At the time of writing, Google&#8217;s Cloud Build uses a Docker version older than v23.0.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="180" src="https://myshittycode.com/wp-content/uploads/2024/03/cloudbuild-docker-version-1024x180.png?x45560" alt="" class="wp-image-2576" srcset="https://myshittycode.com/wp-content/uploads/2024/03/cloudbuild-docker-version-1024x180.png 1024w, https://myshittycode.com/wp-content/uploads/2024/03/cloudbuild-docker-version-300x53.png 300w, https://myshittycode.com/wp-content/uploads/2024/03/cloudbuild-docker-version-768x135.png 768w, https://myshittycode.com/wp-content/uploads/2024/03/cloudbuild-docker-version.png 1396w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Hence, an environment variable must be set to enable the experimental mode when using an older Docker version.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [7,8]; title: ; notranslate">
# cloudbuild.yml

options:
  logging: CLOUD_LOGGING_ONLY
  machineType: E2_HIGHCPU_32
  dynamicSubstitutions: true
  env:
    - DOCKER_CLI_EXPERIMENTAL=enabled
</pre></div>


<h3 class="wp-block-heading" id="step-2-specify-build-driver">Step 2: Specify build driver</h3>



<p>A different Docker driver must be explicitly specified to use the layer caching feature in the older Docker version.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# cloudbuild.yml

steps:
  - name: gcr.io/cloud-builders/docker
    entrypoint: bash
    args:
      - -c
      - &gt;-
        docker buildx create
        --driver docker-container
        --use
</pre></div>


<h3 class="wp-block-heading" id="step-3-configure-build-caches">Step 3: Configure build caches</h3>



<p>Now, configure Docker to fetch and store the caches.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# cloudbuild.yml

steps:
  # ...

  - name: gcr.io/cloud-builders/docker
    entrypoint: bash
    args:
      - -c
      - &gt;-
        docker buildx build
        --cache-from ${_NAME}:cache
        --cache-to type=registry,ref=${_NAME}:cache,mode=max
        -t ${_NAME} .
        --push
</pre></div>


<p>In this example, the cache image is stored in the same image repository in Artifact Registry but with a different tag, <strong>cache</strong>.</p>



<p>To ensure all layers&#8217; build information is cached, <strong>mode=max</strong> is specified, too.</p>



<h3 class="wp-block-heading" id="step-4-putting-everything-together">Step 4: Putting everything together</h3>



<p>The modified build file looks like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
# cloudbuild.yml

steps:
  - name: gcr.io/cloud-builders/docker
    entrypoint: bash
    args:
      - -c
      - &gt;-
        docker buildx create
        --driver docker-container
        --use

  - name: gcr.io/cloud-builders/docker
    entrypoint: bash
    args:
      - -c
      - &gt;-
        docker buildx build
        --cache-from ${_NAME}:cache
        --cache-to type=registry,ref=${_NAME}:cache,mode=max
        -t ${_NAME} .
        --push

substitutions:
  _LOCATION: us-central1
  _REPO: shared
  _IMAGE: chatbot
  _NAME: ${_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${_REPO}/${_IMAGE}

options:
  logging: CLOUD_LOGGING_ONLY
  machineType: E2_HIGHCPU_32
  dynamicSubstitutions: true
  env:
    - DOCKER_CLI_EXPERIMENTAL=enabled
</pre></div>


<h3 class="wp-block-heading" id="step-5-analyze-build-results">Step 5: Analyze build results</h3>



<p>Now, submit the build multiple times to examine the results.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="232" src="https://myshittycode.com/wp-content/uploads/2024/03/docker-build-after-1024x232.png?x45560" alt="" class="wp-image-2580" srcset="https://myshittycode.com/wp-content/uploads/2024/03/docker-build-after-1024x232.png 1024w, https://myshittycode.com/wp-content/uploads/2024/03/docker-build-after-300x68.png 300w, https://myshittycode.com/wp-content/uploads/2024/03/docker-build-after-768x174.png 768w, https://myshittycode.com/wp-content/uploads/2024/03/docker-build-after.png 1352w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The build logs show that the first run takes about 12 minutes because the cache has yet to exist. Once the cache exists, the subsequent build takes an average of 20 seconds.</p>



<p>The reason for the gap between 4 PM and 7 PM was that nobody had the time to sit for 12 minutes for the build to finish.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="543" height="460" src="https://myshittycode.com/wp-content/uploads/2024/03/beer.jpg?x45560" alt="" class="wp-image-2581" srcset="https://myshittycode.com/wp-content/uploads/2024/03/beer.jpg 543w, https://myshittycode.com/wp-content/uploads/2024/03/beer-300x254.jpg 300w" sizes="auto, (max-width: 543px) 100vw, 543px" /></figure>



<h3 class="wp-block-heading" id="step-6-verify-image-repository">Step 6: Verify image repository</h3>



<p>The images stored in the Artifact Registry look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="483" src="https://myshittycode.com/wp-content/uploads/2024/03/image-artifact-registry-1-1024x483.png?x45560" alt="" class="wp-image-2589" srcset="https://myshittycode.com/wp-content/uploads/2024/03/image-artifact-registry-1-1024x483.png 1024w, https://myshittycode.com/wp-content/uploads/2024/03/image-artifact-registry-1-300x142.png 300w, https://myshittycode.com/wp-content/uploads/2024/03/image-artifact-registry-1-768x363.png 768w, https://myshittycode.com/wp-content/uploads/2024/03/image-artifact-registry-1-1536x725.png 1536w, https://myshittycode.com/wp-content/uploads/2024/03/image-artifact-registry-1.png 1716w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>As you can see, the final image (with the <strong>latest</strong> tag) and the cache image (with the <strong>cache</strong> tag) are successfully stored in the Artifact Registry. The 20-second build is exclusively spent pulling a few gigabytes of cache image from the Artifact Registry.</p>
<p>The post <a rel="nofollow" href="https://myshittycode.com/2024/03/21/supercharge-docker-build-pipeline/">Supercharge Docker Build Pipeline by 97%</a> appeared first on <a rel="nofollow" href="https://myshittycode.com">My Shitty Code</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://myshittycode.com/2024/03/21/supercharge-docker-build-pipeline/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2568</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)
Database Caching using Disk

Served from: myshittycode.com @ 2026-02-21 14:44:09 by W3 Total Cache
-->