<?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>Forem: Sevada Ghazaryan</title>
    <description>The latest articles on Forem by Sevada Ghazaryan (@adavesik).</description>
    <link>https://forem.com/adavesik</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3728279%2F0839083a-7e1e-4559-aa8b-a2d82e341f00.jpeg</url>
      <title>Forem: Sevada Ghazaryan</title>
      <link>https://forem.com/adavesik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/adavesik"/>
    <language>en</language>
    <item>
      <title>Stop Fighting YAML: I Built a Visual Docker Compose Architect to Fix It</title>
      <dc:creator>Sevada Ghazaryan</dc:creator>
      <pubDate>Mon, 26 Jan 2026 10:05:00 +0000</pubDate>
      <link>https://forem.com/adavesik/stop-fighting-yaml-i-built-a-visual-docker-compose-architect-to-fix-it-m00</link>
      <guid>https://forem.com/adavesik/stop-fighting-yaml-i-built-a-visual-docker-compose-architect-to-fix-it-m00</guid>
      <description>&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%2Fiq0v8nsqw26aaay16g4d.webp" 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%2Fiq0v8nsqw26aaay16g4d.webp" alt="Stop Fighting YAML" width="800" height="522"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;The Problem: YAML vs. Reality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If Docker Compose keeps tripping you up, it is rarely because you do not understand containers. It is because Compose makes you juggle two things at once: YAML rules and Docker's schema.&lt;/p&gt;

&lt;p&gt;If you hve ever tried to visualize a Docker Compose file, you know the drill: most tools work great on hello-world examples but choke the moment you throw a real-world file at them.&lt;/p&gt;

&lt;p&gt;Why? because "Real World" Docker Compose is messy. It has environment variables (&lt;code&gt;${PORT:-8080}&lt;/code&gt;), it uses service inheritance (extends), and it relies on complex overrides.&lt;/p&gt;

&lt;p&gt;Why &lt;strong&gt;Compoviz&lt;/strong&gt; is different, and why it can finally handle your "cursed" Docker files.&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%2Fwoeuo5amkd23ead0ncxn.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%2Fwoeuo5amkd23ead0ncxn.png" alt="Real World" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Solved: The "Missing Port" Bug (Inheritance)&lt;/strong&gt;&lt;br&gt;
Service inheritance (&lt;code&gt;extends&lt;/code&gt;) is where most parsers fail.&lt;/p&gt;

&lt;p&gt;If you have a base service with port &lt;code&gt;80&lt;/code&gt; and an extended service adds port &lt;code&gt;443&lt;/code&gt;, many tools mistakenly replace the list—meaning port &lt;code&gt;80&lt;/code&gt; disappears.&lt;/p&gt;

&lt;p&gt;Compoviz knows when to merge lists (like ports and volumes) and when to override them (like image tags). You see the final, actual configuration, not just the last layer.&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%2Fyddsxph595b1itby27d4.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%2Fyddsxph595b1itby27d4.png" alt="extended service" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Support for YAML Anchors &amp;amp; Aliases&lt;/strong&gt;&lt;br&gt;
Do not repeat yourself (DRY) is great for code, but hard for parsers. If you use YAML anchors (&lt;code&gt;&amp;amp;&lt;/code&gt;) to share logging configs or healthchecks across services, simple visualizers often ignore them or show raw references like &lt;code&gt;*default-logging&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Compoviz fully resolves YAML aliases before building the graph. This means if you alias a volume or a network configuration, the visualizer sees the resolved properties and draws the connections correctly.&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%2Foahyo88eio229oc65q0a.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%2Foahyo88eio229oc65q0a.png" alt="Anchors &amp;amp; Aliases" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Profiles: Dev vs. Prod Views&lt;/strong&gt;&lt;br&gt;
We often shove everything into one huge &lt;code&gt;compose.yml&lt;/code&gt; and use profiles (&lt;code&gt;profiles: ["dev", "monitoring"]&lt;/code&gt;) to control what runs.&lt;/p&gt;

&lt;p&gt;Compoviz now includes a &lt;strong&gt;Profile Selector&lt;/strong&gt;. You can toggle profiles on and off to see exactly how your architecture changes between environments. It filters the graph in real-time, removing the noise of disabled services.&lt;/p&gt;

&lt;p&gt;Without any profile selected"&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%2F9gktca71h8fgzyjwggde.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%2F9gktca71h8fgzyjwggde.png" alt="Without a profile" width="728" height="791"&gt;&lt;/a&gt;&lt;br&gt;
Dev profile selected:&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%2Fukmo78yp7cu8oyh6gutj.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%2Fukmo78yp7cu8oyh6gutj.png" alt="dev profile" width="800" height="633"&gt;&lt;/a&gt;&lt;br&gt;
Dev &amp;amp; Prod profiles selected:&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%2F6ceohja4b66z92p1ot5h.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%2F6ceohja4b66z92p1ot5h.png" alt="Devandprod" width="800" height="654"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Visual Conflict Detection (Compare Mode)&lt;/strong&gt;&lt;br&gt;
We rarely run just one Docker stack. You have your main app, a legacy backend, and maybe a side project, all fighting for &lt;code&gt;localhost:5432&lt;/code&gt; or &lt;code&gt;port 80&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Project Loading:&lt;/strong&gt; You can load up to three different compose files simultaneously into the same workspace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collision Highlighting:&lt;/strong&gt; The engine cross-references every exposed port, container name, and volume mount. If Project A claims port &lt;code&gt;5432&lt;/code&gt; and Project B tries to grab it too, Compoviz instantly highlights the collision in red.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Benefit:&lt;/strong&gt; You spot the conflict visually before you run &lt;code&gt;docker compose up&lt;/code&gt; and get that cryptic "address already in use" error.&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.amazonaws.com%2Fuploads%2Farticles%2F5u6f4cxjeq7reoourjub.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%2F5u6f4cxjeq7reoourjub.png" alt="Visual Conflict Detection" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Still 100% Client-Side (Privacy First)&lt;/strong&gt;&lt;br&gt;
Despite the new power, the architecture remains unchanged in one critical way: &lt;strong&gt;Privacy&lt;/strong&gt;. There is no backend. Your &lt;code&gt;.env&lt;/code&gt; files (which likely contain API keys and passwords) never leave your browser memory. The parsing happens locally on your machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try It Out&lt;/strong&gt;&lt;br&gt;
If you have a complex Docker Compose file that breaks other tools, I want you to try breaking this one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Tool:&lt;/strong&gt; &lt;a href="https://compoviz.pro" rel="noopener noreferrer"&gt;compoviz.pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="//github.com/adavesik/compoviz"&gt;github.com/adavesik/compoviz&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>opensource</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
