<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Deploying Elixir]]></title><description><![CDATA[Screencasts about cloud, devops and deployment strategies. All of them however in scope of Elixir language.]]></description><link>https://deployingelixir.eu</link><image><url>https://substackcdn.com/image/fetch/$s_!-jPw!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1cdbc46e-bd1e-448b-b807-84df7c705d0e_900x900.png</url><title>Deploying Elixir</title><link>https://deployingelixir.eu</link></image><generator>Substack</generator><lastBuildDate>Sun, 10 May 2026 19:47:16 GMT</lastBuildDate><atom:link href="https://deployingelixir.eu/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Piotr Szmielew]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[deployingelixir@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[deployingelixir@substack.com]]></itunes:email><itunes:name><![CDATA[Piotr Szmielew]]></itunes:name></itunes:owner><itunes:author><![CDATA[Piotr Szmielew]]></itunes:author><googleplay:owner><![CDATA[deployingelixir@substack.com]]></googleplay:owner><googleplay:email><![CDATA[deployingelixir@substack.com]]></googleplay:email><googleplay:author><![CDATA[Piotr Szmielew]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Resilience when using Google Kubernetes in Autopilot mode]]></title><link>https://deployingelixir.eu/p/resilience-when-using-google-kubernetes</link><guid isPermaLink="false">https://deployingelixir.eu/p/resilience-when-using-google-kubernetes</guid><dc:creator><![CDATA[Piotr Szmielew]]></dc:creator><pubDate>Thu, 16 Oct 2025 08:01:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4vEf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>Please note that this blog post has been originally published on <a href="https://blog.musicglue.tech/">blog.musicglue.tech</a> company blog.</em></p><p>&#8230;or a little story about how everything isn&#8217;t provided by default.</p><h3>The current state of affairs</h3><p>I will be describing an example app &#8211; dockerised, stateless and more-or-less follows the Twelve-Factor App methodology &#8211; deployed on a Kubernetes cluster. Let&#8217;s say an e-commerce store, although it doesn&#8217;t matter that much in this particular note. The cluster itself is running in autopilot mode, which means Google provisions and de-provisions nodes for us, while we&#8217;re paying only for the resources we&#8217;re using, but we&#8217;re also giving up administrative control of the nodes.</p><h3>How we can guarantee resilience when using GKE in autopilot mode</h3><p>When using GKE autopilot cluster in regional mode, it gives you resilience (as in: control plane access) out of the box. Since we don&#8217;t control nodes, and the the control plane is replicated, then we expect the same for our workloads. However when using default pod settings and deployment, you can&#8217;t guarantee that your app (think: stuff deployed on worker nodes) will be available at any given time.</p><p>In this post I will showcase three real-life scenarios where your app could end up unexpectedly being offline, while still obeying all the requirements you explicitly specified in your K8s manifests, and how you can protect your deployment from those events.</p><h3>What are we working with?</h3><p>We&#8217;re deploying an e-commerce application as a single container (along with other services omitted for clarity). We&#8217;re deploying two copies of the app (two replicas), in order to ensure high availability. Just like you would normally do in an on-prem environment.</p><p>In a nutshell, our deployment is two pods, each consisting of a single container spread somewhere in the K8s cluster.</p><h3>Scenario A - <a href="https://en.wikipedia.org/wiki/Raiders_of_the_Lost_Ark">Raiders of the Lost Node</a></h3><p>Your cluster has nodes A, B and C (you can&#8217;t see them, since it&#8217;s hidden from you, but they are there - you can verify with <code>kubectl get nodes</code>). You&#8217;re deploying two replicas of the app for resiliency. However, it happens that they are both deployed on node A.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4vEf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4vEf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 424w, https://substackcdn.com/image/fetch/$s_!4vEf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 848w, https://substackcdn.com/image/fetch/$s_!4vEf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 1272w, https://substackcdn.com/image/fetch/$s_!4vEf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4vEf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png" width="820" height="420" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:420,&quot;width&quot;:820,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:14817,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4vEf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 424w, https://substackcdn.com/image/fetch/$s_!4vEf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 848w, https://substackcdn.com/image/fetch/$s_!4vEf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 1272w, https://substackcdn.com/image/fetch/$s_!4vEf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7658dcb-ec04-4ab0-9355-c35fc54821ca_820x420.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then node A goes down for any reason. If we&#8217;re lucky and it&#8217;s planned, our app is going to receive SIGTERM and K8s will start spinning it up on a second node. Maybe we get away with no downtime.</p><p>But if it&#8217;s a crash or hardware failure (yes, there is real hardware behind the cloud!) then you&#8217;re suddenly without any copy of a running app.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TTiY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TTiY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 424w, https://substackcdn.com/image/fetch/$s_!TTiY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 848w, https://substackcdn.com/image/fetch/$s_!TTiY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 1272w, https://substackcdn.com/image/fetch/$s_!TTiY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TTiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png" width="820" height="425" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/acc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:425,&quot;width&quot;:820,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25799,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TTiY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 424w, https://substackcdn.com/image/fetch/$s_!TTiY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 848w, https://substackcdn.com/image/fetch/$s_!TTiY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 1272w, https://substackcdn.com/image/fetch/$s_!TTiY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facc4382f-7309-488d-ac49-9e4117cf4fe6_820x425.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The solution? You need to specify pod anti-affinity. It&#8217;s a very specific instruction given to the scheduler. It means pods are steered away from each other and run on separate nodes, a bit like magnets repelling each other. By using <code>topologyKey: &#8220;kubernetes.io/hostname&#8221;</code>, we&#8217;re specifying that we want the hostname as the discriminator, which means the pods will be spread across available nodes.</p><p>However, since we&#8217;re using <code>preferredDuringSchedulingIgnoredDuringExecution</code>, it means this isn&#8217;t a hard requirement. If for any reason, e.g. GCP is currently running out of nodes, K8s won&#8217;t be able to fulfil the spec, K8s would still run two copies of our app.</p><p>The opposite policy would be <code>requiredDuringSchedulingIgnoredDuringExecution</code>. Please note, that the hard requirement might cause your pods to be stuck in unschedulable state. If the scheduler is unable to find suitable nodes, it will simply refuse to run them. In autopilot&#8217;s case, it will probably mean that the cluster needs to scale in order to have new nodes available, which will take extra time and may be inconvenient at the given time.</p><p>As implied by the &#8220;ignoredDuringExecution&#8221; suffix, these policies have no effect on a pod&#8217;s runtime lifecycle. Hence your pods may still end up on same node in some unlikely turn of events.</p><pre><code><code>spec:
  template:
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - unit
               topologyKey: &#8220;kubernetes.io/hostname&#8221;
</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TDvy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TDvy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 424w, https://substackcdn.com/image/fetch/$s_!TDvy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 848w, https://substackcdn.com/image/fetch/$s_!TDvy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 1272w, https://substackcdn.com/image/fetch/$s_!TDvy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TDvy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png" width="820" height="420" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:420,&quot;width&quot;:820,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13391,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TDvy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 424w, https://substackcdn.com/image/fetch/$s_!TDvy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 848w, https://substackcdn.com/image/fetch/$s_!TDvy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 1272w, https://substackcdn.com/image/fetch/$s_!TDvy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f38e70f-9aef-43bd-ad0a-9e81c08cb5d2_820x420.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Scenario B - <a href="https://en.wikipedia.org/wiki/Indiana_Jones_and_the_Temple_of_Doom">The Zone of Doom</a></h3><p>You deployed your app with pod anti-affinity and it&#8217;s now deployed on nodes A and B. However, it turns out they are both in the same zone.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HGNS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HGNS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!HGNS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!HGNS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!HGNS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HGNS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png" width="940" height="460" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:460,&quot;width&quot;:940,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19978,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HGNS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!HGNS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!HGNS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!HGNS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8ec889-f920-431a-9eaa-d343250a25f5_940x460.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Should that zone go down, then so does your app.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5HWI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5HWI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!5HWI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!5HWI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!5HWI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5HWI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png" width="940" height="460" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:460,&quot;width&quot;:940,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:47365,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5HWI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!5HWI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!5HWI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!5HWI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19fc8e6f-7f23-4f7c-b8e9-025618b2197d_940x460.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You&#8217;re out of luck again.</p><p>The solution? You need to deploy your app in multiple zones. You can do it by using a regional cluster &#8211; which is the only cluster type available when using GKE in autopilot mode, and specifying the <code>topologyKey</code> in your deployment&#8217;s <code>podAntiAffinity</code> spec:</p><pre><code><code>spec:
  template:
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - unit
              topologyKey: topology.kubernetes.io/zone
</code></code></pre><p>If you need more control and options (which are unsuitable to express in <code>affinity</code> terms) there is also another configuration called <code>topologySpreadConstraints</code>. You can find the motivations behind it <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/#motivation">in the docs</a> and on <a href="https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/895-pod-topology-spread#motivation">the proposal when it was introduced</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Cjyz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cjyz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!Cjyz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!Cjyz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!Cjyz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Cjyz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png" width="940" height="460" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:460,&quot;width&quot;:940,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19958,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cjyz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!Cjyz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!Cjyz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!Cjyz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd56ae5bd-0e3d-4ef7-96a8-6d5c02f570c9_940x460.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Scenario C - <strong><a href="https://en.wikipedia.org/wiki/Indiana_Jones_and_the_Last_Crusade">The Last Upgrade</a></strong></h3><p>You did all of the above. However, now the K8s control plane is doing node upgrades. And &#8211; you guessed it &#8211; node A and C are going to be upgraded at the same time. In other words, your app is going to be down. Again, no luck.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KzvK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KzvK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!KzvK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!KzvK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!KzvK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KzvK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png" width="940" height="460" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d033e621-9cc0-45b4-a978-55c06973faa4_940x460.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:460,&quot;width&quot;:940,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:31768,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KzvK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 424w, https://substackcdn.com/image/fetch/$s_!KzvK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 848w, https://substackcdn.com/image/fetch/$s_!KzvK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 1272w, https://substackcdn.com/image/fetch/$s_!KzvK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd033e621-9cc0-45b4-a978-55c06973faa4_940x460.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The solution? You need to use <code>PodDisruptionBudget</code> to limit how many pods can be down at the same time, or at least how many are required to be up.</p><p>Example:</p><pre><code><code>apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: unit-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: unit
</code></code></pre><p>Although it depends on the situation and the decisions by the scheduler, when running it may look like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bcak!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bcak!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 424w, https://substackcdn.com/image/fetch/$s_!bcak!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 848w, https://substackcdn.com/image/fetch/$s_!bcak!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 1272w, https://substackcdn.com/image/fetch/$s_!bcak!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bcak!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png" width="1020" height="1860" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1860,&quot;width&quot;:1020,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:164524,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://deployingelixir.eu/i/175181682?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bcak!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 424w, https://substackcdn.com/image/fetch/$s_!bcak!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 848w, https://substackcdn.com/image/fetch/$s_!bcak!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 1272w, https://substackcdn.com/image/fetch/$s_!bcak!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d05210d-f07b-47d2-9b5f-2a5a471ca0da_1020x1860.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Conclusion</h3><p>I hope you find these additions to your toolbox useful and you never again made a mistake of having <em>HA</em> pods setup, which in case of failure, turns out to be not-HA at all.</p><p>If you want to read more, here are some links that might be useful to you:</p><ul><li><p><a href="https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity">Pod affinity and anti-affinity docs</a></p></li><li><p><a href="https://kubernetes.io/docs/tasks/run-application/configure-pdb/">Pod disruption budget docs</a></p></li><li><p><a href="https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/">Topology spread constraints docs</a> and <a href="https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/895-pod-topology-spread">proposal</a></p></li><li><p><a href="https://github.com/infracloudio/kubernetes-scheduling-examples/blob/master/podAffinity/README.md">Examples of using affinity and anti-affinity</a></p></li><li><p><a href="https://www.cloudskillsboost.google/paths/13/course_templates/34/video/460067">Google Cloud SkillBoost lesson on pod placement</a></p></li></ul><p>Deploying Elixir is a reader-supported publication. To receive new posts and support my work:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://deployingelixir.eu/subscribe?coupon=a6108b95&amp;utm_content=175181682&quot;,&quot;text&quot;:&quot;Get 30 day free trial&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://deployingelixir.eu/subscribe?coupon=a6108b95&amp;utm_content=175181682"><span>Get 30 day free trial</span></a></p><p>or</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://deployingelixir.eu/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://deployingelixir.eu/subscribe?"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Dockerfile tune-up for production and dev envs]]></title><link>https://deployingelixir.eu/p/dockerfile-tune-up-for-production</link><guid isPermaLink="false">https://deployingelixir.eu/p/dockerfile-tune-up-for-production</guid><dc:creator><![CDATA[Piotr Szmielew]]></dc:creator><pubDate>Thu, 09 Oct 2025 08:01:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/vimeo/w_728,c_limit,d_video_placeholder.png/1122854624" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this episode, we&#8217;ll revisit our previously written Dockerfile and improve it by creating two versions - one optimized for development and another tailored for production.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://deployingelixir.eu/subscribe?coupon=a6108b95&amp;utm_content=174835030&quot;,&quot;text&quot;:&quot;Get 30 day free trial&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://deployingelixir.eu/subscribe?coupon=a6108b95&amp;utm_content=174835030"><span>Get 30 day free trial</span></a></p>
      <p>
          <a href="https://deployingelixir.eu/p/dockerfile-tune-up-for-production">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[ElixirConf EU 2025 talk: Four Years of Running Elixir on Kubernetes in Google Cloud: Lessons Learned]]></title><link>https://deployingelixir.eu/p/elixirconf-eu-2025-talk-four-years</link><guid isPermaLink="false">https://deployingelixir.eu/p/elixirconf-eu-2025-talk-four-years</guid><dc:creator><![CDATA[Piotr Szmielew]]></dc:creator><pubDate>Thu, 02 Oct 2025 08:02:29 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/Zce0SM1sm7A" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="youtube2-Zce0SM1sm7A" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;Zce0SM1sm7A&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/Zce0SM1sm7A?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Deploying Elixir is a reader-supported publication. To receive new posts and support my work:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://deployingelixir.eu/subscribe?coupon=a6108b95&amp;utm_content=174835735&quot;,&quot;text&quot;:&quot;Get 30 day free trial&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://deployingelixir.eu/subscribe?coupon=a6108b95&amp;utm_content=174835735"><span>Get 30 day free trial</span></a></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://deployingelixir.eu/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">or</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Anatomy of Dockerfile]]></title><description><![CDATA[In this episode we will dockerize existing Phoenix application, while looking into anatomy of dockerfile]]></description><link>https://deployingelixir.eu/p/anatomy-of-dockerfile</link><guid isPermaLink="false">https://deployingelixir.eu/p/anatomy-of-dockerfile</guid><dc:creator><![CDATA[Piotr Szmielew]]></dc:creator><pubDate>Thu, 25 Sep 2025 16:23:21 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ddbde916-2b4f-4dd5-9502-39587e797854_3840x2160.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://deployingelixir.eu/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://deployingelixir.eu/subscribe?"><span>Subscribe now</span></a></p><div id="vimeo-1121937197" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;1121937197&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/1121937197?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><p>Transcript (auto-generated):</p><p>[0:03] Hello, and welcome to Deploying Elixir. In this episode, we will be dockerizing an existing Phoenix application, which I have pre-created here. So we have something to work with. So before we begin, we need to talk a little bit about how Docker constructs the final image. It&#8217;s constructed of something called layers. So we start with a base layer, which we&#8217;ll see in a moment. Then we add files, add files, run some compilations, run more stuff. And then we end up in a final image, which is actually a base image, with all of the layers added as an overlays. So let&#8217;s start. I just generated a very brief Phoenix application without Ecto for the brave of simplicity. Let&#8217;s just start with running the application so we can see it&#8217;s actually working. So mix.ph server and yes it&#8217;s a default phoenix application so everything is working they&#8217;re fine so let&#8217;s just start writing our docker file so as i said before first must be our base layer so only from elixir.</p><p>[1:15] Minus iAlpine, which is an officially maintained elixir of the newest version and using Alpine, which is a very light, quite linear distribution, very often used in a Dockerfile. Then we need to add some packages. So let&#8217;s just add... Build-base and git and tinny, because we&#8217;ll need tinny in a moment. And let&#8217;s just say we are using slash app as path for our work. So it will change directory to that current working directory, and it will allow us to do everything in the scope of that work there. And then let&#8217;s just set mix and variable to prod. Which means we&#8217;ll be using our Phoenix application in production mode.</p><p>[2:11] And as you may remember from your first journey with Elixir, you may want to add, you will need to add local hex and local rebar, because as you may know, the Docker environment in which we&#8217;ll be building our application is different from your local machine, so it won&#8217;t be having everything you have. So we need to do everything from scratch, like you are installing your Elixir for the very first time and everything. And then this very important step here. So let&#8217;s just say copy, which copies files from the local directory to the Docker container. Let&#8217;s just copy mix and mix lock. And then let&#8217;s just run mix devs get only mix env. Why is it important? So If something changes, for example, in the mix.xs, it will invalidate all of the lines underneath, which means on the rebuild, they will need to be rebuilt. If they stay the same, the Docker file evaluation will start from the bottom line, which means you&#8217;re changing your code more often than you&#8217;re changing your dependencies. And then just add here mcadier config, because we need that, and then let&#8217;s just say copy config slash config dot xs and the config.</p><p>[3:41] Protaxs to config directory. So from now on, if we change config files, everything from the bottom will be involved and that would copy the existing config files to the config files in our docker container. And then we can compile our dependencies because they are dependent on configs. So if we do that the other way, that would make sense. That would change more of your compilation. We want to reuse cached layer as much as possible here.</p><p>[4:14] Then copy all of the remaining files which is needed for our application to work. Since we copied our pre-flipping assets, we can compile our assets and compile our application, which will create a build of our app ready to be released and both with our assets, then we can copy the runtime file to our config and then run mixtry. So this will copy the config runtime, which as you may remember from the other stuff contains a runtime configuration for application. But on the other hand, it&#8217;s evaluated only when you start your application. So changing in that file doesn&#8217;t need to cause recompilation because it only is evaluated during the startup of your Erlang virtual machine. And then run a mix release. And then something interesting. So this is actually kind of a different command because it basically doesn&#8217;t add a new layer. Remember the layer? So every copy, every run creates a new layer to get overlay, but some of the commands only changes metadata. And this is exactly that command. So it exposes port 4000, which basically means we&#8217;re saying here that this container is listening internally on port 4000.</p><p>[5:43] And you can either tell Docker to bind that to random port on your local machine or you can forward the port directly to your Docker running container.</p><p>[5:55] It&#8217;s up to you, but you know to expect that inside port 4000 will be open for business. Then just add entry point, which will be teeny.</p><p>[6:08] And this is like a Swiss army knife tool for being an entry point in the containers. Because it listens to system signals correctly and do all of that stuff that you want there. And then, basically, if you want to avoid a lot of issues with zombie processes and stuff like that, TINI is your weapon of choice because it handles all of it for you and you don&#8217;t need to worry about it. And then let&#8217;s just say command and it would be slash app because we used a workdir app and build because this is the directory in which build is start, prod because we&#8217;re running production environment rel because it&#8217;s list and then up again bin and up name again and we want to start it, cool so let&#8217;s just say let&#8217;s just check if that works So let&#8217;s just say docker-build-tBuildHello. Excellent. We have our container. We have our image ready. Let&#8217;s just run container out of it. Docker run-pHello. But we need to provide secret key base.</p><p>[7:17] And since we don&#8217;t need to have a traffic going from one instance to another, we can just use a randomly generated number here. So let&#8217;s just go with docker run minus e and let&#8217;s just say secret key base should be mix ph-agent secret generated locally. And if we look at the runtime, we see that there&#8217;s exactly secret key base here, which we need to provide. And then we also want to provide pxyserver equals true here in order to have that specific instance listening for traffic. You may ask yourself, what are the examples of server you don&#8217;t want to listen to traffic? So, for example, let&#8217;s just say you&#8217;re running a background job processor. So running some of the instances, running for serving traffic, some of them actually listening to background processes. That would be the case, for example, or if you forwarding traffic to that endpoint from some other endpoint, which we can do, that would be another example. So let&#8217;s just run here.</p><p>[8:45] Oh, I just typed run two times. Amazing. And let&#8217;s just check what is the part. So, 55003. Amazing! Everything works. That&#8217;s fine.</p><p>[9:04] And there the final image is a conglomerate of layers. We can actually see that. As I said before to you, this image consists of layers and you can actually see this layer. So if you go docker-inspect-hello, you can see that there are layers specified here. And if we, for one second, do that and then let&#8217;s just say we want to combine that with docker because you may see that there are just quite many of these layers, right?</p><p>[9:41] Oh, there&#8217;s also exposed here port, which is the information that its port will be served on the port 4000 instantly. And you want to push the traffic to that port if you want to do something with that. So let&#8217;s just say we&#8217;re inspecting the elixir and we have three layers. And if we look at here, you can clearly see that these three layers are the same as these three layers. Because we use our elixir image as a base, which basically means the bottom three layers of our file will be taken from here. And we have one, two, three, four, five, six, seven, eight, nine, 10, 11, 12, 13, 14 layers. And this Docker file is far from optimum. For example, it uses a build image, also a runtime image, so it&#8217;s not a production ready. But we&#8217;ll look into that in the next episode in which we&#8217;ll rebuild that Docker file to be production-friendly, for example, starting stuff like multi-stage build and doing some of their tweaks. So thank you very much for listening and see you in the next episode.</p>]]></content:encoded></item></channel></rss>