<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Timur Tukaev</title>
    <description>The latest articles on DEV Community by Timur Tukaev (@tym83).</description>
    <link>https://dev.to/tym83</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4106498%2F37805902-9d62-4acf-bbd1-17db344af684.jpg</url>
      <title>DEV Community: Timur Tukaev</title>
      <link>https://dev.to/tym83</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tym83"/>
    <language>en</language>
    <item>
      <title>I built a real container orchestrator that runs on a Google Sheet</title>
      <dc:creator>Timur Tukaev</dc:creator>
      <pubDate>Wed, 02 Sep 2026 15:59:44 +0000</pubDate>
      <link>https://dev.to/tym83/i-built-a-real-container-orchestrator-that-runs-on-a-google-sheet-4k2h</link>
      <guid>https://dev.to/tym83/i-built-a-real-container-orchestrator-that-runs-on-a-google-sheet-4k2h</guid>
      <description>&lt;p&gt;Some projects start as a bad idea you can't shake. Mine was: what if the only rule was "keep everything inside a spreadsheet"?&lt;/p&gt;

&lt;p&gt;Not "export metadata to a CSV." Not "log to Sheets." I mean the whole control plane. Deployments, Nodes, Pods, Events. They're tabs. A scheduler reads and writes cells. A &lt;code&gt;kubectl&lt;/code&gt;-style CLI talks to the sheet. And on the other end, real Docker containers actually start.&lt;/p&gt;

&lt;p&gt;The spreadsheet doesn't pretend to be a cluster. It &lt;em&gt;is&lt;/em&gt; the cluster.&lt;/p&gt;

&lt;p&gt;I called it &lt;strong&gt;Sheeternetes&lt;/strong&gt;. It's a joke. It also compiles, has tests, and survives a node dying. Let me show you how it works, how to run it in five minutes, how it goes air-gapped on a desktop Excel file, and the part I'm weirdly proud of: you can store a whole container image inside the cells and even boot DOOM from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, the obligatory disclaimer
&lt;/h2&gt;

&lt;p&gt;Don't run production on this. If you do, film the save dialog.&lt;/p&gt;

&lt;p&gt;Everything below is real code though. The scheduler does bin-packing and failover. There's HMAC request signing, make-before-break live migration, and a container image format that lives in cells. The substrate is cursed. The engineering isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea in one picture
&lt;/h2&gt;

&lt;p&gt;Kubernetes, squinting: desired state in etcd, controllers that drag reality toward it. Swap etcd for a Sheets tab and the controller for a reconcile loop, and you've got Sheeternetes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7b0lgy0k14dzz0tyhfgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7b0lgy0k14dzz0tyhfgr.png" alt="Your cluster is a spreadsheet" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The sheet&lt;/strong&gt; is the store and the source of truth. Four tabs: &lt;code&gt;Deployments&lt;/code&gt;, &lt;code&gt;Nodes&lt;/code&gt;, &lt;code&gt;Pods&lt;/code&gt;, &lt;code&gt;Events&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The apiserver&lt;/strong&gt; serves the data and runs the scheduler. In the cloud that's Google Apps Script bound to the sheet. On-prem it's a small Python server over an &lt;code&gt;.xlsx&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The kubelet&lt;/strong&gt; is a bash script. It turns any Docker host into a node: sends a heartbeat, gets the pods it should run, and makes local Docker match.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;skctl&lt;/strong&gt; is a tiny kubectl. Just &lt;code&gt;curl&lt;/code&gt; and &lt;code&gt;jq&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The contract is small enough to fit in a tweet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET  ?token=T&amp;amp;kind=pods|nodes|deployments|events   -&amp;gt;  { "items": [...] }
POST { token, action: "apply"|"scale"|"delete", ... }
POST { token, node, pods:[...] }                    # kubelet heartbeat -&amp;gt; desired pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Five minutes to a cluster
&lt;/h2&gt;

&lt;p&gt;Cloud version, on Google Sheets. You need a Google account, a Docker host, and &lt;code&gt;bash curl jq&lt;/code&gt;. All the code is in &lt;a href="https://github.com/sncfoundation/sheeternetes" rel="noopener noreferrer"&gt;github.com/sncfoundation/sheeternetes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's no template to copy, on purpose. A blank sheet turns itself into a cluster:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a blank Google Sheet.&lt;/li&gt;
&lt;li&gt;Extensions, then Apps Script, and paste in &lt;code&gt;Code.gs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set a &lt;code&gt;TOKEN&lt;/code&gt; at the top.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;setup()&lt;/code&gt; once. It builds the four tabs, seeds a couple of sample workloads, and starts a one-minute reconcile trigger.&lt;/li&gt;
&lt;li&gt;Deploy as a Web app and copy the &lt;code&gt;/exec&lt;/code&gt; URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now bring up a node on any Docker box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WEBAPP_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://script.google.com/macros/s/XXXX/exec
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;secret
&lt;span class="nv"&gt;NODE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node-a &lt;span class="nv"&gt;CPU_TOTAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4000 &lt;span class="nv"&gt;MEM_TOTAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8192 ./kubelet.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No spare machines? &lt;code&gt;./local-cluster.sh&lt;/code&gt; fakes three nodes on one Docker daemon.&lt;/p&gt;

&lt;p&gt;Deploy something. The manifest is plain JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"deployments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"web"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nginx:alpine"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nl"&gt;"replicas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cpu_req"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mem_req"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hashicorp/http-echo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"replicas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"cpu_req"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"mem_req"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-text=hello-from-a-spreadsheet -listen=:8080"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skctl apply lab/hello-web.json
skctl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the moment that got me. You open the sheet and your cluster is &lt;em&gt;right there&lt;/em&gt; as rows. Change &lt;code&gt;replicas&lt;/code&gt; in a cell and the next reconcile spins up the pods. It's &lt;code&gt;kubectl edit&lt;/code&gt;, except the editor is your cursor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyk9cihy5cgl48m0ldn28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyk9cihy5cgl48m0ldn28.png" alt="Your cluster is a spreadsheet" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And in the terminal it looks suspiciously grown-up:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmfzux4z9rb3ftnta7ym4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmfzux4z9rb3ftnta7ym4.png" alt="skctl doing kubectl things" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The containers are real. &lt;code&gt;docker ps&lt;/code&gt; on the node proves it. Sheetlium (our Cilium) drops them on a shared Docker network and gives each deployment a DNS alias, which is basically a Service.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scheduler is not a toy
&lt;/h2&gt;

&lt;p&gt;The usual reaction is "it's just a list." It isn't. On every heartbeat the apiserver actually places replicas, and it's a pure function with unit tests behind it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bin-packing&lt;/strong&gt; by &lt;code&gt;cpu_req&lt;/code&gt; and &lt;code&gt;mem_req&lt;/code&gt;. Fits nowhere, gets marked &lt;code&gt;Unschedulable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sticky placement&lt;/strong&gt;, so pods don't wander between nodes for no reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failover&lt;/strong&gt;. A node stops sending heartbeats, goes &lt;code&gt;NotReady&lt;/code&gt;, and its pods land on the survivors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cordon, drain, migrate&lt;/strong&gt;, the kubectl way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Affinity and taints/tolerations&lt;/strong&gt;, so GPU jobs go to GPU nodes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;skctl drain node-a          &lt;span class="c"&gt;# pods evacuate to other nodes&lt;/span&gt;
skctl taint node-a &lt;span class="nv"&gt;gpu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;:NoSchedule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watching pods hop off a dying node, in a spreadsheet, live, is a genuinely good time.&lt;/p&gt;

&lt;h2&gt;
  
  
  SheetOS, because the node needs an OS
&lt;/h2&gt;

&lt;p&gt;If you have an orchestrator, you want a node OS to go with it. &lt;strong&gt;SheetOS&lt;/strong&gt; is our Talos: minimal, immutable, declaratively configured, and self-bootstrapping. &lt;code&gt;sheetstrap&lt;/code&gt; reads the node's desired image from a sheet, brings up the runtime, registers as a Node, and if you ask nicely, installs a Sheeternetes cluster on top of itself.&lt;/p&gt;

&lt;p&gt;Yes, that's a spreadsheet OS bootstrapping a spreadsheet cluster. Try not to think about it too hard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bare metal: no cloud, no internet
&lt;/h2&gt;

&lt;p&gt;The cloud version is fun, but the real flex is running this air-gapped on a desktop file. That's the &lt;code&gt;sheeternetes-onprem&lt;/code&gt; edition. The apiserver is a local Python process over an &lt;code&gt;.xlsx&lt;/code&gt;, same contract as the cloud, so &lt;code&gt;kubelet.sh&lt;/code&gt; and &lt;code&gt;skctl&lt;/code&gt; point at it unchanged.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;openpyxl
&lt;span class="nb"&gt;cp&lt;/span&gt; .skctl.env.example .skctl.env

make up      &lt;span class="c"&gt;# apiserver over cluster.xlsx&lt;/span&gt;
make node    &lt;span class="c"&gt;# this host becomes a node&lt;/span&gt;
make apply   &lt;span class="c"&gt;# deploy the demo&lt;/span&gt;
make pods    &lt;span class="c"&gt;# watch it schedule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It bin-packs and fails over between LAN nodes, on a &lt;code&gt;.xlsx&lt;/code&gt;. About Excel vs LibreOffice: openpyxl reads &lt;code&gt;.xlsx&lt;/code&gt;, so in LibreOffice Calc just Save As &lt;code&gt;.xlsx&lt;/code&gt;. Native &lt;code&gt;.ods&lt;/code&gt; is on the list. And this edition ships with 52 tests and CI, because a joke with no tests is just a liability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wiring sheets together
&lt;/h2&gt;

&lt;p&gt;One cluster is boring. The good part is federating several, including different kinds: a local Excel cluster talking to a cloud Google Sheets cluster.&lt;/p&gt;

&lt;p&gt;On-prem boxes can't be reached from outside, so the bridge dials out. It reads the local apiserver and reconciles against a peer, giving you cross-substrate service discovery. Then the fun one, live migration, make-before-break:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 bridge.py migrate web &lt;span class="nt"&gt;--from&lt;/span&gt; &lt;span class="nb"&gt;local&lt;/span&gt; &lt;span class="nt"&gt;--to&lt;/span&gt; peer &lt;span class="nt"&gt;--rollback-window&lt;/span&gt; 30 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--local&lt;/span&gt; http://localhost:8787 &lt;span class="nt"&gt;--local-token&lt;/span&gt; secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--peer&lt;/span&gt;  https://script.google.com/macros/s/XXXX/exec &lt;span class="nt"&gt;--peer-token&lt;/span&gt; secret2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the spec to the target, wait until it's actually up, then drain the source. If the target never comes up, the source is left alone, so there's no downtime. Add &lt;code&gt;--rollback-window&lt;/code&gt; and it watches the target after cutover and rolls back if it degrades.&lt;/p&gt;

&lt;p&gt;There's also two-way &lt;code&gt;sync&lt;/code&gt; as a daemon, and optional HMAC signing on requests (timestamp plus signature, checked within a TTL) for when your peer is exposed across substrates. We have HMAC on spreadsheets now. I'm not sure how to feel about it either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two kinds of containers, and yes, DOOM
&lt;/h2&gt;

&lt;p&gt;This is my favorite part. Sheeternetes runs containers two ways, and they're interchangeable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OCI mode.&lt;/strong&gt; Put &lt;code&gt;image: nginx:alpine&lt;/code&gt; in the manifest and the node pulls it from a normal registry. Full compatibility with the entire container world, working today. The sheet just holds desired state; the bytes come from Docker Hub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SICF native mode.&lt;/strong&gt; Put &lt;code&gt;image: sicf:web:v1&lt;/code&gt; and the image is resolved from &lt;em&gt;inside the workbook&lt;/em&gt;. Layers are stored as base64, split across cells, addressed by sha256. No registry. The kubelet pulls the layers out of the sheet, checks every digest, and runs it.&lt;/p&gt;

&lt;p&gt;There's a lossless bridge between the two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sheetbuild import nginx:alpine   &lt;span class="c"&gt;# OCI image  -&amp;gt; rows in the sheet&lt;/span&gt;
sheetbuild &lt;span class="nb"&gt;export &lt;/span&gt;web:v1 ...     &lt;span class="c"&gt;# rows       -&amp;gt; OCI image&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same digests round-trip, so import then export gets you back exactly what you started with.&lt;/p&gt;

&lt;p&gt;Which brings us to the question every infra project must answer. Can it run DOOM? It can, and the whole game lives in the cells. Shareware DOOM plus a tiny web front-end is a few hundred base64 cells, nowhere near the 10M-cell limit. The demo that makes people blink:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; doom:shareware &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker save doom:shareware &lt;span class="nt"&gt;-o&lt;/span&gt; doom.tar
sheetbuild import doom.tar &lt;span class="nt"&gt;--name&lt;/span&gt; doom:shareware &lt;span class="nt"&gt;--store&lt;/span&gt; cluster.xlsx
docker rmi doom:shareware        &lt;span class="c"&gt;# gone locally. it only exists in the spreadsheet now.&lt;/span&gt;
skctl apply doom.json            &lt;span class="c"&gt;# image: sicf:doom:shareware&lt;/span&gt;
skctl get pods                   &lt;span class="c"&gt;# doom-1  Running&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The kubelet saw &lt;code&gt;sicf:&lt;/code&gt;, fetched the layers from the sheet, verified the hashes, &lt;code&gt;docker load&lt;/code&gt;ed the image back into existence, and ran it. The game came out of a spreadsheet. Code is at &lt;a href="https://github.com/sncfoundation/sheetdoom" rel="noopener noreferrer"&gt;github.com/sncfoundation/sheetdoom&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One honest note: the game still runs on the node's real CPU. The sheet stores the image and schedules the pod. It's the coordinator, never the executor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboards, in cells
&lt;/h2&gt;

&lt;p&gt;Of course there are dashboards. &lt;strong&gt;Sheetheus&lt;/strong&gt; scrapes metrics into a tab, &lt;strong&gt;Sheetfana&lt;/strong&gt; renders them with conditional formatting and sparklines, in the sheet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9vsf8ao6zq95smkyjuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9vsf8ao6zq95smkyjuk.png" alt="Sheetfana" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pods running, nodes ready, CPU allocated, a bar chart, a time series. All cells.&lt;/p&gt;

&lt;h2&gt;
  
  
  It grew a foundation
&lt;/h2&gt;

&lt;p&gt;At some point there were enough projects that they asked for a foundation. So there's the &lt;strong&gt;Sheet-Native Computing Foundation&lt;/strong&gt;, a straight-faced parody of the CNCF that happens to work.&lt;/p&gt;

&lt;p&gt;There's a real standard, the &lt;strong&gt;Sheet Container Initiative&lt;/strong&gt;, modeled on the OCI: SCRI for the runtime interface and SICF for images, both written from shipping code, with a conformance suite. Where you have two implementations, you should have a spec, and we had two.&lt;/p&gt;

&lt;p&gt;There's verifiable certification. You open an issue, a GitHub Action mints a serial like &lt;code&gt;SFE000001&lt;/code&gt; into a public registry, and you collect credentials toward ranks: SheetCadet, SheetAstronaut, SheetCommander, SheetAdmiral.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc6ma3a6k8lru09cbja3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc6ma3a6k8lru09cbja3b.png" alt="Certified Sheeternetes Fundamentals Engineer" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzising1zgt7dm8v9b2hu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzising1zgt7dm8v9b2hu.png" alt="SheetAdmiral" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it's genuinely open. A community contributor recently built SheetHub, our GitLab-on-a-spreadsheet, from scratch: apiserver, web UI, CLI, tests. It went through a real review, picked up a couple of security findings, got fixed in hours, and shipped. That's the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come build weird things
&lt;/h2&gt;

&lt;p&gt;The community is international and English-speaking, so join from anywhere.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get &lt;a href="https://sncfoundation.github.io/certification.html" rel="noopener noreferrer"&gt;certified&lt;/a&gt;, serial number included.&lt;/li&gt;
&lt;li&gt;Grab a good first issue on &lt;a href="https://github.com/sncfoundation" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Say hi on &lt;a href="https://sncfoundation.github.io/slack.html" rel="noopener noreferrer"&gt;Slack&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The actual point
&lt;/h2&gt;

&lt;p&gt;None of this belongs in production. But building a working cloud-native stack on a ridiculous substrate turned out to be a great way to explain the real thing. People finally &lt;em&gt;see&lt;/em&gt; reconcile happen. They get why make-before-break matters, what a digest is for, why a control plane is separate from execution. Sometimes the fastest way to teach a serious idea is to build it somewhere silly.&lt;/p&gt;

&lt;p&gt;It reconciles.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>containers</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
