<?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: Md Umair</title>
    <description>The latest articles on DEV Community by Md Umair (@md_umair_88fd7c1b0fa06f96).</description>
    <link>https://dev.to/md_umair_88fd7c1b0fa06f96</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%2F3856729%2F6f3a3f86-ec45-4c05-916a-7ff42f84b8f2.png</url>
      <title>DEV Community: Md Umair</title>
      <link>https://dev.to/md_umair_88fd7c1b0fa06f96</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/md_umair_88fd7c1b0fa06f96"/>
    <language>en</language>
    <item>
      <title>Stop Using .env Files for Docker Secrets — Try This Instead</title>
      <dc:creator>Md Umair</dc:creator>
      <pubDate>Thu, 16 Apr 2026 16:49:45 +0000</pubDate>
      <link>https://dev.to/md_umair_88fd7c1b0fa06f96/stop-using-env-files-for-docker-secrets-try-this-instead-2de1</link>
      <guid>https://dev.to/md_umair_88fd7c1b0fa06f96/stop-using-env-files-for-docker-secrets-try-this-instead-2de1</guid>
      <description>&lt;p&gt;Managing secrets in Docker usually starts simple—a &lt;code&gt;.env&lt;/code&gt; file here, a hardcoded variable there. But once you move past a single local machine, things get messy quickly. &lt;/p&gt;

&lt;p&gt;Kubernetes users are spoiled for choice with tools like External Secrets Operator (ESO), but for those of us running standalone Docker or Compose on a handful of VMs, the options have always felt a bit "hacked together." You’re often stuck with the manual overhead of syncing files, or worse, hard-coding "temporary" credentials that inevitably end up in a Git commit.It works — until it doesn’t.&lt;/p&gt;

&lt;p&gt;I started &lt;strong&gt;Docker Secret Operator (DSO)&lt;/strong&gt; as a side project to solve a specific headache: I wanted my containers to talk to cloud secret managers without managing local files or SSHing into servers every time a password changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is DSO?
&lt;/h3&gt;

&lt;p&gt;DSO is a lightweight way to manage secrets in plain Docker environments. It consists of two parts: a background &lt;strong&gt;Agent&lt;/strong&gt; that talks to your cloud provider (AWS, Azure, Vault, etc.) and a &lt;strong&gt;Docker CLI Plugin&lt;/strong&gt; that lets you run containers with those secrets injected at runtime.&lt;/p&gt;

&lt;p&gt;The goal was simple: your application code should just see an environment variable like &lt;code&gt;DB_PASSWORD&lt;/code&gt;, but that password should never exist as a plain text string on your server’s disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison: How do we handle secrets?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;.env Files&lt;/th&gt;
&lt;th&gt;Docker Secrets (Swarm)&lt;/th&gt;
&lt;th&gt;DSO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Plaintext on disk&lt;/td&gt;
&lt;td&gt;Encrypted (Swarm only)&lt;/td&gt;
&lt;td&gt;In-memory (RAM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloud Sync&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Native (AWS/Vault/etc)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rotation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual restart&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What Problem It Solves
&lt;/h3&gt;

&lt;p&gt;If you aren't on Kubernetes, your options are usually a bit messy. You're either hoping nobody with read access to the server steals your &lt;code&gt;.env&lt;/code&gt; files, or you're setting host environment variables manually, which makes automation a nightmare. &lt;/p&gt;

&lt;p&gt;DSO fills this gap. It fetches secrets directly from your source of truth and injects them into your containers. If you update a secret in your cloud console, DSO can detect that change and automatically rotate the credentials in your running containers—no manual intervention needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;At a high level, it works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;DSO Agent:&lt;/strong&gt; Runs as a systemd service. It authenticates with your provider, fetches secrets, and keeps them in an in-memory RAM cache. They never touch the physical disk.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;CLI Plugin:&lt;/strong&gt; You use &lt;code&gt;docker dso up&lt;/code&gt; instead of &lt;code&gt;docker compose up&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Communication:&lt;/strong&gt; The CLI talks to the agent over a secure Unix domain socket (&lt;code&gt;/var/run/dso.sock&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Injection:&lt;/strong&gt; The plugin overlays the secrets onto your container's environment just as it starts.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Zero-Persistence:&lt;/strong&gt; Secrets live in RAM, never on disk.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Multi-Cloud:&lt;/strong&gt; Native support for AWS Secrets Manager, Azure Key Vault, HashiCorp Vault, and Huawei CSMS.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Auto-Rotation:&lt;/strong&gt; Refreshes the cache and can trigger rolling restarts when a secret changes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Native UX:&lt;/strong&gt; It’s a Docker plugin, so it works seamlessly with the standard &lt;code&gt;docker&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tiny Footprint:&lt;/strong&gt; Written in Go with minimal resource usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installation &amp;amp; Quick Setup
&lt;/h3&gt;

&lt;p&gt;You can get up and running on Ubuntu or Debian with a single command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/docker-secret-operator/dso/main/install.sh | &lt;span class="nb"&gt;sudo &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create your configuration file at &lt;code&gt;/etc/dso/dso.yaml&lt;/code&gt;. Here’s what a typical AWS setup looks like:&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;providers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;aws-prod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
    &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;    &lt;span class="c1"&gt;# Change to your AWS region&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;iam_role&lt;/span&gt;

&lt;span class="na"&gt;agent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;polling_interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5m&lt;/span&gt;    

&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;inject&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;env&lt;/span&gt;
  &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rolling&lt;/span&gt; &lt;span class="c1"&gt;# Default strategy for all secrets&lt;/span&gt;

&lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:secretsmanager:REGION:ACCOUNT:secret:YOUR_SECRET_NAME&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-prod&lt;/span&gt;
    &lt;span class="na"&gt;rotation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;restart&lt;/span&gt; &lt;span class="c1"&gt;# Override global default for this specific secret&lt;/span&gt;
    &lt;span class="na"&gt;mappings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;DB_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_USER&lt;/span&gt;
      &lt;span class="na"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MYSQL_PASSWORD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start dso-agent.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example Usage
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;docker-compose.yaml&lt;/code&gt;, you just reference the keys without values:&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;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;my-app:latest&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_USER&lt;/span&gt;      &lt;span class="c1"&gt;# DSO will fill this&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_PASSWORD&lt;/span&gt;  &lt;span class="c1"&gt;# DSO will fill this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, instead of the standard compose command, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker dso up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DSO will fetch the credentials from AWS, map them to your environment variables, and start your stack. No &lt;code&gt;.env&lt;/code&gt; files to manage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why I Built This
&lt;/h3&gt;

&lt;p&gt;I built this because I was tired of the "secret drift" problem. I'd update a database password in the cloud console, and then have to remember which five EC2 instances needed an &lt;code&gt;.env&lt;/code&gt; update and a manual &lt;code&gt;docker compose restart&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Missing even one instance usually led to a production fire at 2 AM. I wanted a "set it and forget it" solution—something that felt native to the Docker CLI but had the brains to handle fetching and rotating secrets automatically. DSO is the result of that frustration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing
&lt;/h3&gt;

&lt;p&gt;DSO is open-source, and I’m looking for feedback. If you're running Docker without Kubernetes, this might save you a lot of headaches.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/docker-secret-operator/dso" rel="noopener noreferrer"&gt;docker-secret-operator/dso&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Documentation:&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://dso.skycloudops.in/docs/" rel="noopener noreferrer"&gt;https://dso.skycloudops.in/docs/&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd love to hear what other providers or features you'd like to see. PRs and feedback are always welcome!&lt;/p&gt;

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