<?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/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Tag: ci/cd - Ryan Daniels</title>
	<atom:link href="https://ryandaniels.ca/blog/tag/ci-cd/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Mon, 13 Dec 2021 19:21:42 +0000</lastBuildDate>
	<language>en-CA</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://ryandaniels.ca/wp-content/uploads/2019/07/img_5907-small-blur-square-100x100.jpg</url>
	<title>Tag: ci/cd - Ryan Daniels</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">22628916</site>	<item>
		<title>Helm Post-Renderer and an ugly Windows Batch Script</title>
		<link>https://ryandaniels.ca/blog/helm-post-renderer-and-ugly-windows-batch-script/</link>
		
		<dc:creator><![CDATA[Ryan Daniels]]></dc:creator>
		<pubDate>Sun, 28 Nov 2021 19:36:00 +0000</pubDate>
				<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[ci/cd]]></category>
		<category><![CDATA[GitLab CI/CD]]></category>
		<category><![CDATA[Helm]]></category>
		<category><![CDATA[IT Automation]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://ryandaniels.ca/?p=2592</guid>

					<description><![CDATA[<p>The year is 2021, and I need to write a Windows Batch Script to get Helm Post-Renderer working on Windows so I can deploy my application to Kubernetes.</p>
<p>The post <a href="https://ryandaniels.ca/blog/helm-post-renderer-and-ugly-windows-batch-script/">Helm Post-Renderer and an ugly Windows Batch Script</a> appeared first on <a href="https://ryandaniels.ca/">Ryan Daniels</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The year is 2021, and I need to write a Windows Batch Script to get Helm Post-Renderer working on Windows so I can deploy my application to Kubernetes.</p>



<span id="more-2592"></span>



<h2 class="wp-block-heading" id="what-is-helm">What is Helm?</h2>



<p>From the <a href="https://helm.sh/" target="_blank" rel="noreferrer noopener">Helm website</a>: &#8220;Helm helps you manage Kubernetes applications&#8221;.<br>If you use Kubernetes, there&#8217;s a good chance you will be using at least some portion of Helm. Helm has many features, and is most well known for Helm Charts. You can (and should) also use Helm to deploy your application to Kubernetes.</p>



<h2 class="wp-block-heading" id="helm-post-renderer">Helm Post-Renderer</h2>



<p>The <a href="https://helm.sh/docs/topics/advanced/" target="_blank" rel="noreferrer noopener">Helm Post-Renderer feature</a> allows Helm to deploy an application using advance configurations using tools like <a href="https://kustomize.io/" target="_blank" rel="noreferrer noopener">Kustomize</a>. </p>



<h2 class="wp-block-heading" id="windows-batch-script-with-helm-post-renderer-and-wsl">Windows Batch Script with Helm Post-Renderer and WSL</h2>



<p>I want my Kubernetes deployment (using Helm and Kustomize) to be able to work on my laptop, and also in a GitLab CI/CD pipeline. And because my Windows laptop has WSL (no WSL2!) I can do a few cool Linux things with it, like directly run Helm commands (Maybe WSL2 also has this problem). If only I could use a <a href="https://ryandaniels.ca/blog/5-reasons-windows-upgrade-to-linux/">real Linux laptop</a> at work, but anyways..</p>



<p>The Helm Post-Renderer gives an error when running a Linux Bash script in WSL. So much to my amazement, in 2021 I needed to write a Windows Batch Script!</p>



<h3 class="wp-block-heading" id="error-message-in-wsl">Error message in WSL</h3>



<p>Running a Helm install/upgrade gives the error:</p>



<pre class="wp-block-code"><code>helm upgrade --install release123 my-charts/app123-charts --version=0.1.0 --namespace=dev1 --values=../values.yaml --post-renderer ./kustomize.sh --debug --dry-run

## Error: error while running post render on files: error while running command \\C\Users\username\helm\my-charts\app123-charts\app-kustomize\kustomize-post-render\kustomize.sh. error output:
## : fork/exec \\C\Users\username\helm\my-charts\app123-charts\app-kustomize\kustomize-post-render\kustomize.sh: %1 is not a valid Win32 application.</code></pre>



<p>Just the error:</p>



<pre class="wp-block-code"><code>%1 is not a valid Win32 application.</code></pre>



<p>Okay, that&#8217;s interesting. Running a helm command gives me a Windows related error. So now we need to do it the Windows way.</p>



<h2 class="wp-block-heading" id="helm-post-renderer-windows-batch-script">Helm Post-Renderer Windows Batch Script</h2>



<p>This Windows Batch Script will work from Windows (kustomize.bat):</p>



<pre class="wp-block-code"><code>@echo off

REM fix mapped drive in TS: https://stackoverflow.com/questions/9013941/how-to-run-batch-file-from-network-share-without-unc-path-are-not-supported-me/34182234#34182234
@pushd %~dp0

REM findstr is pure windows command: https://superuser.com/questions/853580/real-windows-equivalent-to-cat-stdin/1425671#1425671
FINDSTR . &gt; all.yaml

kustomize build . &amp;&amp; del all.yaml || exit 1

@popd

</code></pre>



<p>The above Batch Script also works from a Windows Terminal Server that is mapping a drive.</p>



<h2 class="wp-block-heading" id="helm-post-renderer-linux-bash-script">Helm Post-Renderer Linux Bash script</h2>



<p>For reference, the same in Linux would be (kustomize.sh):</p>



<pre class="wp-block-code"><code>#!/bin/bash

cat &lt;&amp;0 &gt; all.yaml

kustomize build . &amp;&amp; rm all.yaml</code></pre>



<p>Above Linux bash script source: <a href="https://github.com/thomastaylor312/advanced-helm-demos/blob/master/post-render/kustomize/kustomize" target="_blank" rel="noreferrer noopener">Taylor Thomas</a>.</p>



<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>



<p>With this Windows Batch Script, you can run Helm install/upgrade commands directly on your Windows laptop so you can deploy to your local or remote Kubernetes cluster. This can help to debug your true pipeline deployments, if using something like GitLab CI/CD since it&#8217;s now possible to deploy using the same method.</p>
<p>The post <a href="https://ryandaniels.ca/blog/helm-post-renderer-and-ugly-windows-batch-script/">Helm Post-Renderer and an ugly Windows Batch Script</a> appeared first on <a href="https://ryandaniels.ca/">Ryan Daniels</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2592</post-id>	</item>
		<item>
		<title>Dockerfile ARG FROM ARG trouble with Docker</title>
		<link>https://ryandaniels.ca/blog/docker-dockerfile-arg-from-arg-trouble/</link>
		
		<dc:creator><![CDATA[Ryan Daniels]]></dc:creator>
		<pubDate>Mon, 30 Dec 2019 15:24:00 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<category><![CDATA[ci/cd]]></category>
		<category><![CDATA[Guide]]></category>
		<guid isPermaLink="false">https://ryandaniels.ca/?p=2017</guid>

					<description><![CDATA[<figure class="alignleft size-thumbnail"><a href="https://ryandaniels.ca/blog/docker-dockerfile-arg-from-arg-trouble"><img src="https://ryandaniels.ca/wp-content/uploads/2019/12/Dockerfile_ARG-300x266.jpg" alt="Dockerfile ARG" class="wp-image-2033"/></a></figure>
<p>Using a dynamic Dockerfile can have great benefits when used in your CI/CD pipeline. You can use the ARG statement in your Dockerfile to pass in a variable at build time. Even use a variable in the FROM statement!<br />
&#160;</p>
<p>The post <a href="https://ryandaniels.ca/blog/docker-dockerfile-arg-from-arg-trouble/">Dockerfile ARG FROM ARG trouble with Docker</a> appeared first on <a href="https://ryandaniels.ca/">Ryan Daniels</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="564" height="500" src="https://ryandaniels.ca/wp-content/uploads/2019/12/Dockerfile_ARG.jpg" alt="Dockerfile ARG" class="wp-image-2033" srcset="https://ryandaniels.ca/wp-content/uploads/2019/12/Dockerfile_ARG.jpg 564w, https://ryandaniels.ca/wp-content/uploads/2019/12/Dockerfile_ARG-300x266.jpg 300w" sizes="(max-width: 564px) 100vw, 564px" /></figure></div>



<p>Using a dynamic <a rel="noreferrer noopener" aria-label="Dockerfile (opens in a new tab)" href="https://docs.docker.com/engine/reference/builder/" target="_blank">Dockerfile</a> can have great benefits when used in your CI/CD pipeline. You can use the <code>ARG</code> statement in your <code>Dockerfile</code> to pass in a variable at build time. Even use a variable in the <code>FROM</code> statement! Dockerfile ARG FROM ARG. That will make more sense later.</p>



<span id="more-2017"></span>



<p>This post is about <a rel="noreferrer noopener" aria-label="Container virtualization technology (opens in a new tab)" href="https://rancher.com/learning-paths/what-are-containers/" target="_blank">Container virtualization technology</a>, and problems when building a container image using <a rel="noreferrer noopener" aria-label="Docker Engine (opens in a new tab)" href="https://www.docker.com/products/container-runtime" target="_blank">Docker Engine</a>. <br>For some background on a dynamic Dockerfile, check out <a rel="noreferrer noopener" aria-label="Jeff Geerling's post (opens in a new tab)" href="https://www.jeffgeerling.com/blog/2017/use-arg-dockerfile-dynamic-image-specification" target="_blank">Jeff Geerling&#8217;s post</a>.</p>



<p>One problem I&#8217;ve come across with this, is the <code>Dockerfile</code> <code>ARG</code> variable usage isn&#8217;t intuitive. It is actually kind of weird. And I&#8217;m not alone on this! There&#8217;s lots of feedback in <a rel="noreferrer noopener" aria-label="GitHub Issue #34129 (opens in a new tab)" href="https://github.com/moby/moby/issues/34129" target="_blank">GitHub Issue #34129</a>. </p>



<h2 class="wp-block-heading">What&#8217;s the Problem?</h2>



<p>A variable declared at the top of the <code>Dockerfile</code> using <code>ARG</code> doesn&#8217;t work if you try to use it after the <code>FROM</code> statement. Not by default at least. It only works if used in the <code>FROM</code> statement. </p>



<pre class="wp-block-code"><code>ARG TAG=latest
FROM myimage:$TAG # &lt;------ This works!
LABEL BASE_IMAGE="myimage:$TAG" # &lt;------ Does not work!</code></pre>



<p>The <code>FROM</code> above will use the <code>TAG</code> passed in from a build-arg, or default to use the string &#8220;latest&#8221;.<br>But the <code>LABEL</code> won&#8217;t work. The <code>TAG</code> portion will be empty!</p>



<p>This was tested with the most recent version of Docker Engine (version: 19.03.5).</p>



<h2 class="wp-block-heading">How Does it Work?</h2>



<p>To use a variable in the <code>FROM</code> section, you need to put the <code>ARG</code> before the <code>FROM</code>. So far so good. But, now let&#8217;s use that variable again after the <code>FROM</code>? No you can&#8217;t. It&#8217;s not there. Unless you use another <code>ARG</code> statement after the <code>FROM</code>.<br>Wait, it gets more weird. Any <code>ARG</code> before the FIRST <code>FROM</code>, can be used in any <code>FROM</code> (for multi-stage builds). In fact the <code>ARG</code> must be above the first <code>FROM</code> even if you only want to use it in a later <code>FROM</code>. Wow, that&#8217;s a lot of <code>ARG</code>s and <code>FROM</code>s. The <code>ARG</code> is kind of &#8220;global&#8221; but only if you declare it again inside the build stage.</p>



<h2 class="wp-block-heading">Dockerfile ARG FROM ARG</h2>



<p>Let&#8217;s look at an example to make it easier. Below is not a useful Dockerfile. It&#8217;s only an example to illustrate this.</p>



<pre class="wp-block-code"><code>#These ARGs are used in the FROM statements
#Or as global variables if declared again (without the default value)
ARG BUILDER_TAG=latest
ARG BASE_TAG=latest
ARG APP="app.go"

#First build stage
FROM mybuildapp:$BUILDER_TAG AS builder
ARG APP
RUN compile_my_app $APP

#Second build stage
FROM registry.access.redhat.com/ubi8/ubi-minimal:$BASE_TAG
ARG BASE_TAG
ARG APP
LABEL BASE_IMAGE="registry.access.redhat.com/ubi8/ubi-minimal:$BASE_TAG"
COPY --from=builder $APP .</code></pre>



<p>Now, let&#8217;s run the example build:</p>



<pre class="wp-block-code"><code>docker build . \
  --pull
  --build-arg BUILDER_TAG="2.0" \
  --build-arg BASE_TAG="8.1" \
  --build-arg APP="the_best_app.go" \
  -t image_tag</code></pre>



<p>Once the Docker build finishes, this is the result of your command line argument usage inside the docker image:</p>



<pre class="wp-block-code"><code>BUILDER_TAG="2.0"
BASE_TAG="8.1"
APP="the_best_app.go"</code></pre>



<h2 class="wp-block-heading">Results</h2>



<p>The <code>BUILDER_TAG</code> and <code>BASE_TAG</code> will be used in the <code>FROM</code> statements. <code>BASE_TAG</code> is also used inside the second build stage. And <code>APP</code> will be used in both build stages. <code>ARG APP="app.go"</code> only needs to be declared if you want to set a default value. In my example we don&#8217;t really need that since we are passing in a build argument.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Remember that <code>ARG</code>s at the top of the <code>Dockerfile</code> can be used in the <code>FROM</code> statements. They are &#8220;global&#8221; only if you declare the <code>ARG</code> again in each build stage (after <code>FROM</code> (and before the next <code>FROM</code> if using a multi-stage build)).<br>You can remember it this way: <code>Dockerfile</code> <code>ARG</code> <code>FROM</code> <code>ARG</code><br>But, after wasting an hour on this, it was more like: Dockerfile <em>Arrggh!</em> FROM <em>Arrggh!</em></p>



<p>You can use something like this in your CI/CD, for automatic docker image building. </p>



<p><strong>Side note</strong>: Building an image using <a rel="noreferrer noopener" aria-label="Podman (opens in a new tab)" href="https://podman.io/" target="_blank">Podman</a> does not have the same issue as Docker Engine (tested with Podman version 1.4.4, 1.6.3, and 1.7.0). You do not need to specify the <code>ARG</code> again inside the build stage when Podman creates the container image!</p>



<p>Further reading:<br><a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact" target="_blank">Dockerfile Reference: Understand how ARG and FROM interact</a><br><a rel="noreferrer noopener" aria-label="Dockerfile Reference: Scope (opens in a new tab)" href="https://docs.docker.com/engine/reference/builder/#scope" target="_blank">Dockerfile Reference: Scope</a><br><a href="https://docs.docker.com/develop/develop-images/multistage-build" target="_blank" rel="noreferrer noopener" aria-label="Multi-Stage Builds (opens in a new tab)">Multi-Stage Builds</a></p>
<p>The post <a href="https://ryandaniels.ca/blog/docker-dockerfile-arg-from-arg-trouble/">Dockerfile ARG FROM ARG trouble with Docker</a> appeared first on <a href="https://ryandaniels.ca/">Ryan Daniels</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2017</post-id>	</item>
	</channel>
</rss>
