<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Prathmesh Shinde]]></title><description><![CDATA[Prathmesh Shinde]]></description><link>https://prathmeshshinde.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Prathmesh Shinde</title><link>https://prathmeshshinde.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 14 Sep 2026 22:53:51 GMT</lastBuildDate><atom:link href="https://prathmeshshinde.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Reduced My Docker Image Size from 1GB to 150MB]]></title><description><![CDATA[When I first Dockerized my Node.js app, I was just happy that it worked.
I didn’t care about the image size… until I tried pushing it.
It was huge (~1GB) and took forever to build and upload. That’s w]]></description><link>https://prathmeshshinde.hashnode.dev/how-i-reduced-my-docker-image-size-from-1gb-to-150mb</link><guid isPermaLink="true">https://prathmeshshinde.hashnode.dev/how-i-reduced-my-docker-image-size-from-1gb-to-150mb</guid><category><![CDATA[Docker]]></category><category><![CDATA[docker images]]></category><category><![CDATA[multi stage docker file]]></category><category><![CDATA[distroless]]></category><category><![CDATA[Dockerignore]]></category><dc:creator><![CDATA[Prathmesh Shinde]]></dc:creator><pubDate>Tue, 14 Apr 2026 11:32:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695cb7562a72789a9142390a/1d59f80d-aa78-4561-bd0f-7118566037ec.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When I first Dockerized my Node.js app, I was just happy that it worked.</p>
<p>I didn’t care about the image size… until I tried pushing it.</p>
<p>It was <strong>huge (~1GB)</strong> and took forever to build and upload. That’s when it hit me—this is not how production systems should behave.</p>
<p>So I spent some time figuring out how to reduce Docker image size, and honestly, a few small changes made a <em>big</em> difference.</p>
<p>In this blog, I’ll share what actually worked for me.</p>
<hr />
<h2>Why Image Size Even Matters</h2>
<p>At first, I thought:</p>
<blockquote>
<p>“Storage is cheap, why does size matter?”</p>
</blockquote>
<p>But in real scenarios, it affects:</p>
<ul>
<li><p>Build time (slower CI/CD)</p>
</li>
<li><p>Push/pull speed (painful on deployments)</p>
</li>
<li><p>Cloud costs (ECR, Docker Hub, etc.)</p>
</li>
<li><p>Overall developer experience</p>
</li>
</ul>
<p>Smaller images just make everything smoother.</p>
<hr />
<h2>1. Switching to Alpine (Biggest Easy Win)</h2>
<p>Initially, I was using:</p>
<pre><code class="language-dockerfile">FROM node:latest
</code></pre>
<p>Then I switched to:</p>
<pre><code class="language-dockerfile">FROM node:18-alpine
</code></pre>
<p>And that alone reduced a <em>lot</em> of unnecessary weight.</p>
<p>Alpine is a minimal Linux distro, so you’re not carrying around stuff you don’t need.</p>
<hr />
<h2>2. Multi-Stage Builds (Game Changer)</h2>
<p>This was probably the most impactful change.</p>
<p>Earlier, everything—build files, dev dependencies—was going into the final image.</p>
<p>Then I tried multi-stage builds:</p>
<pre><code class="language-dockerfile"># Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm install --only=production
CMD ["node", "dist/index.js"]
</code></pre>
<p>Now the final image only contains what’s actually needed to run the app.</p>
<p>No extra baggage.</p>
<hr />
<h2>3. .dockerignore (I Completely Missed This Initially)</h2>
<p>I was unknowingly sending everything to Docker during build.</p>
<p>Including:</p>
<ul>
<li><p>node_modules</p>
</li>
<li><p>.git</p>
</li>
<li><p>.env</p>
</li>
<li><p>logs</p>
</li>
</ul>
<p>Adding a <code>.dockerignore</code> fixed that:</p>
<pre><code class="language-plaintext">node_modules
.git
.env
logs
tests
</code></pre>
<p>This made builds faster and cleaner.</p>
<hr />
<h2>4. Cleaning Up Layers</h2>
<p>I also learned that every <code>RUN</code> creates a new layer.</p>
<p>Earlier, I had:</p>
<pre><code class="language-dockerfile">RUN apt-get update
RUN apt-get install -y curl
</code></pre>
<p>Now I combine them:</p>
<pre><code class="language-dockerfile">RUN apt-get update &amp;&amp; apt-get install -y curl &amp;&amp; rm -rf /var/lib/apt/lists/*
</code></pre>
<p>Less layers = smaller image.</p>
<hr />
<h2>5. Installing Only What’s Needed</h2>
<p>I didn’t realize how much space dev dependencies take.</p>
<p>Switching to:</p>
<pre><code class="language-dockerfile">RUN npm ci --omit=dev
</code></pre>
<p>helped keep things lean.</p>
<hr />
<h2>6. Actually Checking the Image</h2>
<p>One mistake I made was not checking image layers at all.</p>
<p>These commands helped:</p>
<pre><code class="language-bash">docker images
docker history &lt;image_name&gt;
</code></pre>
<p>You can literally see what’s bloating your image.</p>
<hr />
<h2>What Changed After Optimization</h2>
<p>After applying these changes:</p>
<ul>
<li><p>Image size: <strong>~1GB → ~150MB</strong></p>
</li>
<li><p>Build time: noticeably faster</p>
</li>
<li><p>Deployment: much smoother</p>
</li>
</ul>
<p>Honestly, I didn’t expect this much improvement.</p>
<hr />
<h2>Final Thoughts</h2>
<p>If you’re working with Docker (especially in MERN or backend projects), don’t ignore image size like I did initially.</p>
<p>You don’t need advanced optimizations—just:</p>
<ul>
<li><p>Use a lightweight base image</p>
</li>
<li><p>Try multi-stage builds</p>
</li>
<li><p>Avoid unnecessary files</p>
</li>
<li><p>Keep dependencies minimal</p>
</li>
</ul>
<p>These small things add up quickly.</p>
<hr />
<p>If you’re already Dockerizing your projects, try these out—you’ll definitely notice the difference.</p>
<p>And if you’ve found other tricks, I’d love to know too 🙂</p>
]]></content:encoded></item></channel></rss>