{"componentChunkName":"component---src-templates-blog-post-jsx","path":"/blog/docker-is-great-just-not-for-local-dev/","result":{"data":{"site":{"siteMetadata":{"name":"Huzaifa Rasheed","title":"Huzaifa Rasheed","description":"Software Engineer","about":"\n      Hey, I'm Huzaifa.\n      <br/><br/>\n      Engineer by trade, builder by instinct - I believe in owning my stack, shipping fast, and occasionally running on chai (tea) and stubbornness. I work best in that sweet spot between deep focus and fast feedback - solo or in sync with a good team.\n      <br/><br/>\n      This site's my little corner of the internet - part portfolio, part lab - where I document what I build, break, or learn.\n      <br/><br/>\n      Outside work, I'm into long walks, pixel-perfect headshots in FPS games (eventually... maybe), plants I probably overwater, and the occasional \"classified\" hobby to stay curious.\n      <br/><br/>\n      Reach out anytime - my digital door's always open. 👋\n    ","twitter":"https://twitter.com/huzRasheed","github":"https://github.com/huzaifa-99","linkedin":"https://www.linkedin.com/in/huzaifa-rasheed/","devto":"https://dev.to/huzaifa99","stackoverflow":"https://stackoverflow.com/users/12579290/huzaifa","leetcode":"https://leetcode.com/rhuzaifa","discord":"https://discordapp.com/users/rhuzaifa","email":"dev@rhuzaifa.com","projects":[{"name":"FFMpeg Web","description":"An experimental browser-based terminal that runs FFmpeg using WebAssembly, enabling media processing directly in the browser.","link":"https://ffmpeg-web.rhuzaifa.com/","github":"https://github.com/huzaifa-99/ffmpeg-web"},{"name":"Feed base 2","description":"A mini browser game where players manipulate 4-bit binary blocks to match target BCD values - part puzzle, part binary logic trainer.","link":"https://feedbase2.rhuzaifa.com/","github":"https://github.com/huzaifa-99/feed-base-2"},{"name":"Fabric browser extension","description":"A Chrome extension that injects engineered Fabric prompts directly into the ChatGPT interface for enhanced workflow automation.","link":"https://github.com/huzaifa-99/fabric-browser-extension","github":"https://github.com/huzaifa-99/fabric-browser-extension"},{"name":"Pure Cinema","description":"An experimental, tongue-in-cheek text-to-video generator that stitches together footage, synthesized voiceovers, and background music with a Node.js + ffmpeg pipeline. Not quite Hollywood, but it renders.","link":"https://cinema.rhuzaifa.com","github":null},{"name":"Aria2c Packload","description":"A Bash script for bulk downloading magnet links or torrents using aria2c - optimized for series or list-based transfers.","link":"https://github.com/huzaifa-99/aria2c-packload","github":"https://github.com/huzaifa-99/aria2c-packload"},{"name":"RSS Watchdog","description":"A lightweight Bash script that watches RSS/Atom feeds and compiles a Markdown-based reading checklist for Unix systems.","link":"https://github.com/huzaifa-99/rss-watchdog","github":"https://github.com/huzaifa-99/rss-watchdog"},{"name":"QuoteGen","description":"A quote graphic generator that produces stylized quote images with random selection and a built-in editor for customization.","link":"https://quotegen.rhuzaifa.com/","github":null},{"name":"WebRTC Video Chat","description":"A basic WebRTC-powered app enabling peer-to-peer video and audio calls between two users.","link":"https://webrtc-video-chat.rhuzaifa.com/","github":null}],"experience":null,"skills":[{"name":"Languages & Frameworks","description":"JavaScript, TypeScript, Python, Bash - Frameworks include Node.js, React, Next.js, Vue, React Native, FastAPI."},{"name":"Databases & Storage","description":"PostgreSQL, MySQL, MongoDB - Experience with schema design, indexing, query optimization, and migrations."},{"name":"Cloud & Infrastructure","description":"AWS (EC2, RDS, S3, Lambda), Vercel, Netlify, Heroku - Comfortable with serverless, autoscaling, and cost optimization."},{"name":"DevOps & Tooling","description":"Docker, Git, CI/CD pipelines (GitHub Actions, GitLab CI) - Experience with observability, containerization, and release workflows."},{"name":"Testing & QA Automation","description":"Jest, Playwright, Puppeteer, Selenium - Focus on E2E testing, mocking APIs, and maintaining test coverage."}]}},"markdownRemark":{"id":"b2b8351e-e603-596b-91ba-fafbb57c6122","excerpt":"Let’s get this out of the way first:  I don’t hate Docker.  It’s brilliant for deployment.  Containerization is magical.  Dockerfiles are poetry when done right…","html":"<p>Let’s get this out of the way first: </p>\n<p>I don’t <em>hate</em> Docker. </p>\n<p>It’s brilliant for deployment. </p>\n<p>Containerization is magical. </p>\n<p>Dockerfiles are poetry when done right.</p>\n<p>But when it comes to <strong>local development environments</strong>, I dodge Docker like it’s trying to sell me an enterprise Java certification. 😑</p>\n<p>This is not a purist rant. </p>\n<p>It’s a tired developer speaking from experience.</p>\n<p>Someone who’s shipped enough code. </p>\n<p>Fixed enough “why-is-this-not-working-on-my-machine” bugs.</p>\n<p>Wasted enough hours debugging in container hell to make this a conscious, intentional choice.</p>\n<hr>\n<h2>👨‍💻 Devs Aren’t Meant to Be Sysadmins (At Least Not Every Day)</h2>\n<p>Yes, Docker is supposed to <em>“abstract away the environment.”</em></p>\n<p>But in practice, it often ends up replacing simple local tooling with complex orchestration.</p>\n<p>Instead of running <code class=\"language-text\">npm run dev</code>, you’re now dealing with:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">docker-compose up --build</code></pre></div>\n<p>And when something breaks? </p>\n<p>You’re Googling obscure Dockerfile flags or trying to mount your volumes right for the hundredth time. </p>\n<p>You become the part-time maintainer of a container orchestration mess you didn’t ask for.</p>\n<p>I’m all for reproducibility - but reproducibility after the dev loop, not inside it.</p>\n<h2>🐛 Debugging in Docker? No Thanks</h2>\n<p>Want to read logs in real time?</p>\n<p>Want to mount your code without weird permissions?</p>\n<p>Want to use your IDE’s debugger?</p>\n<p>Cool, now layer in Docker and watch all of that get clunky real fast.</p>\n<p>I remember once trying to debug a Python app running in Docker, and I spent more time configuring <code class=\"language-text\">remotePath</code> in VSCode than actually solving the bug. </p>\n<p>The containerized environment becomes a black box.</p>\n<p>One more place where state leaks, errors hide, and you end up wondering if the container is even picking up your code changes.</p>\n<p>I don’t want to SSH into a container to fix a typo.</p>\n<h2>⏳ Docker for Dev Adds <em>Latency</em> - Mentally and Literally</h2>\n<p>Ever tried making rapid changes to code, only to wait for Docker volumes to sync or for the container to rebuild every time?</p>\n<p>That dev loop latency adds up - and so does the mental latency.</p>\n<p>When you’re deep in flow, the last thing you want is to context-switch into Docker’s abstraction model. </p>\n<p>Every layer between you and your code makes iteration feel heavier. </p>\n<p>Like trying to code in a space suit.</p>\n<h2>⚡️ Local Dev Should Be Fast, Loose, and Bare Metal</h2>\n<p>Let’s not confuse dev environments with production.</p>\n<p>Your dev machine is your playground. </p>\n<p>It should be flexible, hackable, and optimized for speed and feedback - not enterprise-grade reproducibility.</p>\n<p>I want to brew install or apt install, maybe run a quick script, and be done. </p>\n<p>If I want to test something experimental, I’ll use a VM, a separate user profile, or even a lightweight container. </p>\n<p>But not Docker as the default dev runtime.</p>\n<h2>⚙️ “But It Works on My Dockerfile!”</h2>\n<p>Sure, it works in Docker. </p>\n<p>But if no one else on your team understands that setup…</p>\n<p>or the image breaks silently because of a version mismatch in Alpine vs Ubuntu…</p>\n<p>or the container dies because of an unexposed port, then what did we really solve?</p>\n<p>Docker doesn’t remove config hell. It just relocates it.</p>\n<h2>🧳 What I Do Instead</h2>\n<ul>\n<li>Scripts > Containers: I write good setup scripts (setup.sh, init<em>dev</em>env.py) to install what I need.</li>\n<li>Dotfiles + Docs: My dotfiles + README keep things reproducible enough.</li>\n<li>Vagrant / VM if Needed: For heavy isolation, I’ll use a dev VM. At least it’s predictable.</li>\n<li>Docker for Prod, Not for Local: I always Dockerize for deployment - staging/prod builds, yes. - But never for live development.</li>\n</ul>\n<h2>🐳 When I Do Use Docker in Dev</h2>\n<p>Okay okay, it’s not all fire and brimstone. I’ll use Docker in dev when:</p>\n<ul>\n<li>I need a DB or service (Postgres, Redis, etc.) - those are clean to run via containers.</li>\n<li>The target prod env requires container parity (e.g., special kernel stuff).</li>\n<li>I’m working with a team that already has an excellent DX setup with Docker (rare).</li>\n</ul>\n<p>But even then, I keep my app code outside the container. </p>\n<p>I let Docker handle services, not the dev runtime.</p>\n<p>Here’s a quick cheat sheet to sum up where Docker shines - and where it doesn’t:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; margin: 0 0 30px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/6f2480f52e9b0ee9356371b1ba3c9e42/d56e1/docker-usage-table.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 66.89189189189189%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAABnElEQVQ4y4WT646CQAxGff9ndE1EEUHBAII4t+6caokbf+zESpkOp19b2MjHej6fcr/fZZomiTHqXkpJvPfqPx4PGYZBuraV2+32FWdteNA2+r6Xw+Eg5/NZ4RxelkWTxOwDqXKsrCo9xxniCIARQngB53mWNme9Xq96bZpGjXtiAJ1zEjI0As9nUhbAHqqJA8Q2UMkAAGVlWapVWQVAVADlnMu2jIPMTS1LhplCgPgKROHxeFQYdrlcNMHpdFIjESooP9CzfhQ51erHEFeVcDBVaOXVda1XoF3XrdBVgfPSza1U90qST+K8W3sIeC3ZlBmofU+Re2KU7IOXFJLUcyPb4Uckz/HpXiVr3IaS3tNDJWpMIT69ZPI8hBoFTrVs+60qBEi5NuW1h2ygjJIxINg4jhqzhkcfpc0lF0Mh0UVN8gVEpr3UNoT9fq+l2ouLwhDzufw7o3DY/ikZ6J8e8ooAs77h08eiKPSeZAZscg93w059IAZcFfKHKqCUCYiyDU4rPofSLZ0cp3Lt4deUKem/hUIr35b5n58ue79Y1Oyx/yAGJAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Quick cheat sheet showing where Docker is useful vs not\"\n        title=\"Quick cheat sheet showing where Docker is useful vs not\"\n        src=\"/static/6f2480f52e9b0ee9356371b1ba3c9e42/fcda8/docker-usage-table.png\"\n        srcset=\"/static/6f2480f52e9b0ee9356371b1ba3c9e42/12f09/docker-usage-table.png 148w,\n/static/6f2480f52e9b0ee9356371b1ba3c9e42/e4a3f/docker-usage-table.png 295w,\n/static/6f2480f52e9b0ee9356371b1ba3c9e42/fcda8/docker-usage-table.png 590w,\n/static/6f2480f52e9b0ee9356371b1ba3c9e42/efc66/docker-usage-table.png 885w,\n/static/6f2480f52e9b0ee9356371b1ba3c9e42/d56e1/docker-usage-table.png 1130w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<div style=\"display: none;\">\n  \n| Scenario                    | Use Docker |\n|----------------------------|:----------:|\n| Local App Development      | ❌         |\n| Rapid Iteration / Debugging| ❌         |\n| Sys services in Dev (i.e DB)     | ✅         |\n| Team Setup / Onboarding    | ✅         |\n| CI/CD Pipelines            | ✅         |\n| Staging / Production Builds| ✅         |\n</div>\n<h2>_ The Bottom Line</h2>\n<p>Docker is great.</p>\n<p>Docker is powerful.</p>\n<p>Not every local Docker setup is a “mess” - some teams build excellent DX around Docker.</p>\n<p>But let’s be honest:</p>\n<p>Great DX with Docker is rare.</p>\n<p>Most of the time, it’s overused in local development.</p>\n<p>If it’s slowing you down, breaking your flow, or making onboarding a pain… </p>\n<p>It’s okay to drop it. </p>\n<p>Simpler is often better. </p>\n<p>A clean dev machine is still a valid stack.</p>\n<p>Let Docker shine in CI/CD, deployments, and staging. </p>\n<p>Not in your everyday creative loop. </p>\n<p>You’re not wrong for wanting your tools to disappear so you can just build.</p>","frontmatter":{"title":"Docker Is Great, Just Not for Local Dev","date":"September 17, 2024","description":"It's great - just not in my dev loop. Here's why I avoid it for local development and what I do instead."}}},"pageContext":{"slug":"/blog/docker-is-great-just-not-for-local-dev/","previous":{"fields":{"slug":"/blog/one-wildcard-ssl-certificate-to-secure-all-subdomains-via-certbot/"},"frontmatter":{"title":"One Wildcard SSL Certificate to Secure All Subdomains via Certbot"}},"next":{"fields":{"slug":"/blog/tracking-email-for-educational-purposes/"},"frontmatter":{"title":"Tracking emails \"for educational purposes\""}}}},"staticQueryHashes":["2276319502"]}