<?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: Shani G</title>
    <description>The latest articles on Forem by Shani G (@shani_gotlib_f5e51aed8363).</description>
    <link>https://forem.com/shani_gotlib_f5e51aed8363</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%2F3573643%2F45fb9239-7e22-434e-bd81-ab765086d97d.png</url>
      <title>Forem: Shani G</title>
      <link>https://forem.com/shani_gotlib_f5e51aed8363</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shani_gotlib_f5e51aed8363"/>
    <language>en</language>
    <item>
      <title>🚀 Secure Your Microservices: API Gateway + Docker Private Networks</title>
      <dc:creator>Shani G</dc:creator>
      <pubDate>Wed, 10 Dec 2025 14:51:51 +0000</pubDate>
      <link>https://forem.com/shani_gotlib_f5e51aed8363/secure-your-microservices-api-gateway-docker-private-networks-dnb</link>
      <guid>https://forem.com/shani_gotlib_f5e51aed8363/secure-your-microservices-api-gateway-docker-private-networks-dnb</guid>
      <description>&lt;p&gt;🚀 A practical guide for developers building their first distributed system&lt;/p&gt;

&lt;p&gt;When building microservices for the first time, most developers focus on features,&lt;br&gt;
scaling, or breaking the monolith — but almost nobody talks about security architecture.&lt;/p&gt;

&lt;p&gt;And that’s exactly where things can go wrong.&lt;/p&gt;

&lt;p&gt;While developing my own distributed system, I discovered that several internal APIs —&lt;br&gt;
and even the PostgreSQL database — were accidentally exposed to the public. 😬&lt;/p&gt;

&lt;p&gt;So I implemented a simple, production-ready pattern:&lt;br&gt;
API Gateway + Docker Private Networks.&lt;/p&gt;

&lt;p&gt;This post will show you exactly how (and why) I did it, and how you can use the same approach in your own projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💥 The Real Problem: Microservices Accidentally Exposing Everything&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2F8tos6g0810rcyfwaas4c.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%2F8tos6g0810rcyfwaas4c.png" alt=" " width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s how many beginner systems accidentally look:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each service is exposed on its own port&lt;/li&gt;
&lt;li&gt;The client talks to everything directly&lt;/li&gt;
&lt;li&gt;The database (!) may also be exposed&lt;/li&gt;
&lt;li&gt;No central control or routing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates security issues, debugging complexity, and a messy architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧩 Part 1 — The API Gateway: Your Single Entry Point&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Why the API Gateway is critical
&lt;/h4&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%2Fds5ijm7wbhslc53tivv1.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%2Fds5ijm7wbhslc53tivv1.png" alt=" " width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  How it works
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The client sends a single request to the Gateway.&lt;/li&gt;
&lt;li&gt;The Gateway decides which service should handle it.&lt;/li&gt;
&lt;li&gt;It forwards the request &lt;em&gt;inside&lt;/em&gt; the private Docker network.&lt;/li&gt;
&lt;li&gt;Internal URLs are never exposed to the outside world.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Gateway is not just a fancy router — it becomes the front door to your entire system.&lt;/p&gt;

&lt;p&gt;Why it's so important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One place for authentication&lt;/li&gt;
&lt;li&gt;One place for routing&lt;/li&gt;
&lt;li&gt;Internal services remain hidden&lt;/li&gt;
&lt;li&gt;Cleaner code and better control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:3000/orders&lt;br&gt;
http://localhost:4000/reports&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Your client only calls:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://gateway/api/orders&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
The Gateway forwards the request internally.&lt;br&gt;
Your services never need to be exposed again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧱 Part 2 — Docker Private Networks (The Physical Security Layer)&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  How Docker networks protect your system
&lt;/h4&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%2Fii2bfof3fzbtc1lim830.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%2Fii2bfof3fzbtc1lim830.png" alt=" " width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters&lt;/strong&gt;&lt;br&gt;
Without a private network, Docker exposes containers to the host machine.&lt;br&gt;
With it:&lt;/p&gt;

&lt;p&gt;✔ Only the Gateway is reachable&lt;br&gt;
✔ All internal traffic stays inside the network&lt;br&gt;
✔ Databases cannot be accessed directly&lt;/p&gt;

&lt;p&gt;Putting services into a private Docker network prevents the outside world&lt;br&gt;
from reaching anything except what you explicitly expose.&lt;/p&gt;

&lt;p&gt;Most developers don't realize that Docker exposes containers publicly unless configured otherwise.&lt;/p&gt;

&lt;p&gt;The solution?&lt;/p&gt;

&lt;p&gt;Put all internal services in a private network.&lt;/p&gt;

&lt;p&gt;This prevents the outside world from reaching anything except what you explicitly expose.&lt;/p&gt;

&lt;p&gt;What this gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal-only communication&lt;/li&gt;
&lt;li&gt;Zero accidental port exposure&lt;/li&gt;
&lt;li&gt;Database fully isolated&lt;/li&gt;
&lt;li&gt;Clean, professional architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if someone bypasses the Gateway (rare),&lt;br&gt;
they still can't access Service A, B, or the Database — because they're not on a public network.&lt;/p&gt;

&lt;p&gt;🛡️ Combining the Two: A Simple, Solid Security Pattern&lt;/p&gt;
&lt;h4&gt;
  
  
  How the full architecture works together
&lt;/h4&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%2Fdug3ishycp6nq3361qxq.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%2Fdug3ishycp6nq3361qxq.png" alt=" " width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you combine:&lt;/p&gt;

&lt;p&gt;✔ Logical Security (API Gateway)&lt;br&gt;
✔ Physical Security (Private Network)&lt;/p&gt;

&lt;p&gt;You get a microservices architecture that's both simple and robust — without Kubernetes, service mesh, or any heavy DevOps tooling.&lt;/p&gt;

&lt;p&gt;The architecture becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client
   ↓
 API Gateway
   ↓
Private Docker Network
 ├── Service A
 ├── Service B
 └── Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the Gateway is public.&lt;br&gt;
Everything else is safely tucked away behind it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 Minimal Docker Compose Example (Copy/Paste Ready&lt;/strong&gt;&lt;br&gt;
Here’s the minimal setup I used — clean, simple, and production-friendly:&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-gateway&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./gateway&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;public_net&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;private_net&lt;/span&gt;

  &lt;span class="na"&gt;service-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./service-a&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;private_net&lt;/span&gt;

  &lt;span class="na"&gt;service-b&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./service-b&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4000"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;private_net&lt;/span&gt;

  &lt;span class="na"&gt;internal-db&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;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;private_net&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;public_net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;private_net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Key takeaways
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Only the Gateway has ports → public&lt;/li&gt;
&lt;li&gt;Internal services use expose → private&lt;/li&gt;
&lt;li&gt;Everything sits inside private_net&lt;/li&gt;
&lt;li&gt;Clean, secure architecture with minimal configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🎯 What I Learned&lt;/p&gt;

&lt;p&gt;Implementing this pattern gave me:&lt;/p&gt;

&lt;p&gt;✔ Zero accidental exposure of internal services&lt;br&gt;
✔ A secure, predictable entry point&lt;br&gt;
✔ Faster debugging&lt;br&gt;
✔ Easier onboarding for teammates&lt;br&gt;
✔ A scalable foundation for future services&lt;br&gt;
✔ Professional-level architecture with beginner-friendly tools&lt;/p&gt;

&lt;p&gt;✨ Final Thoughts&lt;/p&gt;

&lt;p&gt;This architecture may look simple — and that’s exactly why it works.&lt;/p&gt;

&lt;p&gt;You don’t need Kubernetes, a service mesh, or complex DevOps setups&lt;br&gt;
to build a secure and scalable distributed system.&lt;/p&gt;

&lt;p&gt;Start with:&lt;br&gt;
✔ One API Gateway&lt;br&gt;&lt;br&gt;
✔ One private Docker network  &lt;/p&gt;

&lt;p&gt;This foundation will naturally support your system as it grows.&lt;br&gt;
Simple. Clean. Secure. Effective.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>microservices</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
