<?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: Mario Ezquerro</title>
    <description>The latest articles on DEV Community by Mario Ezquerro (@marioezquerro).</description>
    <link>https://dev.to/marioezquerro</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%2F878530%2F7288c9b0-63e5-4a85-b7a1-be9f1234dfbd.jpeg</url>
      <title>DEV Community: Mario Ezquerro</title>
      <link>https://dev.to/marioezquerro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marioezquerro"/>
    <language>en</language>
    <item>
      <title>Building Enterprise Storage, Backups &amp; Cosign Image Security in Go &amp; Flutter with Google Antigravity</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Thu, 20 Aug 2026 18:13:27 +0000</pubDate>
      <link>https://dev.to/gde/building-enterprise-storage-backups-cosign-image-security-in-go-flutter-with-google-antigravity-3ao3</link>
      <guid>https://dev.to/gde/building-enterprise-storage-backups-cosign-image-security-in-go-flutter-with-google-antigravity-3ao3</guid>
      <description>&lt;h1&gt;
  
  
  Building Enterprise Storage, Point-in-Time Backups &amp;amp; Cosign Image Security in Go &amp;amp; Flutter with Google Antigravity
&lt;/h1&gt;

&lt;p&gt;When architecting a modern container orchestrator like &lt;strong&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;Gubernator (gbnt)&lt;/a&gt;&lt;/strong&gt; — designed to strike the &lt;strong&gt;Goldilocks balance&lt;/strong&gt; between the simplicity of Docker Swarm and the placement flexibility of Nomad — two major enterprise pillars stand between an MVP and true production readiness:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;State Persistence &amp;amp; Backup Mobility (&lt;em&gt;The Granaries / Horreum&lt;/em&gt;)&lt;/strong&gt;: Moving stateful containers (PostgreSQL, MySQL, Redis, custom data volumes) across worker nodes without data loss, backed by compressed point-in-time snapshots and retention policies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software Supply Chain Security &amp;amp; Admission Control (&lt;em&gt;The Imperial Seal / Armamentarium&lt;/em&gt;)&lt;/strong&gt;: Detecting CVE vulnerabilities before deployment, cataloging dependencies via Software Bill of Materials (SBOM), signing container images with cryptographic keypairs (Cosign/Sigstore), and enforcing strict Gatekeeper admission policies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we break down how we designed and implemented these two major subsystems in &lt;strong&gt;Gubernator v2.24.0 &amp;amp; v2.25.0&lt;/strong&gt;, and how we leveraged &lt;strong&gt;Google Antigravity (AGY)&lt;/strong&gt; as an autonomous AI engineering partner to architect, implement, test, and live-deploy Full-Stack features (Go + SQLite + Flutter Web + CLI) across a live 3-node multi-host cluster.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: Persistent Storage &amp;amp; The Backup Subsystem (&lt;em&gt;The Granaries&lt;/em&gt;)
&lt;/h2&gt;

&lt;p&gt;Stateful container workloads present a fundamental orchestration challenge: &lt;strong&gt;how can a container move between different physical hosts while maintaining access to its persistent disk storage?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ┌─────────────────────────────────────────────────────────────────────────┐
 │                   GUBERNATOR STORAGE &amp;amp; BACKUP ENGINE                     │
 ├─────────────────────────────────────────────────────────────────────────┤
 │   /var/contenedores (Shared Mobility Pool: NFS, GlusterFS, CephFS)    │
 │   Point-in-Time Compressed Tarballs (.tar.gz) + SHA-256 Checksums     │
 │   Background Cron Scheduler &amp;amp; Automated Retention Pruning            │
 │   Zero-Downtime Consistent Freeze (docker pause -&amp;gt; tar -&amp;gt; unpause)    │
 └─────────────────┬───────────────────────────────────┬───────────────────┘
                   │                                   │
                   ▼                                   ▼
      ┌─────────────────────────┐         ┌─────────────────────────┐
      │  Centurion 1 (Manager)  │         │  Centurion 2 (Worker 1) │
      │   IP: 192.168.252.27    │         │   IP: 192.168.252.25    │
      │  Mount: /var/contened.. │         │  Mount: /var/contened.. │
      └─────────────────────────┘         └─────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Shared Storage Mobility (&lt;code&gt;/var/contenedores&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Gubernator standardizes volume mobility by designating &lt;code&gt;/var/contenedores&lt;/code&gt; across all cluster nodes. When backed by a distributed file system (NFS, GlusterFS, CephFS, CIFS) or localized volumes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The orchestrator can dynamically schedule database or application containers to any active Centurion host.&lt;/li&gt;
&lt;li&gt;The storage explorer inspects and displays disk utilization (&lt;code&gt;used / total&lt;/code&gt;, percentage, and node read/write mount health).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Database-Consistent Snapshots with Docker Freeze
&lt;/h3&gt;

&lt;p&gt;Backing up a running relational database (PostgreSQL, MariaDB, SQLite) while active transactions are in flight risks data corruption. &lt;/p&gt;

&lt;p&gt;We implemented an optional &lt;strong&gt;Atomic Freeze Strategy&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// internal/storage/backup.go&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CreateBackup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targetPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stackName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serviceName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pauseContainer&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Backup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pauseContainer&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;containerID&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;slog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"backup: pausing container for consistent snapshot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;containerID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dockerClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContainerPause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;containerID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;dockerClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContainerUnpause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;containerID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Stream directory to tar.gz with SHA-256 calculation&lt;/span&gt;
    &lt;span class="n"&gt;archiveFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sha256Checksum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sizeBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;archiveDirectory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;destFile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c"&gt;// ... Save record to SQLite ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Automated Cron Policies &amp;amp; Retention Rotation
&lt;/h3&gt;

&lt;p&gt;Gubernator's background backup daemon evaluates standard cron expressions (e.g. &lt;code&gt;0 2 * * *&lt;/code&gt; for nightly 2:00 AM backups) and automatically prunes older snapshots according to a configured retention count (e.g. keep last 7 copies).&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: Image Security, SBOM &amp;amp; Cosign Cryptography (&lt;em&gt;The Imperial Seal&lt;/em&gt;)
&lt;/h2&gt;

&lt;p&gt;Deploying third-party container images blindly introduces severe supply-chain risks. In &lt;strong&gt;v2.25.0&lt;/strong&gt;, we introduced a complete &lt;strong&gt;Pre-Deployment Admission Gatekeeper&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         [ Stack Deploy / Container Run Request ]
                                          │
                                          ▼
                 ┌──────────────────────────────────────────────────┐
                 │     GUBERNATOR ADMISSION GATEKEEPER (Port 4000)   │
                 │     - Evaluates Cluster &amp;amp; Stack Security Policy  │
                 └────────────────────────┬─────────────────────────┘
                                          │
          ┌───────────────────────────────┴───────────────────────────────┐
          ▼                                                               ▼
 ┌───────────────────────────┐                                 ┌───────────────────────────┐
 │  1. Cryptographic Sign  │                                 │ 🔍 2. CVE Vulnerability   │
 │    (Cosign / Sigstore)    │                                 │    Scanning &amp;amp; CVSS Scores │
 ├───────────────────────────┤                                 ├───────────────────────────┤
 │ Is the image signed with  │                                 │ Does image exceed Max     │
 │ a trusted cluster key?    │                                 │ Severity (Critical/High)? │
 └─────────────┬─────────────┘                                 └─────────────┬─────────────┘
               │                                                             │
               ├───────── ❌ Unsigned / Invalid                              ├───────── ❌ Exceeds Threshold
               │          (If policy = 'ENFORCE')                            │          (If policy = 'BLOCK')
               ▼                                                             ▼
 ╔═══════════════════════════╗                                 ╔═══════════════════════════╗
 ║  ⛔ DEPLOYMENT REJECTED   ║                                 ║   ⛔ DEPLOYMENT BLOCKED   ║
 ║ "Signature check failed"  ║                                 ║ "Found 2 Critical CVEs"   ║
 ╚═══════════════════════════╝                                 ╚═══════════════════════════╝
               │                                                             │
               └──────────────────────────┬──────────────────────────────────┘
                                          │ ✅ Passes All Admission Checks
                                          ▼
                         ╔═════════════════════════════════╗
                         ║ 🚀 Container Scheduled on Hosts ║
                         ╚═════════════════════════════════╝
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Pure Go Cosign ECDSA Keypair Generation &amp;amp; Signing
&lt;/h3&gt;

&lt;p&gt;To eliminate heavy external binary dependencies like &lt;code&gt;cosign&lt;/code&gt; or CGO toolchains, we implemented the cryptographic signing engine using Go's standard library (&lt;code&gt;crypto/ecdsa&lt;/code&gt;, &lt;code&gt;crypto/elliptic&lt;/code&gt;, &lt;code&gt;crypto/x509&lt;/code&gt;, &lt;code&gt;crypto/sha256&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// internal/security/signing.go&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GenerateCosignKeypair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubPEM&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;privPEM&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ecdsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elliptic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;P256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;privBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarshalECPrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;privPEMBlock&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"EC PRIVATE KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;privBytes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;privPEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeToMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;privPEMBlock&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;pubBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;x509&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarshalPKIXPublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;privKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pubPEMBlock&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"PUBLIC KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pubBytes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;pubPEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EncodeToMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pubPEMBlock&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pubPEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;privPEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Multi-Standard SBOM Generator (CycloneDX &amp;amp; SPDX)
&lt;/h3&gt;

&lt;p&gt;For software inventory audits and compliance, Gubernator automatically analyzes container image layers, extracts packages and OS libraries (musl, glibc, OpenSSL, busybox), and exports standardized Software Bill of Materials in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CycloneDX 1.5 JSON&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SPDX 2.3 JSON&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Cluster-Wide Auto-Discovery &amp;amp; Host Mapping
&lt;/h3&gt;

&lt;p&gt;Rather than requiring users to register images manually, Gubernator continuously discovers all container images running across every node in the cluster (&lt;code&gt;Manager&lt;/code&gt;, &lt;code&gt;Worker 1&lt;/code&gt;, &lt;code&gt;Worker 2&lt;/code&gt;). The UI dynamically renders &lt;strong&gt;host badges and service tags&lt;/strong&gt; indicating where every container instance is hosted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: The Flutter Web Dashboard Visualization
&lt;/h2&gt;

&lt;p&gt;Gubernator's Web Dashboard (Port 4001) provides two rich Material Design 3 interfaces:&lt;/p&gt;

&lt;h3&gt;
  
  
  Storage &amp;amp; Backups (The Granaries)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Volumes Table&lt;/strong&gt;: Displays Named Volumes, Shared Pools, and Host Bind Mounts with live disk usage calculations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot Manager&lt;/strong&gt;: 1-click on-demand backup creation, direct &lt;code&gt;.tar.gz&lt;/code&gt; browser downloads, and backup restore modals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pool Health Matrix&lt;/strong&gt;: Validates mount availability, read/write permissions, and free disk space across all cluster hosts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Image Security &amp;amp; SBOM (The Imperial Seal)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;** Vulnerabilities Tab**: Real-time image catalog displaying Critical, High, Medium, Low CVE counts, verified signature badges, and host mappings (&lt;code&gt;Used in: caddy, promtail on Manager, Worker 1, Worker 2&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;** SBOM Explorer Tab**: Component dependency tree with license compliance auditing and 1-click CycloneDX/SPDX downloads.&lt;/li&gt;
&lt;li&gt;** Signatures &amp;amp; Keys Tab**: In-cluster Cosign ECDSA keypair generator and image signing terminal.&lt;/li&gt;
&lt;li&gt;** Gatekeeper Policies Tab**: Interactive admission policy switches (&lt;code&gt;Audit / Warn Only&lt;/code&gt; vs &lt;code&gt;Strict Enforcement&lt;/code&gt;, CVE severity threshold blocking).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚡ Part 4: Full CLI Parity
&lt;/h2&gt;

&lt;p&gt;Every capability is accessible directly through the &lt;code&gt;gbnt&lt;/code&gt; CLI:&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="c"&gt;# === Storage &amp;amp; Backups ===&lt;/span&gt;
gbnt volume &lt;span class="nb"&gt;ls
&lt;/span&gt;gbnt backup &lt;span class="nb"&gt;ls
&lt;/span&gt;gbnt backup create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"postgres-nightly"&lt;/span&gt; &lt;span class="nt"&gt;--pause&lt;/span&gt; /var/contenedores/postgres
gbnt backup restore &amp;lt;backup-id&amp;gt; &lt;span class="nt"&gt;--target&lt;/span&gt; /var/contenedores/postgres

&lt;span class="c"&gt;# === Image Security &amp;amp; SBOM ===&lt;/span&gt;
gbnt scan
gbnt scan postgres:16-alpine
gbnt sbom postgres:16-alpine &lt;span class="nt"&gt;--format&lt;/span&gt; cyclonedx-json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; sbom.json

&lt;span class="c"&gt;# === Cosign Signing &amp;amp; Verification ===&lt;/span&gt;
gbnt security key generate &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"prod-release-key"&lt;/span&gt;
gbnt image sign company/payments:2.1.0 &lt;span class="nt"&gt;--key&lt;/span&gt; /path/to/private.key
gbnt image verify company/payments:2.1.0

&lt;span class="c"&gt;# === Cluster Gatekeeper Policy ===&lt;/span&gt;
gbnt security policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Part 5: How We Built This with Google Antigravity (AGY)
&lt;/h2&gt;

&lt;p&gt;Building a distributed orchestrator with state synchronization, cryptographic operations, cross-compilation, and Full-Stack Web UIs is an intricate endeavor. Here is how &lt;strong&gt;Google Antigravity&lt;/strong&gt; accelerated development:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Specification-Driven Engineering
&lt;/h3&gt;

&lt;p&gt;Before writing code, we used Antigravity to formalize comprehensive architectural blueprints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator/blob/main/SPEC-storage-backups.md" rel="noopener noreferrer"&gt;&lt;code&gt;SPEC-storage-backups.md&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator/blob/main/SPEC-image-security.md" rel="noopener noreferrer"&gt;&lt;code&gt;SPEC-image-security.md&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having structured specifications allowed the AI to implement the entire pipeline (GORM database schemas, pure Go cryptography, REST API routes, Flutter Dart models, and CLI flags) with complete architectural alignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Autonomous Root-Cause Debugging
&lt;/h3&gt;

&lt;p&gt;During initial testing of the backup scheduler, we encountered a recursive mutex deadlock: &lt;code&gt;StartBackupScheduler()&lt;/code&gt; was holding &lt;code&gt;cronMutex.Lock()&lt;/code&gt; while calling &lt;code&gt;SyncSchedules()&lt;/code&gt;, which also attempted to acquire &lt;code&gt;cronMutex.Lock()&lt;/code&gt;. Antigravity inspected the call graph, refactored &lt;code&gt;syncSchedulesLocked()&lt;/code&gt;, and verified thread-safety without human intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Live Cluster Deployment &amp;amp; Verification
&lt;/h3&gt;

&lt;p&gt;Antigravity seamlessly built Linux ARM64 binaries (&lt;code&gt;CGO_ENABLED=0 GOOS=linux GOARCH=arm64&lt;/code&gt;), transferred them to a live 3-node Multipass virtualized cluster (&lt;code&gt;gbnt-manager&lt;/code&gt;, &lt;code&gt;gbnt-worker1&lt;/code&gt;, &lt;code&gt;gbnt-worker2&lt;/code&gt;), and executed live HTTP and CLI verification checks against Port 4000, 4001, and 4002.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Conclusion &amp;amp; What's Next
&lt;/h2&gt;

&lt;p&gt;With &lt;strong&gt;Storage &amp;amp; Backups (v2.24.0)&lt;/strong&gt; and &lt;strong&gt;Image Security &amp;amp; Cosign (v2.25.0)&lt;/strong&gt;, Gubernator bridges the gap between lightweight simplicity and enterprise-grade resilience.&lt;/p&gt;

&lt;p&gt;Whether you are running a single-node homelab or an edge-distributed cluster, you can now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run stateful databases with confidence using point-in-time compressed backups.&lt;/li&gt;
&lt;li&gt;Secure your software supply chain with automated CVE scanning and Cosign cryptographic signatures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explore the project on GitHub:&lt;br&gt;
 &lt;strong&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;GitHub: mario-ezquerro/gubernator&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://mario-ezquerro.github.io/gubernator/" rel="noopener noreferrer"&gt;Official Documentation &amp;amp; Guides&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you implemented image signing or shared volume mobility in your container setups? Share your thoughts in the comments below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gubernator</category>
      <category>docker</category>
      <category>antigravity</category>
    </item>
    <item>
      <title>Building Enterprise Active Directory, LDAP &amp; Dynamic RBAC in Go &amp; Flutter with Google Antigravity</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Mon, 17 Aug 2026 09:00:16 +0000</pubDate>
      <link>https://dev.to/gde/building-enterprise-active-directory-ldap-dynamic-rbac-in-go-flutter-with-google-antigravity-4al4</link>
      <guid>https://dev.to/gde/building-enterprise-active-directory-ldap-dynamic-rbac-in-go-flutter-with-google-antigravity-4al4</guid>
      <description>&lt;h1&gt;
  
  
  Building Enterprise Active Directory, LDAP &amp;amp; Dynamic RBAC in Go &amp;amp; Flutter with Google Antigravity
&lt;/h1&gt;

&lt;p&gt;When building a lightweight container orchestrator like &lt;strong&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;Gubernator (gbnt)&lt;/a&gt;&lt;/strong&gt; — designed to strike the perfect balance between the &lt;strong&gt;simplicity of Docker Swarm&lt;/strong&gt; and the &lt;strong&gt;flexibility of Nomad&lt;/strong&gt; under a Roman Empire theme — a critical milestone inevitably emerges: &lt;strong&gt;Enterprise Security and Access Control&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While a default &lt;code&gt;admin&lt;/code&gt; credential works well for local dev environments, moving into enterprise production with multi-disciplinary engineering teams demands:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Corporate Single Sign-On (SSO)&lt;/strong&gt; with Microsoft Active Directory and OpenLDAP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role-Based Access Control (RBAC)&lt;/strong&gt; to clearly segregate who can deploy stacks, restart containers, or audit telemetries in read-only mode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Group Mapping&lt;/strong&gt; from corporate security groups (&lt;code&gt;memberOf&lt;/code&gt;) to orchestrator roles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emergency Break-Glass Access&lt;/strong&gt; (Local Administrator) in case network directory controllers are unreachable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we explore the complete architecture of the enterprise security engine introduced in &lt;strong&gt;Gubernator v2.20.0&lt;/strong&gt;, and how we leveraged &lt;strong&gt;Google Antigravity (AGY)&lt;/strong&gt; as an autonomous AI pair programmer to design, implement, test, and verify this Full-Stack feature (Go + Flutter Web) across a live 3-node cluster.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Security Architecture
&lt;/h2&gt;

&lt;p&gt;We designed a decoupled, asymmetric architecture connecting identity providers, REST API middleware, and the Flutter Web UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ┌────────────────────────────────────────────────────────┐
 │                   GUBERNATOR WEB UI                    │
 │   - Modern Login Screen with Domain / AD Selector      │
 │   - Header Role Badge: Admin |  Ops |  Read-Only.      │
 └──────────────────────────┬─────────────────────────────┘
                            │ (REST /api/auth/login)
                            ▼
 ┌────────────────────────────────────────────────────────┐
 │             GUBERNATOR CORE AUTH ENGINE (Go)           │
 │  - Local Emergency Admin (admin / admin fallback)      │
 │  - Multi-Server Active Directory / OpenLDAP Dialers    │
 │  - LDAPS (Port 636) &amp;amp; StartTLS (Port 389) Handshake    │
 │  - Dynamic Group DN -&amp;gt; RBAC Role Resolution            │
 │  - Cryptographic HMAC-SHA256 JWT Token Signing         │
 └─────────────┬────────────────────────────┬─────────────┘
               │                            │
               ▼                            ▼
 ┌───────────────────────────┐ ┌──────────────────────────┐
 │  Primary Active Directory │ │ Secondary LDAP Server    │
 │   dc1.corporate.local     │ │   dc2.dr-site.local      │
 └───────────────────────────┘ └──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Role-Based Access Control (RBAC) Matrix
&lt;/h3&gt;

&lt;p&gt;We established three distinct operational tiers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operational Capability&lt;/th&gt;
&lt;th&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;operator&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;readonly&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overview, Metrics &amp;amp; SRE Telemetry&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deploy Stacks (&lt;code&gt;docker-compose.yml&lt;/code&gt;)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Redeploy &amp;amp; Duplicate Stacks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Delete Stacks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Task Lifecycle (Start / Stop / Restart)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container &amp;amp; Node Terminal Shell&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node Fleet Management (Drain / Activate / Leave)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Caddy TLS Certificates &amp;amp; Ingress Routes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Active Directory &amp;amp; LDAP Directory Settings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;td&gt;❌ Restricted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Grafana, Jaeger &amp;amp; Weave Scope Dashboards&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;td&gt;✅ Full&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  💻 The Go Backend Engine (&lt;code&gt;internal/auth/&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;For LDAP/Active Directory interactions, we used &lt;code&gt;github.com/go-ldap/ldap/v3&lt;/code&gt;, and for session management &lt;code&gt;github.com/golang-jwt/jwt/v5&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Two-Phase Bind &amp;amp; Credential Verification
&lt;/h3&gt;

&lt;p&gt;Authentication follows a secure two-phase pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect and perform a &lt;strong&gt;Service Account Bind&lt;/strong&gt; (&lt;code&gt;BindDN&lt;/code&gt; / &lt;code&gt;BindPassword&lt;/code&gt;) to query the directory.&lt;/li&gt;
&lt;li&gt;Search for the user object using a configurable LDAP filter (defaulting to &lt;code&gt;(&amp;amp;(objectClass=user)(sAMAccountName=%s))&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Open a secondary connection and perform a &lt;strong&gt;Direct User Bind&lt;/strong&gt; with the user-submitted password against the domain controller.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;AuthenticateLDAP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LDAPConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;AuthResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ConnectLDAP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// 1. Initial service account bind&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindDN&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindPassword&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindDN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindPassword&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"service account bind failed: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// 2. Search for the user&lt;/span&gt;
    &lt;span class="n"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EscapeFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;searchReq&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSearchRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScopeWholeSubtree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeverDerefAliases&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"dn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"displayName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"mail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"memberOf"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;searchReq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user not found in directory"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;userEntry&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c"&gt;// 3. Direct user bind to verify password&lt;/span&gt;
    &lt;span class="n"&gt;userConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ConnectLDAP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;userConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;userConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userEntry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invalid credentials"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// 4. Map groups to RBAC role&lt;/span&gt;
    &lt;span class="n"&gt;groups&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;userEntry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"memberOf"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ResolveRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;AuthResult&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;UserDN&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;userEntry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Username&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;DisplayName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userEntry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"displayName"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="n"&gt;userEntry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAttributeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mail"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;Groups&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Dynamic Group-to-Role Mapping
&lt;/h3&gt;

&lt;p&gt;Gubernator inspects the user's &lt;code&gt;memberOf&lt;/code&gt; group list and matches them against the configured group DNs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ResolveRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LDAPConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userGroups&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Role&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;matchesGroup&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetGroup&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;targetGroup&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrimSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targetGroup&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;userGroups&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrimSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;matchesGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AdminGroupDN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RoleAdmin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;matchesGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OperatorGroupDN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RoleOperator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;matchesGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadOnlyGroupDN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;RoleReadOnly&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;NormalizeRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultRole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Flutter Web UI Experience
&lt;/h2&gt;

&lt;p&gt;Gubernator's Web Dashboard is built with &lt;strong&gt;Flutter Web&lt;/strong&gt; and &lt;strong&gt;Material Design 3&lt;/strong&gt;, compiled and embedded directly into the Go binary (&lt;code&gt;go:embed&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Modern Login Screen with Domain Selector
&lt;/h3&gt;

&lt;p&gt;Operators can select their target authentication provider (&lt;code&gt;Corporate Active Directory&lt;/code&gt;, &lt;code&gt;DR Site LDAP&lt;/code&gt;, or &lt;code&gt;Local Administrator&lt;/code&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%2Fzko6ykwioskjaydd6fqg.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%2Fzko6ykwioskjaydd6fqg.png" alt="Login Screen" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Active Directory Management &amp;amp; Diagnostics
&lt;/h3&gt;

&lt;p&gt;In the new &lt;strong&gt;Seguridad &amp;amp; AD&lt;/strong&gt; tab, cluster administrators can configure directory servers, TLS certificates, and run a live &lt;strong&gt;"Test Connection"&lt;/strong&gt; diagnostic tool:&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%2Fs0y8lv3qbyxlf6lxadyb.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%2Fs0y8lv3qbyxlf6lxadyb.png" alt="Security &amp;amp; AD Management" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Real-Time Role Badges &amp;amp; Contextual Guards
&lt;/h3&gt;

&lt;p&gt;The dashboard header displays the active user and their assigned role (&lt;code&gt;ADMIN&lt;/code&gt;, &lt;code&gt;⚡ OPERATOR&lt;/code&gt;, &lt;code&gt;READ-ONLY&lt;/code&gt;). Mutating actions (e.g., Delete Stack, Drain Node, Shell) are automatically disabled for read-only audit accounts.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Google Antigravity Accelerated Development
&lt;/h2&gt;

&lt;p&gt;We utilized &lt;strong&gt;Google Antigravity (AGY)&lt;/strong&gt; as an autonomous AI pair programmer to build this feature end-to-end. AGY accelerated the development cycle through several key workflows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Architectural Planning&lt;/strong&gt;:&lt;br&gt;
Before writing code, Antigravity produced a comprehensive implementation plan (&lt;code&gt;implementation_plan.md&lt;/code&gt;) outlining the GORM schema changes (&lt;code&gt;LDAPConfig&lt;/code&gt;), RBAC authorization matrix, and API routes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Synchronized Full-Stack Implementation&lt;/strong&gt;:&lt;br&gt;
In a single coordinated session, Antigravity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built the Go &lt;code&gt;internal/auth/&lt;/code&gt; engine with LDAP dialers, JWT session handlers, and Gin middlewares.&lt;/li&gt;
&lt;li&gt;Applied SQLite database auto-migrations.&lt;/li&gt;
&lt;li&gt;Implemented the Flutter Web UI (&lt;code&gt;login_screen.dart&lt;/code&gt;, &lt;code&gt;security_page.dart&lt;/code&gt;, and state models).&lt;/li&gt;
&lt;li&gt;Updated existing views (&lt;code&gt;legions_page.dart&lt;/code&gt;, &lt;code&gt;tasks_page.dart&lt;/code&gt;, &lt;code&gt;centurions_page.dart&lt;/code&gt;) with RBAC permission guards.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Live Cluster Testing &amp;amp; Verification&lt;/strong&gt;:&lt;br&gt;
Using automated commands across a 3-node multipass cluster (&lt;code&gt;gbnt-manager&lt;/code&gt;, &lt;code&gt;gbnt-worker1&lt;/code&gt;, &lt;code&gt;gbnt-worker2&lt;/code&gt;), Antigravity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deployed and hot-restarted the ARM64 binaries.&lt;/li&gt;
&lt;li&gt;Tested REST endpoints via &lt;code&gt;curl&lt;/code&gt; (valid login, invalid login, LDAP connection tests, configuration lifecycle).&lt;/li&gt;
&lt;li&gt;Executed Go unit tests (&lt;code&gt;go test ./internal/auth/...&lt;/code&gt;) with 100% pass rates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automated Documentation &amp;amp; Release&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generated high-fidelity visual UI showcases.&lt;/li&gt;
&lt;li&gt;Authored complete documentation in &lt;a href="https://mario-ezquerro.github.io/gubernator/auth-rbac/" rel="noopener noreferrer"&gt;&lt;code&gt;docs/auth-rbac.md&lt;/code&gt;&lt;/a&gt; and validated MkDocs builds in strict mode.&lt;/li&gt;
&lt;li&gt;Bumped the version to &lt;code&gt;v2.20.0&lt;/code&gt;, created git release tags, and triggered GitHub Pages publishing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion &amp;amp; Open Source
&lt;/h2&gt;

&lt;p&gt;Adding Active Directory SSO and RBAC allows teams to deploy Gubernator in enterprise production environments that require enterprise security compliance without the operational overhead of Kubernetes.&lt;/p&gt;

&lt;p&gt;Check out Gubernator and try it out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;github.com/mario-ezquerro/gubernator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Official Documentation:&lt;/strong&gt; &lt;a href="https://mario-ezquerro.github.io/gubernator/" rel="noopener noreferrer"&gt;mario-ezquerro.github.io/gubernator&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Active Directory &amp;amp; RBAC Guide:&lt;/strong&gt; &lt;a href="https://mario-ezquerro.github.io/gubernator/auth-rbac/" rel="noopener noreferrer"&gt;docs/auth-rbac.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What do you think about this hybrid approach to container orchestration? Let us know your thoughts and suggestions in the comments! &lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>flutter</category>
      <category>ai</category>
    </item>
    <item>
      <title>Reviving Open Source Giants: How I Brought Weave Scope Back with Multi-Platform Docker Support in One Afternoon Using Antigravity</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Fri, 14 Aug 2026 16:36:10 +0000</pubDate>
      <link>https://dev.to/gde/reviving-open-source-giants-how-i-brought-weave-scope-back-with-multi-platform-docker-support-in-cmo</link>
      <guid>https://dev.to/gde/reviving-open-source-giants-how-i-brought-weave-scope-back-with-multi-platform-docker-support-in-cmo</guid>
      <description>&lt;p&gt;The open-source ecosystem is full of architectural masterpieces that—due to corporate pivots, lack of maintainers, or shifting market focus—eventually get frozen in time. One of the most prominent examples is &lt;strong&gt;&lt;a href="https://github.com/weaveworks/scope" rel="noopener noreferrer"&gt;Weave Scope&lt;/a&gt;&lt;/strong&gt;: a legendary tool for visual monitoring, real-time mapping, and debugging container clusters.&lt;/p&gt;

&lt;p&gt;When the original repository was archived and left unmaintained, its dependency tree froze and it remained strictly tied to &lt;code&gt;x86_64&lt;/code&gt; architectures. In today’s world, with the widespread adoption of ARM servers (AWS Graviton, Apple Silicon, Raspberry Pi clusters, etc.), running the original build has become nearly impossible.&lt;/p&gt;

&lt;p&gt;I set out to rescue it, modernize its build pipelines, and create multi-platform Docker images. &lt;strong&gt;The result?&lt;/strong&gt; The project is back to life at &lt;strong&gt;&lt;a href="https://github.com/mario-ezquerro/scope" rel="noopener noreferrer"&gt;github.com/mario-ezquerro/scope&lt;/a&gt;&lt;/strong&gt; with multi-arch Docker images live on &lt;strong&gt;Docker Hub&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The best part: &lt;strong&gt;the entire journey took a single afternoon and a few tokens thanks to Antigravity.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge: Brilliant Code Locked in the Past
&lt;/h2&gt;

&lt;p&gt;Weave Scope is far from a trivial codebase. Its architecture integrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low-level kernel probes and agents written in &lt;strong&gt;Go&lt;/strong&gt; and &lt;strong&gt;eBPF&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A reactive, interactive web UI.&lt;/li&gt;
&lt;li&gt;Complex legacy Makefiles and container toolchains originally engineered exclusively for &lt;code&gt;amd64/x86_64&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Manually upgrading this stack to modern &lt;code&gt;docker buildx&lt;/code&gt; workflows with native support for both &lt;strong&gt;ARM64&lt;/strong&gt; and &lt;strong&gt;AMD64&lt;/strong&gt; would traditionally mean days of painful software archaeology: resolving broken Go packages, outdated C libraries, incompatible packaging scripts, and compilation errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Catalyst: Antigravity as a Software Rescue Agent
&lt;/h2&gt;

&lt;p&gt;This is where &lt;strong&gt;Antigravity&lt;/strong&gt; makes an extraordinary difference.&lt;/p&gt;

&lt;p&gt;Instead of spending days fighting legacy &lt;code&gt;Makefiles&lt;/code&gt; and deprecated toolchains, I leveraged Antigravity to parse the repository structure, diagnose build blockers, and modernize the compilation and packaging pipeline for multi-architecture targets.&lt;/p&gt;

&lt;p&gt;What used to be a tedious migration became an agile, iterative session:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Audit &amp;amp; Fixes:&lt;/strong&gt; Identifying system calls and C bindings that prevented cross-compilation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dockerfile &amp;amp; Buildx Refactoring:&lt;/strong&gt; Modernizing the multi-stage build pipeline to compile native binaries for both &lt;code&gt;linux/amd64&lt;/code&gt; and &lt;code&gt;linux/arm64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Publishing:&lt;/strong&gt; Generating multi-arch manifest lists and pushing them directly to Docker Hub.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Modernized Multi-Arch Scope
&lt;/h2&gt;

&lt;p&gt;The revived project is ready for the community:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;New GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/mario-ezquerro/scope" rel="noopener noreferrer"&gt;https://github.com/mario-ezquerro/scope&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Original Repository (Legacy):&lt;/strong&gt; &lt;a href="https://github.com/weaveworks/scope" rel="noopener noreferrer"&gt;https://github.com/weaveworks/scope&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Docker Hub Multi-Arch Images:&lt;/strong&gt; Ready to deploy on both x86 and ARM infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Start
&lt;/h3&gt;

&lt;p&gt;Run the probe and visualization UI on any local machine or server (including Apple Silicon and Raspberry Pi clusters):&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="c"&gt;# Pull and run Scope with multi-arch support&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; weave-scope &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--net&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--privileged&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
  marioezquerro/scope:latest
Open your browser at http://localhost:4040 to see your real-time container topology &lt;span class="k"&gt;in &lt;/span&gt;action.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Takeaway: A Golden Era for Open Source Maintenance&lt;br&gt;
The true power of modern AI platforms like Antigravity isn't just generating boilerplate code from scratch—it is their astonishing capability for software restoration and modernization.&lt;/p&gt;

&lt;p&gt;GitHub contains thousands of brilliant, abandoned projects that simply need an afternoon of care, dependency updates, and container modernization. With a single afternoon and a handful of tokens, any developer now has the superpower to revive forgotten open-source gems and give them back to the global community.&lt;/p&gt;

&lt;p&gt;What abandoned open-source project is on your wishlist to revive next? Let me know in the comments!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>devops</category>
      <category>docker</category>
      <category>ai</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Tue, 11 Aug 2026 08:43:08 +0000</pubDate>
      <link>https://dev.to/marioezquerro/-52j2</link>
      <guid>https://dev.to/marioezquerro/-52j2</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac" class="crayons-story__hidden-navigation-link"&gt;Gubernator v2.13.0: Google SRE SLOs, Native CoreDNS Suite &amp;amp; Caddy Ingress for Docker Compose&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/gde"&gt;
            &lt;img alt="Google Developer Experts logo" 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%2Forganization%2Fprofile_image%2F11939%2Fe3080d5b-ecde-42a8-b089-bafecc31fa97.png" class="crayons-logo__image" width="800" height="800"&gt;
          &lt;/a&gt;

          &lt;a href="/marioezquerro" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F878530%2F7288c9b0-63e5-4a85-b7a1-be9f1234dfbd.jpeg" alt="marioezquerro profile" class="crayons-avatar__image" width="368" height="368"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/marioezquerro" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Mario Ezquerro
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Mario Ezquerro
                
              
              &lt;div id="story-author-preview-content-4366126" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/marioezquerro" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F878530%2F7288c9b0-63e5-4a85-b7a1-be9f1234dfbd.jpeg" class="crayons-avatar__image" alt="" width="368" height="368"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Mario Ezquerro&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/gde" class="crayons-story__secondary fw-medium"&gt;Google Developer Experts&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 11&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac" id="article-link-4366126"&gt;
          Gubernator v2.13.0: Google SRE SLOs, Native CoreDNS Suite &amp;amp; Caddy Ingress for Docker Compose
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/docker"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;docker&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sre"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sre&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/go"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;go&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Gubernator v2.13.0: Google SRE SLOs, Native CoreDNS Suite &amp; Caddy Ingress for Docker Compose</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Tue, 11 Aug 2026 06:14:53 +0000</pubDate>
      <link>https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac</link>
      <guid>https://dev.to/gde/gubernator-v2130-google-sre-slos-native-coredns-suite-caddy-ingress-for-docker-compose-1bac</guid>
      <description>&lt;p&gt;If you love the &lt;strong&gt;simplicity of Docker Swarm&lt;/strong&gt; (native Compose files, lightweight single binary) but miss the &lt;strong&gt;advanced capabilities of Kubernetes&lt;/strong&gt; (targeted label placement, SRE-grade observability, built-in DNS service discovery, and zero-trust ingress), meet &lt;strong&gt;Gubernator (gbnt)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We are excited to release &lt;strong&gt;Gubernator v2.13.0&lt;/strong&gt;, introducing three massive feature suites natively integrated into a single binary and a modern Material Design 3 Flutter Web Dashboard:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Google SRE Multi-Burn-Rate SLO Engine &amp;amp; Interactive Suite&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CoreDNS 4-Tab Management Suite &amp;amp; Interactive Dig Playground&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Caddy Ingress &amp;amp; Zero-Trust Reverse Proxy Suite&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Fun Fact: The entirety of Gubernator's codebase, multi-node deployment pipelines, and SRE features were designed, built, and pair-programmed using **Google Antigravity (AGY)&lt;/em&gt;&lt;em&gt;, Google DeepMind's agentic AI coding assistant!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's dive into what's new and how you can level up your self-hosted or production container clusters!&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Google SRE Multi-Burn-Rate SLO Engine &amp;amp; Web Suite
&lt;/h2&gt;

&lt;p&gt;Defining &lt;strong&gt;Service Level Objectives (SLOs)&lt;/strong&gt; and tracking &lt;strong&gt;Error Budgets&lt;/strong&gt; is the gold standard of Site Reliability Engineering. Until now, implementing SLOs meant running heavy Kubernetes CRDs (via tools like Sloth or Pyrra) or using costly SaaS platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gubernator v2.13.0&lt;/strong&gt; brings Google SRE Workbook (Chapter 5) compliant multi-burn-rate alerting straight to simple &lt;code&gt;docker-compose.yml&lt;/code&gt; services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;payment-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hashicorp/http-echo:latest&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;gbnt.slo.enable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
      &lt;span class="na"&gt;gbnt.slo.target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;99.9"&lt;/span&gt;
      &lt;span class="na"&gt;gbnt.slo.window&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;30d"&lt;/span&gt;
      &lt;span class="na"&gt;gbnt.slo.template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;caddy-http"&lt;/span&gt;
      &lt;span class="na"&gt;gbnt.slo.journey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Checkout&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Flow"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What makes Gubernator's SLO Suite unique?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Multi-Burn-Rate Alerting&lt;/strong&gt;: Automatically generates standard 4-window Prometheus recording and alert rules (&lt;strong&gt;Critical Page 1h/6h&lt;/strong&gt; &amp;amp; &lt;strong&gt;Warning Ticket 3d/14d&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic "No-Code" Management&lt;/strong&gt;: Click &lt;strong&gt;"+ Configure / Add SLO"&lt;/strong&gt; in the Web UI or call &lt;code&gt;POST /v1/slo/edit&lt;/code&gt; to create, edit, or disable SLOs on the fly without editing Compose files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composite User Journeys&lt;/strong&gt;: Group multi-service SLOs into end-to-end flows (&lt;em&gt;Checkout Flow: API Gateway + Payment + DB&lt;/em&gt;) and automatically identify the weakest-link &lt;strong&gt;bottleneck service&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Correlation Timeline&lt;/strong&gt;: Cross-reference real-time burn rate spikes against stack updates and container restarts to answer &lt;em&gt;"Did our last deploy burn the budget?"&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PromQL Dry-Run Backtesting&lt;/strong&gt;: Validate Compose YAML syntax and test PromQL queries against historical Prometheus metrics prior to deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Grafana Dashboards&lt;/strong&gt;: Automatically generates &lt;code&gt;/data/monitor/grafana/dashboards/slo_dashboard.json&lt;/code&gt; on rule sync.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  SLO Ecosystem Comparison Matrix
&lt;/h2&gt;

&lt;p&gt;Here is how Gubernator compares to other popular open-source and commercial SLO tools:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature / Capability&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Gubernator&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;Sloth&lt;/strong&gt; (&lt;code&gt;slok/sloth&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;Pyrra&lt;/strong&gt; (&lt;code&gt;pyrra-dev/pyrra&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;OpenSLO / Nobl9&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Native Runtime Environment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Docker Compose / Swarm / Bare Metal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Kubernetes / OpenSLO CLI&lt;/td&gt;
&lt;td&gt;Kubernetes CRDs / Filesystem&lt;/td&gt;
&lt;td&gt;Multi-Cloud / SaaS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Declarative Spec&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;docker-compose.yml&lt;/code&gt; labels (&lt;code&gt;gbnt.slo.*&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;K8s CRDs / Sloth YAML&lt;/td&gt;
&lt;td&gt;Custom Resources (&lt;code&gt;ServiceLevelObjective&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;OpenSLO YAML Spec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SRE Calculation Engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Google SRE Multi-Burn-Rate&lt;/strong&gt; (via Sloth Engine)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Google SRE Multi-Burn-Rate&lt;/strong&gt; (4 windows)&lt;/td&gt;
&lt;td&gt;Prometheus Multi-Burn-Rate&lt;/td&gt;
&lt;td&gt;Proprietary / Custom&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integrated Web Dashboard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Flutter Web 5-Tab Suite)&lt;/td&gt;
&lt;td&gt;No (CLI / Operator only)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (React/Go UI)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (SaaS Console)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dynamic Hot-Editing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Web UI Modal &amp;amp; REST API)&lt;/td&gt;
&lt;td&gt;No (Requires re-applying YAMLs)&lt;/td&gt;
&lt;td&gt;No (Read-only from K8s/Files)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (SaaS Console)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User Journeys (Composite SLOs)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Aggregation &amp;amp; Bottleneck Analysis)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Related Services)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment Correlation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Real-time Timeline of Stacks/Restarts)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Partial (CI/CD Webhooks)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Built-in SLI Templates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (&lt;code&gt;caddy-http&lt;/code&gt;, &lt;code&gt;http-status&lt;/code&gt;, &lt;code&gt;latency-p99&lt;/code&gt;, &lt;code&gt;grpc&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Partial (Sloth Libraries)&lt;/td&gt;
&lt;td&gt;No (Raw PromQL)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dry-Run PromQL Backtesting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Pre-deploy Validation)&lt;/td&gt;
&lt;td&gt;Partial (&lt;code&gt;validate&lt;/code&gt; command)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RED Metrics Breakdown&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (RPS, Error Rate, P99 Latency Cards)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Partial (RPS &amp;amp; Errors)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Automated Grafana Provisioning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; (Auto-generates &lt;code&gt;slo_dashboard.json&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Partial (Generic Rules)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  2. Native CoreDNS 4-Tab Suite &amp;amp; Interactive Dig Playground
&lt;/h2&gt;

&lt;p&gt;Internal container service discovery should "just work." In Gubernator, every deployed container automatically receives &lt;code&gt;--dns &amp;lt;CoreDNS_IP&amp;gt;&lt;/code&gt;, enabling seamless &lt;code&gt;*.gbnt&lt;/code&gt; internal resolution across multi-node clusters.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;v2.13.0&lt;/strong&gt;, we are expanding CoreDNS into a full &lt;strong&gt;4-Tab Management Suite&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-------------------------------------------------------------------------+
|                      GUBERNATOR COREDNS SUITE                           |
|                                                                         |
|  [Tab 1: Auto-Discovered] [Tab 2: Custom Records] [Tab 3: DNS Playground] [Tab 4: Config]
+-------------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tab 1: Auto-Discovered Stacks (&lt;code&gt;*.gbnt&lt;/code&gt;)&lt;/strong&gt;: Real-time table mapping running containers to &lt;code&gt;&amp;lt;service&amp;gt;.&amp;lt;stack&amp;gt;.gbnt&lt;/code&gt; with copyable &lt;code&gt;curl&lt;/code&gt; commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tab 2: Custom Static DNS Records&lt;/strong&gt;: Manage custom &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;AAAA&lt;/code&gt;, &lt;code&gt;CNAME&lt;/code&gt;, &lt;code&gt;TXT&lt;/code&gt;, and &lt;code&gt;PTR&lt;/code&gt; records stored in SQLite and merged into CoreDNS on the fly (&lt;code&gt;POST /v1/coredns/custom-records&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tab 3: Interactive Dig Playground&lt;/strong&gt;: A built-in terminal console to run DNS queries against local CoreDNS (&lt;code&gt;127.0.0.1:5354&lt;/code&gt;), benchmark query latency in milliseconds, and inspect raw &lt;code&gt;nslookup&lt;/code&gt; output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tab 4: Upstream Forwarders &amp;amp; Corefile Editor&lt;/strong&gt;: One-click upstream DNS presets (&lt;strong&gt;Cloudflare 1.1.1.1&lt;/strong&gt;, &lt;strong&gt;Google 8.8.8.8&lt;/strong&gt;, &lt;strong&gt;Quad9 9.9.9.9&lt;/strong&gt;) and a live Corefile editor with container reload.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Caddy Ingress Suite &amp;amp; Zero-Trust Reverse Proxy
&lt;/h2&gt;

&lt;p&gt;Gubernator packages &lt;strong&gt;Caddy&lt;/strong&gt; as its default edge proxy, handling HTTPS certificate provisioning, reverse proxying, and access logging across multi-node setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features in the Caddy Suite:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;7-Tab Management Visualizer&lt;/strong&gt;: Dashboard, Dynamic Routes Matrix, Corefile Preview, TLS Certs Inspector, Real-time Access Logs, Log Config, and Prometheus Metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root CA Trust Installation&lt;/strong&gt;: One-click download of Gubernator's internal Root CA certificate for local TLS trust across your developer devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Ingress Label Routing&lt;/strong&gt;: Simply add &lt;code&gt;ingress.host=my-app.example.com&lt;/code&gt; to your Compose service, and Gubernator reconfigures Caddy route matrices across all cluster nodes automatically.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting Started in Under 60 Seconds
&lt;/h2&gt;

&lt;p&gt;You can spin up a complete Gubernator cluster with full observability, CoreDNS, Caddy, and Prometheus/Grafana in seconds:&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="c"&gt;# 1. Download binary &amp;amp; start Gubernator Manager&lt;/span&gt;
curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/mario-ezquerro/gubernator/main/install.sh | bash
gbnt serve

&lt;span class="c"&gt;# 2. Deploy the SRE Monitoring Stack (Prometheus, Grafana, Loki, cAdvisor, Jaeger)&lt;/span&gt;
gbnt monitor init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3. Access Web Dashboards
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Web UI Dashboard -&amp;gt; &lt;a href="http://localhost:4001" rel="noopener noreferrer"&gt;http://localhost:4001&lt;/a&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Grafana           -&amp;gt; &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;
&lt;/h1&gt;

&lt;h1&gt;
  
  
  CoreDNS Playground -&amp;gt; &lt;a href="http://localhost:4001" rel="noopener noreferrer"&gt;http://localhost:4001&lt;/a&gt; (CoreDNS tab)
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

## Built Autonomous with Google Antigravity

A special shoutout to **Google Antigravity (AGY)**! The entire architecture of Gubernator -- from Go backend REST APIs, SQLite ORMs, Caddy route management, CoreDNS hosts sync, Sloth SLO rule compilation, down to the 5-tab Flutter Web UI -- was built autonomously in pair-programming sessions with Google Antigravity AI.

---

## Conclusion &amp;amp; Open Source

Gubernator aims to make container orchestration **fast, resilient, and enjoyable** again -- without the steep operational overhead of Kubernetes.

- **GitHub Repository**: [mario-ezquerro/gubernator](https://github.com/mario-ezquerro/gubernator)
- **Documentation &amp;amp; Guides**: [https://mario-ezquerro.github.io/gubernator/](https://mario-ezquerro.github.io/gubernator/)
- **Give us a Star**: If you find Gubernator useful, drop a star on GitHub!

*What are your thoughts on native SLO tracking for Docker Compose? Let us know in the comments below!*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>sre</category>
      <category>go</category>
    </item>
    <item>
      <title>Gubernator Weekly Update: CoreDNS Aqueducts, SRE Stack, Network Topology &amp; Cluster Auto-Updates!i</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Thu, 30 Jul 2026 06:55:16 +0000</pubDate>
      <link>https://dev.to/gde/gubernator-weekly-update-coredns-aqueducts-sre-stack-network-topology-cluster-auto-updates-e1c</link>
      <guid>https://dev.to/gde/gubernator-weekly-update-coredns-aqueducts-sre-stack-network-topology-cluster-auto-updates-e1c</guid>
      <description>&lt;p&gt;Gubernator Weekly Update: CoreDNS Aqueducts, SRE Stack, Network Topology &amp;amp; Cluster Auto-Updates!&lt;br&gt;
Gubernator Weekly Update Banner&lt;br&gt;
Review&lt;br&gt;
Gubernator Weekly Update Banner&lt;/p&gt;

&lt;p&gt;What an intense week for Gubernator (gbnt)! If you're new here, Gubernator is the "Goldilocks" container orchestrator that bridges the gap between Docker Swarm's simplicity (native Compose support, simple node joining) and Nomad's scheduling flexibility (hardware targeting, labels, task-based management).&lt;/p&gt;

&lt;p&gt;Over the past 7 days, Gubernator evolved from a single-node engine into a production-ready cluster ecosystem. Here is a breakdown of everything shipped this week!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Ingress &amp;amp; Service Discovery ("The Aqueducts")&lt;/strong&gt;&lt;br&gt;
One of our biggest milestones this week was shipping automated internal DNS resolution and edge ingress routing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CoreDNS Integration: Every node running Gubernator can now deploy CoreDNS. Containers across all hosts can resolve internal service IPs using dynamic domain names (.gbnt.test). As containers spin up or die, Gubernator's manager updates CoreDNS records in real-time.&lt;/li&gt;
&lt;li&gt;Caddy Ingress: Exposing web services is now effortless. Services deployed with routing labels are automatically proxied by Caddy, managing SSL and HTTP/HTTPS ingress dynamically.&lt;/li&gt;
&lt;/ul&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%2Fgkuiznbls1q51hp1wvib.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%2Fgkuiznbls1q51hp1wvib.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. SRE Observability Suite (gbnt monitor init)&lt;/strong&gt;&lt;br&gt;
Observability shouldn't require writing 500 lines of YAML. With a single command, gbnt monitor init, Gubernator deploys a complete, production-grade observability stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus &amp;amp; cAdvisor: Detailed container and host-level metrics collection (CPU, RAM, Network I/O).&lt;/li&gt;
&lt;li&gt;Loki &amp;amp; Promtail: Centralized log aggregation across all containers.&lt;/li&gt;
&lt;li&gt;Grafana: Pre-configured dashboards for instant visualization out of the box.&lt;/li&gt;
&lt;li&gt;Jaeger Tracing: Full OpenTelemetry distributed tracing support (OTLP gRPC :4317 &amp;amp; HTTP :4318).&lt;/li&gt;
&lt;/ul&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%2Fj0whuk5ti95d4c7ozm8r.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%2Fj0whuk5ti95d4c7ozm8r.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Interactive Network Topology (Weave Scope Integration)
Understanding how containers talk to each other across a distributed cluster can be tough. We integrated Weave Scope directly into the Flutter Web Dashboard!&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Live Process &amp;amp; Socket Spy: Mounts /proc and /sys to trace active socket connections between containers in real-time.&lt;/li&gt;
&lt;li&gt;Dynamic CoreDNS Spy: Container relationships are automatically linked and mapped based on DNS requests and active network traffic.&lt;/li&gt;
&lt;/ul&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%2Fn6ntmp2eutw0fgeq1ytl.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%2Fn6ntmp2eutw0fgeq1ytl.png" alt=" " width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Zero-Downtime Cluster Auto-Updates&lt;/strong&gt;&lt;br&gt;
Keeping a cluster updated shouldn't require manual SSH scripts. We introduced Gubernator Cluster Auto-Updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Releases Integration: The Manager polls the GitHub Releases API (with 15-minute smart caching).&lt;/li&gt;
&lt;li&gt;Header Notification: When a new tag is detected, the top-left sidebar header highlights the available update: [ MANAGER v2.7.2 ] → [ MANAGER v2.7.4 ] &lt;/li&gt;
&lt;li&gt;Cluster-Wide Rolling Update: Clicking the badge opens a confirmation dialog with full release notes. Confirming triggers an automated image pull (marioezquerro/gubernator:) and coordinated rolling restarts across the Manager and all registered Worker nodes!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. UI/UX Refinements (Flutter Web Dashboard)&lt;/strong&gt;&lt;br&gt;
We also polished the Web UI for maximum developer ergonomics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clickable Port Chips: Mapped container ports (e.g. 8080:80) are now rendered as interactive chips. One click opens http://: directly in your browser.&lt;/li&gt;
&lt;li&gt;Bulk Container Actions: Checkboxes on the Tasks table allow batch Start, Stop, Restart, or Delete operations.&lt;/li&gt;
&lt;li&gt;Dynamic Split Ratio: Legions (Stacks) and Centurions (Nodes) panels now feature a default 1/3 vs 2/3 layout with drag-to-resize support.&lt;/li&gt;
&lt;/ul&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%2Fm116mwlfoi9mfj852nn0.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%2Fm116mwlfoi9mfj852nn0.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try Gubernator Today!&lt;/strong&gt;&lt;br&gt;
Gubernator is open-source and built for developers who want the simplicity of Swarm combined with modern SRE observability.&lt;/p&gt;

&lt;p&gt;GitHub Repository: mario-ezquerro/gubernator&lt;br&gt;
Docker Hub: &lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;https://github.com/mario-ezquerro/gubernator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drop a ⭐ on GitHub if you like where Gubernator is heading! What features would you like to see next? Let me know in the comments!&lt;/p&gt;

</description>
      <category>buildwithai</category>
      <category>antigravity</category>
      <category>docker</category>
      <category>orquestator</category>
    </item>
    <item>
      <title>Introducing Gubernator: The Goldilocks Container Orchestrator (Docker Swarm + Nomad Hybrid)</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Sat, 25 Jul 2026 11:47:44 +0000</pubDate>
      <link>https://dev.to/gde/introducing-gubernator-the-goldilocks-container-orchestrator-docker-swarm-nomad-hybrid-1o7</link>
      <guid>https://dev.to/gde/introducing-gubernator-the-goldilocks-container-orchestrator-docker-swarm-nomad-hybrid-1o7</guid>
      <description>&lt;h1&gt;
  
  
  Introducing Gubernator: The Goldilocks Container Orchestrator
&lt;/h1&gt;

&lt;p&gt;Gubernator combines the simplicity of Docker Swarm with the flexibility of Nomad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Foundation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Language:&lt;/strong&gt; Go (Golang)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State:&lt;/strong&gt; SQLite (Centralized on Manager, with local cache on Workers for resilience)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API:&lt;/strong&gt; Secured REST (Port 4000)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web UI:&lt;/strong&gt; Flutter Web Dashboard with Material Design 3 (Port 4001)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; OpenTelemetry + Prometheus, Swagger, Healthchecks (Port 4002)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engine:&lt;/strong&gt; Docker Engine API interaction&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>opentelemetry</category>
      <category>antigravity</category>
    </item>
    <item>
      <title>Building a Hybrid Docker Orchestrator in Go: The Journey from Single VM to Multi-Node Cluster</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Tue, 14 Jul 2026 17:54:10 +0000</pubDate>
      <link>https://dev.to/gde/building-a-hybrid-docker-orchestrator-in-go-the-journey-from-single-vm-to-multi-node-cluster-3i7m</link>
      <guid>https://dev.to/gde/building-a-hybrid-docker-orchestrator-in-go-the-journey-from-single-vm-to-multi-node-cluster-3i7m</guid>
      <description>&lt;p&gt;What if you could combine the native simplicity of &lt;strong&gt;Docker Compose&lt;/strong&gt; with the decentralized targeting and reliability of &lt;strong&gt;HashiCorp Nomad&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;Meet &lt;strong&gt;Gubernator&lt;/strong&gt; (or &lt;code&gt;gbnt&lt;/code&gt;), a "Goldilocks" container orchestrator written in Go. In this post, I want to share how I took Gubernator from a single-node API to a fully decentralized, multi-node VM cluster with autonomous DNS resolution and local ingress routing—all co-authored alongside &lt;strong&gt;Antigravity&lt;/strong&gt;, Google DeepMind's agentic AI pair programmer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Vision: Why Gubernator?
&lt;/h2&gt;

&lt;p&gt;Kubernetes is the undisputed king of container orchestration, but for small-to-medium projects, homelabs, or edge deployments, it represents massive operational overhead. Docker Swarm is simple but lacks fine-grained task scheduling constraints.&lt;/p&gt;

&lt;p&gt;Gubernator is designed to fill that sweet spot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single Binary Portability:&lt;/strong&gt; The same &lt;code&gt;gbnt&lt;/code&gt; binary acts as the Central Manager (holding the centralized SQLite state) and the Worker Agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Central SQLite with Local Cache:&lt;/strong&gt; Workers run a local cache so that containers keep running and resolving internal routes even if connectivity to the Manager is lost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized Ingress &amp;amp; DNS:&lt;/strong&gt; The cluster leverages a distributed network of &lt;strong&gt;CoreDNS&lt;/strong&gt; and &lt;strong&gt;Caddy&lt;/strong&gt; instances.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Architecture: Multi-Node Setup
&lt;/h2&gt;

&lt;p&gt;To test the orchestrator realistically, we provisioned three Multipass Ubuntu VMs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gbnt-manager&lt;/code&gt; (&lt;code&gt;192.168.252.8&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gbnt-worker1&lt;/code&gt; (&lt;code&gt;192.168.252.9&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gbnt-worker2&lt;/code&gt; (&lt;code&gt;192.168.252.10&lt;/code&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD
    Host[Mac/Laptop Host OS] --&amp;gt;|Resolves *.gbnt via local resolver| CoreDNS_Manager
    subgraph Manager VM [gbnt-manager: 192.168.252.8]
        CoreDNS_Manager[gbnt-coredns]
        Mgr[gbnt-manager API &amp;amp; DB]
        Caddy_Mgr[gbnt-caddy]
    end
    subgraph Worker 1 VM [gbnt-worker1: 192.168.252.9]
        Agent1[gbnt Agent]
        Caddy1[gbnt-caddy]
        CoreDNS1[gbnt-coredns]
        Cont1[App Containers]
    end
    subgraph Worker 2 VM [gbnt-worker2: 192.168.252.10]
        Agent2[gbnt Agent]
        Caddy2[gbnt-caddy]
        CoreDNS2[gbnt-coredns]
        Cont2[App Containers]
    end

    Mgr --&amp;gt;|Orchestrates| Agent1 &amp;amp; Agent2
    CoreDNS_Manager --&amp;gt;|Synchronizes Records| CoreDNS1 &amp;amp; CoreDNS2
    Caddy1 --&amp;gt;|Routes to local| Cont1
    Caddy2 --&amp;gt;|Routes to local| Cont2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Decentralized Ingress &amp;amp; Localized Caddy Routing
&lt;/h2&gt;

&lt;p&gt;One of the biggest challenges in multi-host networking is how to route web traffic to containers without overloading the Manager. &lt;/p&gt;

&lt;p&gt;Instead of routing all external traffic through a single ingress proxy on the Manager, we built a fully decentralized routing scheme:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized DNS (CoreDNS):&lt;/strong&gt; When a stack is deployed, Gubernator registers the domain (e.g., &lt;code&gt;hello-app.gbnt&lt;/code&gt;) pointing directly to the IP of the Worker VM hosting the container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Localized Ingress (Caddy):&lt;/strong&gt; Each VM runs its own independent Caddy Ingress container. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized Caddyfiles:&lt;/strong&gt; Caddy on the Manager &lt;em&gt;only&lt;/em&gt; manages reverse-proxy rules for containers running locally on the Manager. Worker agents periodically poll the Manager for their assigned tasks and generate a local Caddyfile targeting &lt;em&gt;only&lt;/em&gt; their local containers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means if &lt;code&gt;hello-app.gbnt&lt;/code&gt; is deployed on &lt;code&gt;gbnt-worker2&lt;/code&gt; (&lt;code&gt;192.168.252.10&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client's browser queries DNS, which resolves to &lt;code&gt;192.168.252.10&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The browser connects directly to Caddy on &lt;code&gt;gbnt-worker2&lt;/code&gt; on port 80.&lt;/li&gt;
&lt;li&gt;Caddy proxies the request to the local container IP (e.g. &lt;code&gt;172.17.0.2:80&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero transit traffic touches the Manager VM.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Co-authoring with Antigravity (Google DeepMind)
&lt;/h2&gt;

&lt;p&gt;What makes this project unique is that &lt;strong&gt;100% of the Go code, GORM integrations, Flutter dashboard widgets, and cluster setups were co-authored with Antigravity&lt;/strong&gt;, Google DeepMind's agentic AI coding assistant.&lt;/p&gt;

&lt;p&gt;Unlike simple autocomplete or chat windows, Antigravity acts as a pair programmer with agentic capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debugging Complex Network Behaviors:&lt;/strong&gt; We encountered an issue where containers connected to multiple Docker networks (like &lt;code&gt;bridge&lt;/code&gt; and &lt;code&gt;gbnt-monitor-net&lt;/code&gt;) had their IPs concatenated (e.g., &lt;code&gt;172.17.0.2172.19.0.7&lt;/code&gt;). Antigravity traced the container IP extraction logic, proposed a fix, and validated the parser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Bootstrapping:&lt;/strong&gt; Antigravity ran Multipass commands to spin up the VMs, transfer Go binaries, configure authorization keys, and join the workers into the cluster via JWT tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Generating the Flutter Dashboard:&lt;/strong&gt; Antigravity designed and iterated on the Flutter Web UI, implementing features like a real-time cluster topology map, live task statuses, and a settings dialog containing system metadata and version tags.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Cluster Observability
&lt;/h2&gt;

&lt;p&gt;Observability is built-in. By running &lt;code&gt;gbnt monitor init&lt;/code&gt;, the Manager spins up a complete telemetry stack connected via a dedicated network &lt;code&gt;gbnt-monitor-net&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cAdvisor:&lt;/strong&gt; Exposes hardware and container metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus:&lt;/strong&gt; Scrapes metrics from all nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grafana:&lt;/strong&gt; Visualizes metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loki &amp;amp; Promtail:&lt;/strong&gt; Aggregates logs across all nodes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Gubernator proves that you don't need a heavy orchestrator like Kubernetes to manage multi-host Docker deployments. By combining Go, SQLite, CoreDNS, and Caddy, we created a lightning-fast, decentralized orchestrator.&lt;/p&gt;

&lt;p&gt;Pair-programming with an agentic coder like Antigravity allowed me to focus on high-level architecture while the AI handled refactoring, cross-compilation, VM deployment, and frontend updates. &lt;/p&gt;

&lt;p&gt;If you are interested in building lightweight orchestration systems, check out the &lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;Gubernator repository&lt;/a&gt; and start building!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you built or used lightweight orchestrators? Let me know in the comments below!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#devops&lt;/code&gt; &lt;code&gt;#docker&lt;/code&gt; &lt;code&gt;#golang&lt;/code&gt; &lt;code&gt;#ai&lt;/code&gt; &lt;code&gt;#pairprogramming&lt;/code&gt; &lt;code&gt;#antigravity&lt;/code&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>ai</category>
      <category>antigravity</category>
    </item>
    <item>
      <title>Stop Copy-Pasting `dns:` Blocks: Introducing Transparent DNS Injection in Gubernator</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Mon, 13 Jul 2026 06:21:32 +0000</pubDate>
      <link>https://dev.to/gde/stop-copy-pasting-dns-blocks-introducing-transparent-dns-injection-in-gubernator-ad4</link>
      <guid>https://dev.to/gde/stop-copy-pasting-dns-blocks-introducing-transparent-dns-injection-in-gubernator-ad4</guid>
      <description>&lt;p&gt;If you’ve ever built a containerized home lab, a multi-host cluster, or an internal development environment using Docker Compose with custom local DNS (like CoreDNS), you know this exact pain point:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
yaml
services:
  web:
    image: nginx:alpine
    dns:
      - 192.168.1.100  # Hardcoded CoreDNS IP
  api:
    image: my-api:latest
    dns:
      - 192.168.1.100  # Copied again...
  db:
    image: postgres:alpine
    dns:
      - 192.168.1.100  # And again!

It is repetitive, it litters your configuration files, and if you forget to paste that block or the DNS IP changes, your container is born blind—unable to resolve internal services or talk to the internet.

With Gubernator, we decided to eliminate this boilerplate entirely.

The Solution: Transparent DNS Injection 🪄
Starting with version v2.4.13, Gubernator implements Transparent DNS Injection.

Now, you can deploy your standard, clean, unedited docker-compose.yml file. No custom network configurations, no hardcoded IPs.

yaml
# Standard, clean Compose file. No "dns:" blocks required!
services:
  web:
    image: nginx:alpine
  api:
    image: my-api:latest
  db:
    image: postgres:alpine

Behind the scenes, Gubernator's deployment executor intercepts container creation and dynamically injects the cluster's CoreDNS host IP directly into the container's runtime configuration.

How It Works Under the Hood 
Host IP Auto-Detection: Gubernator automatically detects the Manager Node IP at startup (either via GBNT_HOST_IP or by testing outbound gateway paths).

Dynamic Templating: CoreDNS templates are updated on the fly to handle custom local routing domains (like *.gbnt and *.gbnt.test).
Runtime Interception: During scheduling and task execution, Gubernator intercepts the container host configuration and populates the DNS servers parameter with the dynamically resolved CoreDNS address.

The Result: 0% Boilerplate, 100% Magic 
Your containers are deployed instantly and gain immediate out-of-the-box support to:

Resolve internal service domains seamlessly.
Communicate with the outer internet through your configured upstream forwarders.
Adapt automatically even if the physical IP of your manager host changes.

Get Started 
Gubernator is designed to combine the simplicity of Docker Compose with the scheduling power of Nomad. You can inspect the code, read the documentation, and launch your first cluster today on GitHub:

Gubernator GitHub Repository https://github.com/mario-ezquerro/gubernator

If you find this feature useful, don't forget to drop a ⭐️ on GitHub! What are your thoughts on container DNS management? Let me know in the comments!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>docker</category>
      <category>go</category>
      <category>coredns</category>
      <category>antigravity</category>
    </item>
    <item>
      <title>Gubernator visual schema.</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Tue, 09 Jun 2026 09:42:18 +0000</pubDate>
      <link>https://dev.to/gde/gubernator-visual-schema-1dfc</link>
      <guid>https://dev.to/gde/gubernator-visual-schema-1dfc</guid>
      <description>&lt;h1&gt;
  
  
  Excited to share the latest feature built for Gubernator (gbnt): Visual Stack Topology &amp;amp; Network Schema!
&lt;/h1&gt;

&lt;p&gt;Gubernator is designed as a "Goldilocks" orchestrator—combining the raw simplicity of Docker Compose with Nomad-inspired scheduling and hardware/AI targeting. But deploying complex multi-container stacks means visualization is key to maintaining control.&lt;/p&gt;

&lt;p&gt;To bridge this gap, I’ve just integrated a native Web Network Schema &amp;amp; Container Topology Viewer directly into the Gubernator dashboard:&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.amazonaws.com%2Fuploads%2Farticles%2Fsvhwdywnophnli5xinr8.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.amazonaws.com%2Fuploads%2Farticles%2Fsvhwdywnophnli5xinr8.png" alt=" " width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What makes it unique?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auto-discovered Ingress &amp;amp; Routing:&lt;/strong&gt; The scheduler parses docker-compose.yml to automatically place a virtual Caddy Ingress node in  web-facing services (e.g. n8n, WordPress, Jupyter)  and internal sinks/databases (e.g. MySQL, PostgreSQL).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live Network Context&lt;/strong&gt;: Every container card details live telemetry—including internal container IPs, host port mappings, and active domains (e.g.ingress.host).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visual Dependency Mapping:&lt;/strong&gt; Custom Bézier-curve connection lines are dynamically drawn in yellow/amber to highlight container network relationships and dependencies (like depends_on).&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.amazonaws.com%2Fuploads%2Farticles%2Fxnmadeu9c3nfen9ehuao.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.amazonaws.com%2Fuploads%2Farticles%2Fxnmadeu9c3nfen9ehuao.png" alt=" " width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One-Click Multi-Format Export:&lt;/strong&gt; Perfect for team architecture syncs or DevOps documentation! Diagrams can be instantly exported and downloaded as PNG, JPEG, PDF, or native SVG (automatically adapting to light/dark system themes).&lt;/p&gt;

&lt;p&gt;Gubernator continues its journey to simplify local and edge container orchestration. Let me know what you think of this visualization layer! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator/" rel="noopener noreferrer"&gt;https://github.com/mario-ezquerro/gubernator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;_ #Docker #Golang #Flutter #DevOps #Nomad #Orchestration #WebDevelopment #SystemArchitecture #Containers&lt;/p&gt;

</description>
      <category>docker</category>
      <category>gubernator</category>
      <category>antigravity</category>
      <category>agenticarchitect</category>
    </item>
    <item>
      <title>Gubernator E101 examples examples examplesss....</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Mon, 08 Jun 2026 12:30:01 +0000</pubDate>
      <link>https://dev.to/gde/gubernator-e101-examples-examples-exampesss-5akn</link>
      <guid>https://dev.to/gde/gubernator-e101-examples-examples-exampesss-5akn</guid>
      <description>&lt;p&gt;Gubernator Examples: Hands-On Tutorials&lt;/p&gt;

&lt;p&gt;Gubernator features four progressive developer examples designed to walk you from basic container orchestration to advanced AI workloads:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Example 101 — Getting Started (WordPress &amp;amp; MySQL)&lt;br&gt;
Goal: Understand the basics of single-node orchestration.&lt;br&gt;
Stack: A classic multi-container application consisting of a WordPress front-end and a MySQL database backend.&lt;br&gt;
Key Concepts: Persistent Docker named volumes, basic container scheduling, internal CoreDNS resolution (db.wp.gbnt), and initial Caddy Ingress routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example 102 — Load Balancing (Round-Robin Routing)&lt;br&gt;
Goal: Learn how Gubernator handles horizontal scaling and high availability.&lt;br&gt;
Stack: A scaled deployment featuring multiple BusyBox HTTP replicas serving their individual container hostnames.&lt;br&gt;
Key Concepts: Scaling up replicas, automatic target grouping under a single DNS record, and Caddy Ingress configuring native round-robin load balancing across the running replicas under hello.gbnt.local.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example n8n — AI Automation Stack (RAG &amp;amp; Local LLMs)&lt;br&gt;
Goal: Orchestrate a modern, automated AI agent workflow.&lt;br&gt;
Stack: An automation workspace integrating n8n (workflows), PostgreSQL (backend database), Ollama (local LLM runtime running llama3.2), and Qdrant (vector database for RAG).&lt;br&gt;
Key Concepts: Inter-container communication using CoreDNS, complex service dependencies, transient automated setup tasks (auto-pulling LLM models on startup), and multi-domain Caddy Ingress routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example Jupyter — AI Development Stack (JupyterLab with PyTorch)&lt;br&gt;
Goal: Spin up a fully-equipped machine learning and data science environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Stack: A specialized developer workspace running JupyterLab powered by the comprehensive quay.io/jupyter/pytorch-notebook image.&lt;br&gt;
Key Concepts: Managing large Docker image downloads, mounting persistent data scientist workspace volumes, and setting up Ingress reverse proxying for custom/non-standard container ports (port 8888).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;https://github.com/mario-ezquerro/gubernator/tree/main/examples&lt;/a&gt;&lt;a href="https://github.com/mario-ezquerro/gubernator/tree/main/examples" rel="noopener noreferrer"&gt;https://github.com/mario-ezquerro/gubernator/tree/main/examples&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  docker #gubernator #examples #orchestration
&lt;/h1&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>gubernator</category>
      <category>containers</category>
    </item>
    <item>
      <title>Examples Gubernator</title>
      <dc:creator>Mario Ezquerro</dc:creator>
      <pubDate>Sat, 06 Jun 2026 09:18:33 +0000</pubDate>
      <link>https://dev.to/gde/examples-gubernator-3pk9</link>
      <guid>https://dev.to/gde/examples-gubernator-3pk9</guid>
      <description>&lt;p&gt;Gubernator Orchestrator Update!&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fkbl5vy2wvofq7041ooyy.jpg" 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.amazonaws.com%2Fuploads%2Farticles%2Fkbl5vy2wvofq7041ooyy.jpg" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just shipped some major improvements examples to Gubernator (the lightweight Go container orchestrator):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Premium Data Grid UI: Upgraded the Tasks Dashboard to PlutoGrid for interactive column resizing, filtering, and custom actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dynamic Ingress Routing: Fixed port mapping to auto-detect and route traffic to custom container ports (like n8n, Qdrant, Ollama) instead of hardcoding port 80.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI Automation Stack (n8n + Ollama + Qdrant): Added a complete RAG workflow example with automated LLM pulling and CoreDNS service discovery.&lt;br&gt;
Simplicity of Docker Swarm meets the flexibility of Nomad!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check it out: &lt;a href="https://github.com/mario-ezquerro/gubernator" rel="noopener noreferrer"&gt;https://github.com/mario-ezquerro/gubernator&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>gubernator</category>
      <category>docker</category>
      <category>containers</category>
    </item>
  </channel>
</rss>
