<?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>Immutable OS Archives - Linuxcent</title>
	<atom:link href="https://linuxcent.com/category/immutable-os/feed/" rel="self" type="application/rss+xml" />
	<link>https://linuxcent.com/category/immutable-os/</link>
	<description>Infrastructure security, from the kernel up.</description>
	<lastBuildDate>Mon, 06 Jul 2026 21:30:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.4</generator>

<image>
	<url>https://linuxcent.com/wp-content/uploads/2026/04/favicon-512x512-1-150x150.png</url>
	<title>Immutable OS Archives - Linuxcent</title>
	<link>https://linuxcent.com/category/immutable-os/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">211632295</site>	<item>
		<title>Atomic OS Updates Explained: How ostree and bootc Actually Work</title>
		<link>https://linuxcent.com/atomic-os-updates-explained/</link>
					<comments>https://linuxcent.com/atomic-os-updates-explained/#respond</comments>
		
		<dc:creator><![CDATA[Vamshi Krishna Santhapuri]]></dc:creator>
		<pubDate>Mon, 06 Jul 2026 21:30:17 +0000</pubDate>
				<category><![CDATA[Immutable OS]]></category>
		<category><![CDATA[Atomic Updates]]></category>
		<category><![CDATA[bootc]]></category>
		<category><![CDATA[DevSecOps]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[ostree]]></category>
		<guid isPermaLink="false">https://linuxcent.com/atomic-os-updates-explained/</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 7</span> <span class="rt-label rt-postfix">minutes</span></span>See exactly how ostree and bootc implement atomic OS updates — commit graphs, bootloader entries, and rollback — so you know what atomic really means.</p>
<p>The post <a href="https://linuxcent.com/atomic-os-updates-explained/">Atomic OS Updates Explained: How ostree and bootc Actually Work</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 7</span> <span class="rt-label rt-postfix">minutes</span></span><style>
pre{position:relative;background:#1e1e1e;color:#d4d4d4;
    padding:16px 16px 16px 20px;border-radius:6px;overflow-x:auto;
    font-family:'JetBrains Mono','Fira Code','Cascadia Code',Consolas,'Courier New',monospace;
    font-size:.88em;line-height:1.6;border-left:4px solid #555}
code{background:#f4f4f4;padding:2px 5px;border-radius:3px;font-size:.9em}
pre code{background:transparent;padding:0;color:inherit}
pre[data-lang="bash"],pre[data-lang="sh"],
pre[data-lang="shell"],pre[data-lang="zsh"]{border-left-color:#4ec9b0}
pre[data-lang="yaml"],pre[data-lang="json"],
pre[data-lang="toml"],pre[data-lang="xml"]{border-left-color:#569cd6}
pre[data-lang="python"],pre[data-lang="go"],pre[data-lang="rust"],
pre[data-lang="java"],pre[data-lang="c"],pre[data-lang="cpp"]{border-left-color:#c586c0}
pre[data-lang="text"],pre[data-lang="output"],
pre[data-lang="console"]{border-left-color:#888}
.lc-copy-btn{position:absolute;top:8px;right:8px;background:#2d2d2d;color:#ccc;
    border:1px solid #444;border-radius:4px;padding:3px 9px;font-size:.75em;
    font-family:system-ui,sans-serif;cursor:pointer;opacity:0;
    transition:opacity .15s,background .15s;line-height:1.6}
pre:hover .lc-copy-btn{opacity:1}
.lc-copy-btn:hover{background:#3a3a3a;color:#fff}
.lc-copy-btn.copied{color:#4ec9b0;border-color:#4ec9b0}
.lc-lang-badge{position:absolute;top:8px;left:20px;font-family:system-ui,sans-serif;
    font-size:.7em;color:#666;text-transform:uppercase;letter-spacing:.04em;
    line-height:1;pointer-events:none;opacity:0;transition:opacity .15s}
pre:hover .lc-lang-badge{opacity:1}
table{border-collapse:collapse;width:100%;margin:16px 0}
th,td{border:1px solid #ddd;padding:10px 14px;text-align:left}
th{background:#f0f0f0;font-weight:600}
tr:nth-child(even){background:#fafafa}
</style>
<p><script>
(function(){
  if(window.__lcCodeEnhanced)return;
  window.__lcCodeEnhanced=true;
  function enhance(){
    document.querySelectorAll('pre').forEach(function(pre){
      var code=pre.querySelector('code');
      var lang='';
      if(code){var m=(code.className||'').match(/language-(\S+)/);if(m)lang=m[1].toLowerCase();}
      if(lang)pre.setAttribute('data-lang',lang);
      if(lang){var badge=document.createElement('span');badge.className='lc-lang-badge';badge.textContent=lang;pre.insertBefore(badge,pre.firstChild);}
      var btn=document.createElement('button');
      btn.className='lc-copy-btn';btn.textContent='Copy';btn.setAttribute('aria-label','Copy code to clipboard');
      pre.appendChild(btn);
      btn.addEventListener('click',function(){
        var text=code?code.innerText:pre.innerText;
        if(navigator.clipboard&&window.isSecureContext){
          navigator.clipboard.writeText(text).then(function(){ok(btn);}).catch(function(){fb(text,btn);});
        }else{fb(text,btn);}
      });
    });
  }
  function ok(btn){btn.textContent='Copied!';btn.classList.add('copied');setTimeout(function(){btn.textContent='Copy';btn.classList.remove('copied');},2000);}
  function fb(text,btn){
    try{var ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;left:-9999px;top:-9999px;opacity:0';document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);ok(btn);}
    catch(e){btn.textContent='✗ Failed';setTimeout(function(){btn.textContent='Copy';},2000);}
  }
  if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',enhance);}else{enhance();}
})();
</script></p>
<p><em>Immutable OS Series, Episode 2</em><br />
<a href="/what-is-immutable-os/">← EP01: What Is an Immutable OS?</a> · <strong>EP02: Atomic OS Updates Explained</strong> · <a href="/immutable-os-series/">All Immutable OS Episodes →</a></p>
<hr />
<h2 id="tldr">TL;DR</h2>
<ul>
<li>Atomic OS updates explained at the mechanism level: ostree stores every deployment as a content-addressed commit, not a set of files you overwrite — &#8220;atomic&#8221; is a property of the filesystem layout, not a promise a script makes</li>
<li>The actual atomicity boundary is a single bootloader configuration write — everything before that point is fully reversible, and everything after it is a clean boot into a complete, self-contained deployment</li>
<li>bootc builds on the same ostree deployment model but starts from a <code class="" data-line="">Containerfile</code>, so building a bootable OS image uses the same toolchain as building an application container</li>
<li>Power loss mid-update is a non-event: the system reboots into whatever the bootloader pointed at before the write, because the new deployment was never referenced until that one atomic write succeeded</li>
<li>Rollback targets aren&#8217;t kept forever — garbage collection and configurable deployment limits mean &#8220;you can always roll back&#8221; has a real, finite window</li>
<li>This is the mechanism EP01 described in outline; this episode is what actually happens on disk</li>
</ul>
<hr />
<h2 id="the-big-picture-a-commit-graph-not-a-file-tree">The Big Picture: A Commit Graph, Not a File Tree</h2>
<pre><code class="" data-line="">ostree REPOSITORY (content-addressed objects)
─────────────────────────────────────────────
  commit A (hash 8f2a1c...)  ──parent──&#x25b6;  commit B (hash 3b7e9d...)
       │                                        │
       │ checked out as                         │ checked out as
       ▼                                        ▼
  /ostree/deploy/os/deploy/8f2a1c...    /ostree/deploy/os/deploy/3b7e9d...
  (READ-ONLY bind mount → /)            (READ-ONLY bind mount → /, once active)

BOOTLOADER CONFIG (the atomicity boundary)
─────────────────────────────────────────────
  grub.cfg / loader entries
       │
       └── points to exactly ONE deployment directory at a time
           Changing this pointer IS the update. Nothing else has
           to happen for the new deployment to become &quot;the OS.&quot;
</code></pre>
<p>Atomic OS updates explained simply: ostree never edits a running deployment&#8217;s files. It writes an entirely new, complete deployment as a set of immutable, content-addressed objects somewhere else on disk, and the update becomes real the instant a single bootloader entry is rewritten to point at it. EP01 showed this from the outside — <code class="" data-line="">rpm-ostree status</code>, <code class="" data-line="">rollback</code>, a clean before/after. This episode is what&#8217;s actually happening underneath those commands.</p>
<hr />
<h2 id="every-deployment-is-a-commit-not-a-directory-you-edited">Every Deployment Is a Commit, Not a Directory You Edited</h2>
<p>A traditional package manager mutates files in place: <code class="" data-line="">apt upgrade</code> overwrites <code class="" data-line="">/usr/bin/curl</code> with a new binary, in the same inode, on the same live filesystem the kernel and every running process are using. If that write is interrupted, or if two updates race, the result is whatever state the filesystem happened to be in when things stopped — there&#8217;s no defined &#8220;before&#8221; state to return to, because the before state was destroyed in place.</p>
<p>This is the same declarative-artifact idea <a href="https://linuxcent.com/linux-hardening-as-code/">Stratum&#8217;s HardeningBlueprint YAML</a> applies to OS hardening — the artifact either fully exists or the build failed, with nothing skippable in between — extended down to the filesystem itself.</p>
<p>ostree does something structurally different: every file in a deployment is stored as an object named by the SHA-256 hash of its content, inside a repository (<code class="" data-line="">/ostree/repo</code>). A deployment is a commit — a tree of these hashed objects, checksummed all the way up, the same content-addressing model Git uses for a repository&#8217;s history. Deploying an update means:</p>
<ol>
<li>Pull or build the new commit into the local ostree repository (pure object storage — this doesn&#8217;t touch the running system at all)</li>
<li>Check out that commit into a <strong>new</strong> deployment directory (<code class="" data-line="">/ostree/deploy/&lt;os&gt;/deploy/&lt;checksum&gt;</code>) — still doesn&#8217;t touch the running system</li>
<li>Write a new bootloader entry pointing at that new deployment directory</li>
<li>Reboot</li>
</ol>
<p>Steps 1 and 2 can take minutes, involve gigabytes of I/O, and fail halfway through with zero consequence — the running system&#8217;s deployment directory was never opened for writing. There is no partial-update state visible to anything, because nothing that&#8217;s currently running was ever touched.</p>
<hr />
<h2 id="the-atomicity-boundary-one-bootloader-write">The Atomicity Boundary: One Bootloader Write</h2>
<p>&#8220;Atomic&#8221; specifically refers to step 3. Rewriting a bootloader entry (a GRUB <code class="" data-line="">grub.cfg</code> regeneration, or a systemd-boot loader entry file) is small enough to be a single filesystem operation — either the new entry exists on disk, or it doesn&#8217;t. There&#8217;s no meaningful &#8220;half-written bootloader entry&#8221; state that a power failure can leave you in: at boot, the firmware reads whatever bootloader configuration fully exists, and that configuration names exactly one deployment.</p>
<pre><code class="" data-line="">POWER LOSS DURING STEP 1 or 2 (pulling/staging the new commit)
────────────────────────────────────────────────────────────
Next boot: bootloader entry still points at the OLD deployment.
The new commit&#039;s partial objects sit in the repo, orphaned,
inert. System boots exactly as if the update never started.

POWER LOSS DURING STEP 3 (bootloader entry write)
────────────────────────────────────────────────────────────
Filesystem-level atomic rename guarantees the entry write itself
either completes or doesn&#039;t. Next boot: either the old deployment
(write didn&#039;t land) or the new one (write landed) — never a
corrupted bootloader config caught in between.

POWER LOSS AFTER STEP 3, BEFORE REBOOT
────────────────────────────────────────────────────────────
Doesn&#039;t matter — the running system hasn&#039;t changed. The new
deployment activates on the NEXT boot, whenever that happens.
</code></pre>
<p>This is the property EP01 called &#8220;the system is never caught half-updated&#8221; — and now you can see exactly why: every step before the bootloader write is invisible to the running system, and the bootloader write itself is small enough that the filesystem&#8217;s own atomic-rename guarantee covers it. There&#8217;s no custom transaction logic to trust. It&#8217;s a property of doing the update in the right order, using a write that was already atomic.</p>
<hr />
<h2 id="bootc-the-same-model-a-container-build-toolchain">bootc: The Same Model, a Container Build Toolchain</h2>
<p>bootc uses this identical deployment mechanism — the on-disk layout, the bootloader swap, the rollback behavior are all the same ostree machinery. What bootc changes is how the commit gets built in the first place.</p>
<pre><code class="" data-line=""># Containerfile — this IS the OS image definition
FROM quay.io/fedora/fedora-bootc:41

RUN dnf install -y nginx &amp;&amp; \
    systemctl enable nginx &amp;&amp; \
    dnf clean all

# Standard container build — no special OS-image tooling required
</code></pre>
<pre><code class="" data-line=""># Build it exactly like an application container
$ podman build -t myregistry.example.com/os/web-node:v12 .
$ podman push myregistry.example.com/os/web-node:v12

# On the target machine — pulls the image, converts it to an
# ostree commit, stages it as the next deployment
$ bootc switch myregistry.example.com/os/web-node:v12
Queued for next boot: myregistry.example.com/os/web-node:v12
Please reboot to complete the update.

$ systemctl reboot
</code></pre>
<p><code class="" data-line="">bootc switch</code> and <code class="" data-line="">bootc upgrade</code> do the same three-step dance as raw ostree — pull the new commit (here, derived from a container image&#8217;s layers instead of an RPM-based tree), stage a deployment directory, write the bootloader entry — the difference is entirely in step 1: bootc converts OCI container image layers into an ostree commit instead of building one from package installation directly. Your existing container registry, existing <code class="" data-line="">Containerfile</code> conventions, and existing image-signing pipeline all apply unchanged to what is, underneath, a bootable operating system.</p>
<hr />
<h2 id="where-ostree-and-bootc-actually-diverge">Where ostree and bootc Actually Diverge</h2>
<table>
<thead>
<tr>
<th></th>
<th>Raw ostree (Fedora CoreOS style)</th>
<th>bootc</th>
</tr>
</thead>
<tbody>
<tr>
<td>Image defined as</td>
<td><code class="" data-line="">rpm-ostree compose</code> treefile (custom format)</td>
<td>Standard <code class="" data-line="">Containerfile</code></td>
</tr>
<tr>
<td>Build tooling</td>
<td>ostree/rpm-ostree-specific</td>
<td>Any OCI-compatible builder (<code class="" data-line="">podman</code>, <code class="" data-line="">buildah</code>, <code class="" data-line="">docker</code>)</td>
</tr>
<tr>
<td>Registry/distribution</td>
<td>ostree&#8217;s own HTTP-based repo protocol, or OSTree-in-OCI</td>
<td>Standard container registry (Quay, Docker Hub, ECR, GHCR)</td>
</tr>
<tr>
<td>Deployment mechanism on disk</td>
<td>ostree commits, A/B deployments</td>
<td>Identical — ostree commits, A/B deployments</td>
</tr>
<tr>
<td>Rollback command</td>
<td><code class="" data-line="">rpm-ostree rollback</code></td>
<td><code class="" data-line="">bootc rollback</code></td>
</tr>
<tr>
<td>Best fit</td>
<td>Teams already fluent in ostree/ Fedora tooling</td>
<td>Teams that want OS images to fit their existing container CI/CD</td>
</tr>
</tbody>
</table>
<p>Nothing about atomicity, rollback safety, or the deployment model changes between the two — bootc&#8217;s entire value proposition is packaging the same guarantee behind tooling most infrastructure teams already have muscle memory for.</p>
<hr />
<h2 id="the-part-ep01-didnt-mention-rollback-has-a-shelf-life">The Part EP01 Didn&#8217;t Mention: Rollback Has a Shelf Life</h2>
<p>&#8220;The previous deployment is always intact for rollback&#8221; (EP01&#8217;s phrasing) is true, but not indefinitely. Each deployment consumes real disk space — a full OS tree&#8217;s worth of objects, though ostree deduplicates identical objects across commits so an incremental update doesn&#8217;t cost a second full copy. Two mechanisms limit how far back you can actually roll:</p>
<p><strong>Deployment count limits.</strong> Most configurations keep a bounded number of deployments (commonly 2–3). Once you&#8217;ve upgraded past that limit, the oldest deployment is pruned — <code class="" data-line="">rpm-ostree cleanup</code> or an automatic policy removes it, and its objects become eligible for garbage collection if nothing else references them.</p>
<p><strong>Garbage collection reclaims orphaned objects.</strong> <code class="" data-line="">ostree prune</code> (or <code class="" data-line="">rpm-ostree cleanup -p</code>) removes any object in the repository not reachable from a currently-kept deployment or a pinned ref. If you pruned a deployment last week and you need to roll back to it today, that commit is gone — not degraded, not slow to restore, simply no longer present.</p>
<pre><code class="" data-line=""># See exactly what&#039;s kept and what&#039;s eligible for cleanup
$ ostree admin status
  fedora-coreos 38.20240210.3.0 (booted)   # current
  fedora-coreos 38.20240115.2.0            # one rollback available

# Pin a deployment explicitly if you need a longer-lived rollback
# target than the default retention policy provides
$ ostree admin pin 1
</code></pre>
<p>If your incident-response plan assumes &#8220;we can always roll back to last month&#8217;s known-good state,&#8221; verify that against your actual retention policy — the default is usually one previous deployment, not an archive.</p>
<hr />
<h2 id="quick-reference">Quick Reference</h2>
<pre><code class="" data-line=""># Inspect the commit graph and current deployments
ostree admin status                      # deployments + which is booted
ostree log &lt;ref&gt;                         # commit history for a branch
ostree show &lt;checksum&gt;                   # inspect a specific commit

# rpm-ostree (Fedora CoreOS / Silverblue)
rpm-ostree status                        # current + staged, same as EP01
rpm-ostree cleanup -p                    # prune old deployments + GC

# bootc
bootc status                             # current + staged image
bootc switch &lt;image-ref&gt;                 # move to a different image
bootc upgrade                            # pull latest tag, stage it
bootc rollback                           # revert to previous deployment
</code></pre>
<hr />
<h2 id="production-gotchas">Production Gotchas</h2>
<p><strong>&#8220;Atomic&#8221; doesn&#8217;t mean &#8220;instant.&#8221;</strong> Staging a new deployment can take as long as a full OS install — the atomicity guarantee is about the swap being indivisible, not about the whole process being fast. Budget real time for the pull-and-stage phase in maintenance windows.</p>
<p><strong>Deduplication means disk usage doesn&#8217;t scale linearly with deployment count, but it isn&#8217;t free either.</strong> A kernel or major package version bump touches enough objects that &#8220;just keep 5 deployments for safety&#8221; can use more disk than teams expect. Monitor <code class="" data-line="">/ostree/repo</code> size, don&#8217;t assume it&#8217;s negligible.</p>
<p><strong>Pinning a deployment and forgetting about it silently defeats garbage collection.</strong> <code class="" data-line="">ostree admin pin</code> is the right tool for &#8220;I need to guarantee this stays available,&#8221; but a pinned deployment never gets reclaimed automatically — audit pins periodically or disk usage grows unbounded.</p>
<p><strong>bootc&#8217;s registry dependency is a new failure mode ostree-native updates didn&#8217;t have.</strong> If your container registry is unreachable, <code class="" data-line="">bootc upgrade</code> fails the same way a registry-down event fails an application deployment — factor registry availability into your OS update SLA the same way you already do for app deployments.</p>
<hr />
<h2 id="key-takeaways">Key Takeaways</h2>
<ul>
<li>Every ostree deployment is a content-addressed commit, not a set of files mutated in place — that&#8217;s what makes &#8220;atomic&#8221; a filesystem property instead of a script&#8217;s promise</li>
<li>The actual atomicity boundary is a single bootloader entry write; everything before it is invisible to the running system, everything after it takes effect on next boot</li>
<li>bootc uses the identical deployment mechanism, but builds commits from standard <code class="" data-line="">Containerfile</code>s and distributes them through standard container registries</li>
<li>Rollback is real but bounded — deployment limits and garbage collection mean &#8220;always roll back&#8221; has a specific, checkable retention window, not an unlimited one</li>
<li>ostree and bootc differ in build/distribution tooling, not in the safety guarantees the deployment model provides</li>
</ul>
<hr />
<h2 id="whats-next">What&#8217;s Next</h2>
<p>EP02 covered the mechanism in the abstract. EP03 runs it day-to-day — Fedora CoreOS and Silverblue in practice: what changes about <code class="" data-line="">dnf install</code>, package layering, troubleshooting, and rollback when you&#8217;re actually living on top of this model instead of reading about it.</p>
<p><em>Next: EP03 — Fedora CoreOS / Silverblue in Practice</em></p>
<p>Get EP03 in your inbox when it publishes → <a href="https://linuxcent.com/subscribe">linuxcent.com/subscribe</a></p>
<p><a class="a2a_button_mastodon" href="https://www.addtoany.com/add_to/mastodon?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="Mastodon" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_email" href="https://www.addtoany.com/add_to/email?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="Email" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_whatsapp" href="https://www.addtoany.com/add_to/whatsapp?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="WhatsApp" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_reddit" href="https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="Reddit" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_linkedin" href="https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="LinkedIn" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_copy_link" href="https://www.addtoany.com/add_to/copy_link?linkurl=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&amp;linkname=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" title="Copy Link" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Flinuxcent.com%2Fatomic-os-updates-explained%2F&#038;title=Atomic%20OS%20Updates%20Explained%3A%20How%20ostree%20and%20bootc%20Actually%20Work" data-a2a-url="https://linuxcent.com/atomic-os-updates-explained/" data-a2a-title="Atomic OS Updates Explained: How ostree and bootc Actually Work"></a></p><p>The post <a href="https://linuxcent.com/atomic-os-updates-explained/">Atomic OS Updates Explained: How ostree and bootc Actually Work</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxcent.com/atomic-os-updates-explained/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2186</post-id>	</item>
		<item>
		<title>What Is an Immutable OS — and Why Hardening Isn&#8217;t Enough</title>
		<link>https://linuxcent.com/what-is-immutable-os/</link>
					<comments>https://linuxcent.com/what-is-immutable-os/#respond</comments>
		
		<dc:creator><![CDATA[Vamshi Krishna Santhapuri]]></dc:creator>
		<pubDate>Mon, 06 Jul 2026 21:29:28 +0000</pubDate>
				<category><![CDATA[Immutable OS]]></category>
		<category><![CDATA[bootc]]></category>
		<category><![CDATA[DevSecOps]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[ostree]]></category>
		<guid isPermaLink="false">https://linuxcent.com/what-is-immutable-os/</guid>

					<description><![CDATA[<p><span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 7</span> <span class="rt-label rt-postfix">minutes</span></span>Learn what an immutable OS actually is — read-only root, atomic updates, zero drift — and why a hardened image alone can't stay hardened in production.</p>
<p>The post <a href="https://linuxcent.com/what-is-immutable-os/">What Is an Immutable OS — and Why Hardening Isn&#8217;t Enough</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></description>
										<content:encoded><![CDATA[<span class="span-reading-time rt-reading-time" style="display: block;"><span class="rt-label rt-prefix">Reading Time: </span> <span class="rt-time"> 7</span> <span class="rt-label rt-postfix">minutes</span></span><style>
pre{position:relative;background:#1e1e1e;color:#d4d4d4;
    padding:16px 16px 16px 20px;border-radius:6px;overflow-x:auto;
    font-family:'JetBrains Mono','Fira Code','Cascadia Code',Consolas,'Courier New',monospace;
    font-size:.88em;line-height:1.6;border-left:4px solid #555}
code{background:#f4f4f4;padding:2px 5px;border-radius:3px;font-size:.9em}
pre code{background:transparent;padding:0;color:inherit}
pre[data-lang="bash"],pre[data-lang="sh"],
pre[data-lang="shell"],pre[data-lang="zsh"]{border-left-color:#4ec9b0}
pre[data-lang="yaml"],pre[data-lang="json"],
pre[data-lang="toml"],pre[data-lang="xml"]{border-left-color:#569cd6}
pre[data-lang="python"],pre[data-lang="go"],pre[data-lang="rust"],
pre[data-lang="java"],pre[data-lang="c"],pre[data-lang="cpp"]{border-left-color:#c586c0}
pre[data-lang="text"],pre[data-lang="output"],
pre[data-lang="console"]{border-left-color:#888}
.lc-copy-btn{position:absolute;top:8px;right:8px;background:#2d2d2d;color:#ccc;
    border:1px solid #444;border-radius:4px;padding:3px 9px;font-size:.75em;
    font-family:system-ui,sans-serif;cursor:pointer;opacity:0;
    transition:opacity .15s,background .15s;line-height:1.6}
pre:hover .lc-copy-btn{opacity:1}
.lc-copy-btn:hover{background:#3a3a3a;color:#fff}
.lc-copy-btn.copied{color:#4ec9b0;border-color:#4ec9b0}
.lc-lang-badge{position:absolute;top:8px;left:20px;font-family:system-ui,sans-serif;
    font-size:.7em;color:#666;text-transform:uppercase;letter-spacing:.04em;
    line-height:1;pointer-events:none;opacity:0;transition:opacity .15s}
pre:hover .lc-lang-badge{opacity:1}
table{border-collapse:collapse;width:100%;margin:16px 0}
th,td{border:1px solid #ddd;padding:10px 14px;text-align:left}
th{background:#f0f0f0;font-weight:600}
tr:nth-child(even){background:#fafafa}
</style>
<p><script>
(function(){
  if(window.__lcCodeEnhanced)return;
  window.__lcCodeEnhanced=true;
  function enhance(){
    document.querySelectorAll('pre').forEach(function(pre){
      var code=pre.querySelector('code');
      var lang='';
      if(code){var m=(code.className||'').match(/language-(\S+)/);if(m)lang=m[1].toLowerCase();}
      if(lang)pre.setAttribute('data-lang',lang);
      if(lang){var badge=document.createElement('span');badge.className='lc-lang-badge';badge.textContent=lang;pre.insertBefore(badge,pre.firstChild);}
      var btn=document.createElement('button');
      btn.className='lc-copy-btn';btn.textContent='Copy';btn.setAttribute('aria-label','Copy code to clipboard');
      pre.appendChild(btn);
      btn.addEventListener('click',function(){
        var text=code?code.innerText:pre.innerText;
        if(navigator.clipboard&&window.isSecureContext){
          navigator.clipboard.writeText(text).then(function(){ok(btn);}).catch(function(){fb(text,btn);});
        }else{fb(text,btn);}
      });
    });
  }
  function ok(btn){btn.textContent='Copied!';btn.classList.add('copied');setTimeout(function(){btn.textContent='Copy';btn.classList.remove('copied');},2000);}
  function fb(text,btn){
    try{var ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;left:-9999px;top:-9999px;opacity:0';document.body.appendChild(ta);ta.select();document.execCommand('copy');document.body.removeChild(ta);ok(btn);}
    catch(e){btn.textContent='✗ Failed';setTimeout(function(){btn.textContent='Copy';},2000);}
  }
  if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',enhance);}else{enhance();}
})();
</script></p>
<p><em>Immutable OS Series, Episode 1</em><br />
<a href="https://linuxcent.com/stratum-os-hardening-platform/">← Stratum EP06: Stratum — OS Hardening as a Platform</a> · <strong>EP01: What Is an Immutable OS?</strong> · <a href="/atomic-os-updates-explained/">EP02: Atomic OS Updates Explained →</a></p>
<hr />
<h2 id="tldr">TL;DR</h2>
<ul>
<li>An immutable OS is one where the running root filesystem is read-only — the only way to change it is to boot a new, versioned image, never to mutate the one that&#8217;s live</li>
<li>Hardening an image proves it&#8217;s correct <em>at build time</em>. Immutability is what keeps that proof true after the image boots into production</li>
<li>The mechanism is atomic A/B updates: a new OS image is staged fully, then swapped in as one operation — the system is never caught half-updated</li>
<li>A bad update is one command away from undone: <code class="" data-line="">rpm-ostree rollback &amp;&amp; systemctl reboot</code> — no reinstall, no image rebuild</li>
<li>bootc, Fedora CoreOS/Silverblue, and Talos Linux are three real implementations of this model, each targeting a different deployment shape</li>
<li>This is not a replacement for Stratum&#8217;s hardening pipeline — it&#8217;s what keeps a hardened image hardened after it ships</li>
</ul>
<hr />
<h2 id="the-big-picture-a-snapshot-vs-a-guarantee">The Big Picture: A Snapshot vs. a Guarantee</h2>
<pre><code class="" data-line="">TRADITIONAL MUTABLE OS                    IMMUTABLE OS
────────────────────────                  ────────────

Golden image (grade: A)                   Deployment A (active, read-only)
        │ boots into prod                          │
        ▼                                           │  atomic swap
Running root filesystem (read-write)                ▼
        │                                  Deployment B (staged)
        │  SSH fix, config-mgmt run,               │
        │  ad-hoc package install                   │  if boot fails
        ▼                                           ▼
Drifted state — no build artifact         Rollback (one command,
matches what&#039;s actually running            no reinstall)
</code></pre>
<p>An <strong>immutable OS</strong> is a system whose root filesystem cannot be changed in place — every change ships as a new, complete, versioned image, and the system swaps to it atomically or not at all. That&#8217;s the one-sentence answer, and it&#8217;s the reason this series exists: a hardening pipeline can prove an image is correct on the day it&#8217;s built, but on a traditional mutable root filesystem, nothing stops that proof from becoming false the day after.</p>
<hr />
<h2 id="the-gap-stratums-grade-doesnt-cover">The Gap Stratum&#8217;s Grade Doesn&#8217;t Cover</h2>
<p>Stratum&#8217;s series ended with a hardened, graded, pipeline-gated image — <code class="" data-line="">POST /api/pipeline/scan</code> fails the build if the grade drops below B, so an unhardened image never reaches production. That solved a real problem: images used to ship broken by default, and now they don&#8217;t.</p>
<p>But watch what happens six weeks later. An on-call engineer SSHes into a production node at 2 a.m. to unblock an incident and leaves behind a one-line <code class="" data-line="">iptables</code> rule that was never reviewed. A config-management run pushes an unrelated package upgrade because someone&#8217;s playbook target list was too broad. A well-meaning teammate installs a debugging tool &#8220;just for now&#8221; and forgets to remove it. None of this touches the build pipeline. None of it fails a scan, because no scan runs again after the image ships.</p>
<p>Six months later, an auditor asks for evidence that the instance matches its compliance grade. The honest answer is: it did, once, the day it was built. Nobody can say what&#8217;s true about it now — the golden image and the running system are two different, unreconciled things.</p>
<p>That&#8217;s the gap. Hardening is a build-time guarantee. Immutability is what makes it a runtime guarantee too, because there&#8217;s no path left for a change to happen except through the build pipeline that produced the image in the first place.</p>
<hr />
<h2 id="from-golden-images-to-immutable-os-a-short-history">From Golden Images to Immutable OS: A Short History</h2>
<p>Golden images (Stratum&#8217;s territory) solved the &#8220;every instance starts insecure&#8221; problem by baking the correct configuration in at build time — the same idea as infrastructure-as-code applied to an OS baseline. Configuration management tools (Ansible, Chef, Puppet) then tried to solve <em>drift</em> by re-applying the desired state on a schedule, converging the system back toward correctness every run.</p>
<p>Convergence is not the same as prevention. A config-management run that fires every 30 minutes still leaves a 29-minute window where the system can be anything. And convergence tools can only fix drift they know to look for — an ad-hoc <code class="" data-line="">apt install</code> that isn&#8217;t in anyone&#8217;s playbook just sits there, invisible, until someone happens to notice.</p>
<p>Immutable OS designs remove the window entirely. If the root filesystem is mounted read-only, <code class="" data-line="">apt install</code> on a running node doesn&#8217;t drift the system — it fails, because there&#8217;s nowhere to write the new package. The only way to add that package is to build a new image and boot into it. Prevention replaces convergence.</p>
<hr />
<h2 id="how-atomic-updates-actually-work">How Atomic Updates Actually Work</h2>
<p><!-- upload drafts/blog/immutable-os-series/diagram-immutable-architecture.png to WP media and swap src before publishing --></p>
<figure class="wp-block-image size-full" style="margin:1.5em 0 2em 0;">
<img decoding="async" src="diagram-immutable-architecture.png" alt="Golden image vs immutable OS — atomic A/B deployment and rollback compared to a traditional mutable root filesystem drifting after boot" class="wp-image-placeholder" style="width:100%;height:auto;display:block;border-radius:8px;"/><figcaption style="text-align:center;font-size:0.85em;color:#6b7280;margin-top:0.75em;">Left: a hardened golden image drifts once it&#8217;s live on a mutable root filesystem. Right: an immutable OS stages the next image fully before swapping to it atomically, with rollback as a first-class operation.</figcaption></figure>
<p>The core mechanism, used by ostree-based systems (Fedora CoreOS, Silverblue) and bootc alike, is <strong>A/B deployment</strong>:</p>
<ol>
<li><strong>Two deployment slots exist on disk at all times</strong> — call them A (active) and B (staged). Only one is booted at a time.</li>
<li><strong>An update downloads and assembles the entire new OS image into the inactive slot.</strong> This can take minutes. The running system is completely unaffected while it happens — there is no partial state visible to production traffic.</li>
<li><strong>The bootloader entry swaps atomically.</strong> This is a single operation, not a sequence of file writes — the system either boots the new deployment on next reboot, or it doesn&#8217;t. There&#8217;s no window where half the files are new and half are old.</li>
<li><strong>If the new deployment fails to boot or fails a health check, rolling back means booting the previous slot</strong> — the old deployment was never deleted, never modified. It&#8217;s still exactly what it was before the update.</li>
</ol>
<pre><code class="" data-line=""># Check current and staged deployments
$ rpm-ostree status
State: idle
Deployments:
● ostree://fedora:fedora/38/x86_64/coreos
                   Version: 38.20240210.3.0 (2024-02-10T09:14:22Z)
                   Commit: 8f2a1c...

  ostree://fedora:fedora/38/x86_64/coreos
                   Version: 38.20240115.2.0 (2024-01-15T11:02:03Z)
                   Commit: 3b7e9d...

# Roll back to the previous deployment — no rebuild, no reinstall
$ rpm-ostree rollback
Moving &#039;ostree://fedora:fedora/38/x86_64/coreos&#039; (38.20240115.2.0) to be first deployment
Run &quot;systemctl reboot&quot; to start a rollback

$ systemctl reboot
</code></pre>
<p>The <code class="" data-line="">●</code> marks the currently booted deployment. The second entry never disappeared when the update landed — it&#8217;s exactly the filesystem that was running two weeks ago, byte for byte, ready to boot again.</p>
<p>bootc — covered in depth in EP04 — applies the same A/B model but defines the OS image as an OCI container image, built with a standard <code class="" data-line="">Containerfile</code> and pushed to a normal container registry. The deployment mechanism is the same; the packaging format is the one most infrastructure teams already have tooling for.</p>
<hr />
<h2 id="what-you-give-up-and-what-you-get-back">What You Give Up, and What You Get Back</h2>
<table>
<thead>
<tr>
<th></th>
<th>Traditional mutable OS</th>
<th>Immutable OS</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="" data-line="">apt install</code>/<code class="" data-line="">dnf install</code> on a running node</td>
<td>Works, silently drifts the system</td>
<td>Fails — no writable path for it to take</td>
</tr>
<tr>
<td>Config-management convergence loop</td>
<td>Required to fight drift</td>
<td>Not needed — nothing to converge</td>
</tr>
<tr>
<td>&#8220;What changed since deployment?&#8221;</td>
<td>Shell history, playbook logs, guesswork</td>
<td><code class="" data-line="">rpm-ostree status</code> / <code class="" data-line="">bootc status</code> — exact, versioned answer</td>
</tr>
<tr>
<td>Undoing a bad update</td>
<td>Reinstall, restore from backup, or manual repair</td>
<td>One command, one reboot</td>
</tr>
<tr>
<td>Auditing compliance months later</td>
<td>Grade describes the image, not the running system</td>
<td>Grade describes the running system, because it can&#8217;t have changed</td>
</tr>
<tr>
<td>Debugging tools installed ad hoc</td>
<td>Common, invisible in inventory</td>
<td>Requires a new image — visible in version control</td>
</tr>
</tbody>
</table>
<p>The trade-off is real: an immutable OS removes a workflow a lot of engineers rely on — the quick SSH fix. That&#8217;s not a bug in the design. It&#8217;s the entire point. If the quick fix is impossible, it can&#8217;t happen accidentally, and it can&#8217;t happen without going through review.</p>
<hr />
<h2 id="three-ways-this-actually-ships-today">Three Ways This Actually Ships Today</h2>
<p>This series covers each of these in depth over the coming episodes — for now, know they exist and roughly where each one fits:</p>
<ul>
<li><strong>Fedora CoreOS / Silverblue</strong> (EP03) — ostree-based, general-purpose immutable Linux. CoreOS targets servers and container hosts; Silverblue targets immutable desktops. Both use <code class="" data-line="">rpm-ostree</code> for the deployment model shown above.</li>
<li><strong>bootc</strong> (EP04) — an immutable OS image defined as a container image and booted directly, no separate &#8220;OS build&#8221; toolchain from your application build toolchain. Newer, and increasingly the direction RHEL-family distros are heading.</li>
<li><strong>Talos Linux</strong> (EP05) — purpose-built for Kubernetes nodes. No SSH, no shell, no package manager at all — the only interface is an API (<code class="" data-line="">talosctl</code>). The most aggressive point on this spectrum: not just read-only, but no interactive access whatsoever.</li>
</ul>
<p>None of these require you to abandon Stratum. A bootc image or a Fedora CoreOS image can still be built from a hardened, CIS-benchmarked base — the hardening pipeline and the immutability model solve different problems and compose cleanly.</p>
<hr />
<h2 id="production-gotchas">Production Gotchas</h2>
<p><strong>Immutability doesn&#8217;t mean &#8220;no state.&#8221;</strong> <code class="" data-line="">/etc</code> and <code class="" data-line="">/var</code> are typically still writable on ostree-based systems (application data, logs, local config overrides have to live somewhere). &#8220;Immutable&#8221; means the <em>OS binaries and base configuration</em> can&#8217;t be mutated in place — read the docs for your specific distro to know exactly what&#8217;s writable.</p>
<p><strong>Rollback isn&#8217;t instant if you don&#8217;t test it first.</strong> <code class="" data-line="">rpm-ostree rollback</code> works, but if you&#8217;ve never practiced it, the first time you run it under incident pressure is the wrong time to discover a health check you forgot to configure. Rehearse rollback the same way you&#8217;d rehearse a database failover.</p>
<p><strong>Container image tooling doesn&#8217;t automatically make an OS image safe.</strong> bootc images are built like container images, which means it&#8217;s easy to accidentally treat them like disposable containers instead of long-lived OS deployments — with all the patching and lifecycle discipline that implies.</p>
<p><strong>Not everything you run today has an immutable-OS story yet.</strong> Legacy configuration management (Puppet/Chef agents that expect to write to <code class="" data-line="">/etc</code> continuously) and some monitoring agents assume a mutable filesystem. Check compatibility before you migrate a fleet.</p>
<hr />
<h2 id="quick-reference">Quick Reference</h2>
<pre><code class="" data-line=""># ostree/rpm-ostree (Fedora CoreOS, Silverblue)
rpm-ostree status                  # current + staged deployments
rpm-ostree upgrade                 # stage the next image
rpm-ostree rollback                # revert to the previous deployment
ostree admin status                # lower-level deployment inspection

# bootc
bootc status                       # current + staged image, digest-pinned
bootc upgrade                      # pull and stage the next image
bootc rollback                     # revert to the previous deployment

# Talos Linux (API-only, no shell)
talosctl version                   # node + API version
talosctl get machineconfig         # current applied config
talosctl upgrade --image &lt;ref&gt;     # stage a new node image
</code></pre>
<hr />
<h2 id="key-takeaways">Key Takeaways</h2>
<ul>
<li>A hardened image is a build-time guarantee; an immutable OS is what makes that guarantee hold at runtime too</li>
<li>Atomic A/B deployment means the system is never caught half-updated, and the previous deployment is always intact for rollback</li>
<li>Config-management convergence fights drift on a schedule; immutability removes the writable path drift needs to happen at all</li>
<li><code class="" data-line="">rpm-ostree</code>/<code class="" data-line="">bootc</code> give you an exact, versioned answer to &#8220;what changed&#8221; instead of shell history and guesswork</li>
<li>This composes with Stratum&#8217;s hardening pipeline — it doesn&#8217;t replace it</li>
</ul>
<hr />
<h2 id="whats-next">What&#8217;s Next</h2>
<p>EP01 established the gap: hardening proves an image correct once, at build time, and a mutable root filesystem gives that proof an expiration date nobody tracks. EP02 goes one level deeper into the mechanism that closes it — exactly how ostree and bootc implement atomic A/B updates under the hood, including how the bootloader is involved and what &#8220;atomic&#8221; actually guarantees.</p>
<p><em>Next: <a href="/atomic-os-updates-explained/">EP02 — Atomic OS Updates Explained: How ostree and bootc Actually Work</a></em></p>
<p>Get EP02 in your inbox when it publishes → <a href="https://linuxcent.com/subscribe">linuxcent.com/subscribe</a></p>
<p><a class="a2a_button_mastodon" href="https://www.addtoany.com/add_to/mastodon?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="Mastodon" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_email" href="https://www.addtoany.com/add_to/email?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="Email" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_whatsapp" href="https://www.addtoany.com/add_to/whatsapp?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="WhatsApp" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_reddit" href="https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="Reddit" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_x" href="https://www.addtoany.com/add_to/x?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="X" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_linkedin" href="https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="LinkedIn" rel="nofollow noopener" target="_blank"></a><a class="a2a_button_copy_link" href="https://www.addtoany.com/add_to/copy_link?linkurl=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&amp;linkname=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" title="Copy Link" rel="nofollow noopener" target="_blank"></a><a class="a2a_dd addtoany_share_save addtoany_share" href="https://www.addtoany.com/share#url=https%3A%2F%2Flinuxcent.com%2Fwhat-is-immutable-os%2F&#038;title=What%20Is%20an%20Immutable%20OS%20%E2%80%94%20and%20Why%20Hardening%20Isn%E2%80%99t%20Enough" data-a2a-url="https://linuxcent.com/what-is-immutable-os/" data-a2a-title="What Is an Immutable OS — and Why Hardening Isn’t Enough"></a></p><p>The post <a href="https://linuxcent.com/what-is-immutable-os/">What Is an Immutable OS — and Why Hardening Isn&#8217;t Enough</a> appeared first on <a href="https://linuxcent.com">Linuxcent</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://linuxcent.com/what-is-immutable-os/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2183</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 

Served from: linuxcent.com @ 2026-08-23 10:16:17 by W3 Total Cache
-->