{"id":4482,"date":"2026-01-26T21:08:31","date_gmt":"2026-01-26T15:38:31","guid":{"rendered":"https:\/\/www.itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/"},"modified":"2026-02-17T15:57:18","modified_gmt":"2026-02-17T10:27:18","slug":"10-docker-best-practices-to-optimize-your-containers","status":"publish","type":"post","link":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/","title":{"rendered":"10 Docker Best Practices to Optimize Your Containers"},"content":{"rendered":"<p>text<br \/>\n[2024-05-22 03:14:02] INFO: Deployment triggered by &#8216;Rockstar_Dev_69&#8217;<br \/>\n[2024-05-22 03:15:44] ERROR: Failed to pull image &#8220;registry.internal\/awesome-app:latest&#8221;<br \/>\n[2024-05-22 03:15:44] ERROR: RPC error: code = Unknown desc = failed to register layer: Error processing tar file(exit status 1): write \/usr\/src\/app\/node_modules\/huge-useless-library\/dist\/bundle.js: no space left on device<br \/>\n[2024-05-22 03:16:10] CRITICAL: Node ip-10-0-42-12.ec2.internal is DiskPressure<br \/>\n[2024-05-22 03:16:15] CRITICAL: Kubelet stopped posting node status.<br \/>\n[2024-05-22 03:17:00] FATAL: Production cluster is unresponsive. PagerDuty initiated.<\/p>\n<pre class=\"codehilite\"><code>I am currently staring at a cold cup of coffee and a terminal screen that is bleeding red. It is 4:00 AM. I have been awake for 72 hours because you decided that the &quot;docker best&quot; way to deploy a simple Node.js microservice was to wrap it in a 3GB container image and push it directly to our production registry using the `latest` tag. \n\nOur nodes didn't just fail; they choked. They tried to pull your bloated monstrosity, ran out of disk space on the root partition, and the Kubelet died in a fit of rage. I had to manually prune the build cache on twelve different workers just to get the control plane to talk to me again. \n\nSit down. We are going to talk about why your &quot;it works on my machine&quot; mentality is a cancer on this infrastructure.\n\n## Stop Using 'Latest' Like a Gambler\n\nYou tagged your image as `latest`. Do you know what `latest` means in Docker Engine 24.0.7? It means absolutely nothing. It is a default label, not a pointer to the most recent stable build. When you pushed that 3GB image, every single node in the cluster that had an `imagePullPolicy: Always` setting tried to pull it simultaneously. \n\nBecause you didn't version your image, I couldn't roll back. I couldn't just tell Kubernetes to go back to `v1.2.3` because you\u2019ve been overwriting `latest` for the last three weeks. We had to dig through the registry API to find the SHA256 hash of the previous working image while the CEO was screaming in the Slack bridge.\n\nIn a real environment, you pin your versions. You use semantic versioning. You use the git commit hash. You do anything except use that godforsaken tag. If I see another deployment manifest with `image: awesome-app:latest`, I am revoking your registry write permissions and making you deploy via carrier pigeon.\n\n## Your Layers are Bloated and You Should Feel Bad\n\nI ran a `docker history` on your image. It was like performing an autopsy on a man who died from eating too much lead. Here is what I saw:\n\n```bash\nIMAGE          CREATED        CREATED BY                                      SIZE      COMMENT\n&lt;missing&gt;      2 hours ago    \/bin\/sh -c #(nop)  CMD [&quot;npm&quot; &quot;start&quot;]          0B        \n&lt;missing&gt;      2 hours ago    \/bin\/sh -c npm install                          1.8GB     \n&lt;missing&gt;      2 hours ago    \/bin\/sh -c #(nop) COPY dir:7e3... in \/app       1.1GB     \n&lt;missing&gt;      2 hours ago    \/bin\/sh -c apt-get update &amp;&amp; apt-get install\u2026   450MB     \n&lt;missing&gt;      3 weeks ago    \/bin\/sh -c #(nop)  WORKDIR \/app                 0B        \n&lt;missing&gt;      3 weeks ago    \/bin\/sh -c #(nop)  FROM node:bookworm           850MB     \n<\/code><\/pre>\n<p>Three gigabytes. For a Hello World API. <\/p>\n<p>You used <code>node:bookworm<\/code> (Debian Bookworm) as your base image. Why? Do you need a full suite of build tools, man pages, and a C compiler in production? No. You don&#8217;t. You included the <code>.git<\/code> directory. You included the <code>tests<\/code> folder. You included the <code>node_modules<\/code> from your local macOS environment which, newsflash, doesn&#8217;t work on Linux when you have native C++ bindings.<\/p>\n<p>You need to understand OverlayFS2. Every <code>RUN<\/code>, <code>COPY<\/code>, and <code>ADD<\/code> instruction in your Dockerfile creates a new layer. These layers are stacked. If you <code>COPY<\/code> 1GB of data in one layer and then <code>RUN rm -rf<\/code> that data in the next, your image is still 1GB larger. The data is still there, hidden in the lowerdir, haunting the filesystem like a vengeful ghost. To keep things &#8220;docker best&#8221; compliant, you must clean up in the same layer where the mess was made.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_80 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69d8589612b87\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69d8589612b87\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#Multi-Stage_Builds_are_Not_a_Suggestion\" >Multi-Stage Builds are Not a Suggestion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#Stop_Running_as_Root_Before_I_Revoke_Your_Sudo\" >Stop Running as Root Before I Revoke Your Sudo<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#ENTRYPOINT_is_Not_a_Suggestion_and_Shell_Form_is_a_Lie\" >ENTRYPOINT is Not a Suggestion, and Shell Form is a Lie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#Build_Performance_and_the_Myth_of_the_Clean_Slate\" >Build Performance and the Myth of the Clean Slate<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#The_Anatomy_of_OverlayFS2_and_Why_You_Broke_the_Disk\" >The Anatomy of OverlayFS2 and Why You Broke the Disk<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#The_Cost_of_Ignorance\" >The Cost of Ignorance<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#Related_Articles\" >Related Articles<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Multi-Stage_Builds_are_Not_a_Suggestion\"><\/span>Multi-Stage Builds are Not a Suggestion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If you want to be a &#8220;rockstar,&#8221; learn to use a multi-stage Dockerfile. This isn&#8217;t 2014. We don&#8217;t need to ship the compiler with the binary. We use one stage to build the assets and a second, clean stage to run them. <\/p>\n<p>Here is the &#8220;Broken&#8221; Dockerfile you pushed, which I have pinned to the wall of shame:<\/p>\n<pre class=\"codehilite\"><code class=\"language-dockerfile\"># THE BROKEN WAY - DO NOT DO THIS\nFROM node:20\nWORKDIR \/app\nCOPY . .\nRUN apt-get update &amp;&amp; apt-get install -y python3 make g++ # Why is this here?\nRUN npm install\nEXPOSE 3000\nCMD npm start\n<\/code><\/pre>\n<p>And here is what a professional would have written using Alpine 3.19 to keep the footprint small and the attack surface narrow:<\/p>\n<pre class=\"codehilite\"><code class=\"language-dockerfile\"># THE BETTER WAY - Multi-stage with Alpine 3.19\n# Stage 1: Build\nFROM node:20-alpine3.19 AS builder\nWORKDIR \/app\n# Use build mounts to cache npm packages\nRUN --mount=type=cache,target=\/root\/.npm \\\n    COPY package*.json .\/ &amp;&amp; \\\n    npm ci\n\nCOPY . .\nRUN npm run build\n\n# Stage 2: Runtime\nFROM node:20-alpine3.19\nRUN apk add --no-cache tini\nWORKDIR \/app\n# Copy only the necessary artifacts\nCOPY --from=builder \/app\/dist .\/dist\nCOPY --from=builder \/app\/node_modules .\/node_modules\nCOPY --from=builder \/app\/package.json .\/package.json\n\n# Security: Never run as root\nUSER 10001\nENTRYPOINT [&quot;\/sbin\/tini&quot;, &quot;--&quot;]\nCMD [&quot;node&quot;, &quot;dist\/index.js&quot;]\n<\/code><\/pre>\n<p>By using multi-stage builds, you separate the build-time dependencies (like <code>python3<\/code> or <code>g++<\/code> for native modules) from the runtime environment. The final image only contains the compiled code and the production <code>node_modules<\/code>. This would have turned your 3GB disaster into a 150MB image that pulls in three seconds instead of three minutes.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Stop_Running_as_Root_Before_I_Revoke_Your_Sudo\"><\/span>Stop Running as Root Before I Revoke Your Sudo<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I noticed your container process was running as <code>root<\/code>. Do you have any idea how dangerous that is? If there is a container breakout vulnerability in the Linux kernel or the container runtime, the attacker doesn&#8217;t just have your app; they have the host.<\/p>\n<p>You wrote <code>USER 10001<\/code> in your head and then forgot to put it in the file. In the &#8220;docker best&#8221; world, we follow the principle of least privilege. We don&#8217;t need UID 0 to serve a JSON payload over HTTP. By specifying a non-privileged UID (like 10001), even if someone exploits your shitty code, they are trapped in a sandbox with no permissions to do anything meaningful to the underlying node.<\/p>\n<p>Also, notice the <code>apk add --no-cache tini<\/code>. This brings us to the next point that you clearly ignored while you were busy &#8220;disrupting&#8221; the uptime.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"ENTRYPOINT_is_Not_a_Suggestion_and_Shell_Form_is_a_Lie\"><\/span>ENTRYPOINT is Not a Suggestion, and Shell Form is a Lie<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In your Dockerfile, you used <code>CMD npm start<\/code>. This is the &#8220;shell form.&#8221; When you do this, Docker starts a shell (<code>\/bin\/sh -c<\/code>) and then the shell starts your process. Your application is no longer PID 1; the shell is.<\/p>\n<p>Why does this matter? Because shells do not forward signals. <\/p>\n<p>When Kubernetes tries to stop your pod, it sends a <code>SIGTERM<\/code>. It waits 30 seconds for your app to shut down gracefully\u2014closing database connections, finishing active requests, and saving state. But because you used the shell form, your app never sees the <code>SIGTERM<\/code>. It just sits there, oblivious, until the 30-second grace period expires and the kernel sends a <code>SIGKILL<\/code>. <\/p>\n<p><code>SIGKILL<\/code> is the digital equivalent of a bullet to the back of the head. It doesn&#8217;t allow for cleanup. It leaves database locks dangling. It corrupts files.<\/p>\n<p>Use the &#8220;JSON form&#8221; for <code>ENTRYPOINT<\/code> and <code>CMD<\/code>.<br \/>\n&#8211; <strong>Shell form:<\/strong> <code>CMD node index.js<\/code> -&gt; Runs as <code>\/bin\/sh -c \"node index.js\"<\/code><br \/>\n&#8211; <strong>JSON form:<\/strong> <code>CMD [\"node\", \"index.js\"]<\/code> -&gt; Runs as <code>node index.js<\/code> (PID 1)<\/p>\n<p>And use <code>tini<\/code>. It\u2019s a tiny init process that handles zombie processes and forwards signals correctly. It ensures that when I tell the cluster to restart, it actually restarts, rather than hanging for 30 seconds while the Kubelet gets impatient.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Build_Performance_and_the_Myth_of_the_Clean_Slate\"><\/span>Build Performance and the Myth of the Clean Slate<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You complained that the build was &#8220;slow&#8221; on your machine, so you started skipping the <code>.dockerignore<\/code> file. You thought it was faster to just <code>COPY . .<\/code> and let Docker figure it out. <\/p>\n<p>Every time you change a single line in your <code>README.md<\/code>, you invalidate the cache for the <code>COPY . .<\/code> layer. Because that layer is invalidated, every subsequent layer\u2014including the <code>npm install<\/code>\u2014has to run from scratch. That is why our CI\/CD pipeline was backed up for two hours.<\/p>\n<p>By using <code>--mount=type=cache<\/code>, as shown in my &#8220;Fixed&#8221; Dockerfile, we can persist the <code>npm<\/code> cache across builds. Even if the layer is invalidated, the package manager doesn&#8217;t have to re-download the entire internet. It just checks the local cache. <\/p>\n<p>Also, for the love of all that is holy, use a <code>.dockerignore<\/code> file. <\/p>\n<pre class=\"codehilite\"><code class=\"language-text\">.git\nnode_modules\nnpm-debug.log\ndist\ntests\n.env\n<\/code><\/pre>\n<p>If these files are in your build context, they are sent to the Docker daemon. If your <code>.git<\/code> folder is 1.2GB (which yours was, because you never prune your objects), then every time you run <code>docker build<\/code>, you are transferring 1.2GB of useless metadata to the daemon. It\u2019s slow, it\u2019s inefficient, and it\u2019s the opposite of &#8220;docker best&#8221; behavior.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_Anatomy_of_OverlayFS2_and_Why_You_Broke_the_Disk\"><\/span>The Anatomy of OverlayFS2 and Why You Broke the Disk<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let&#8217;s get technical, since you seem to think &#8220;DevOps&#8221; is just a buzzword you put on LinkedIn. Docker uses OverlayFS2 to manage image layers. It uses a &#8220;lowerdir&#8221; (read-only layers), an &#8220;upperdir&#8221; (the writable layer of the container), and a &#8220;merged&#8221; view.<\/p>\n<p>When you run <code>apt-get update<\/code>, you are writing hundreds of megabytes of package metadata to the upperdir. If you don&#8217;t delete that metadata in the <em>same<\/em> <code>RUN<\/code> command, it is committed to a read-only layer. <\/p>\n<pre class=\"codehilite\"><code class=\"language-dockerfile\"># WRONG: The cache stays in the image forever\nRUN apt-get update\nRUN apt-get install -y heavy-package\nRUN rm -rf \/var\/lib\/apt\/lists\/*\n\n# RIGHT: The cache is deleted before the layer is committed\nRUN apt-get update &amp;&amp; \\\n    apt-get install -y heavy-package &amp;&amp; \\\n    rm -rf \/var\/lib\/apt\/lists\/*\n<\/code><\/pre>\n<p>In your image, you had five different <code>RUN<\/code> commands for system updates. You had layers that were nothing but <code>apt<\/code> metadata. You were literally shipping a graveyard of cached files that served no purpose other than to make my life miserable at 3:00 AM.<\/p>\n<p>When the container runtime pulls these layers, it has to extract them. Extraction requires disk space. If your image is 3GB compressed, it might be 6GB or 7GB uncompressed. Our worker nodes have 20GB root partitions. You took up 35% of the entire disk with one single, poorly optimized container. When the second and third pods tried to schedule on the same node, the disk filled up, the Kubelet couldn&#8217;t write its own logs, and the node went <code>NotReady<\/code>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_Cost_of_Ignorance\"><\/span>The Cost of Ignorance<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This isn&#8217;t just about disk space. It&#8217;s about the blast radius. Because the node went <code>NotReady<\/code>, Kubernetes tried to reschedule those pods onto <em>other<\/em> nodes. Those nodes also had 20GB disks. They also tried to pull your 3GB image. They also ran out of space. It was a cascading failure\u2014a &#8220;death spiral&#8221; triggered by your lack of basic container hygiene.<\/p>\n<p>I spent four hours writing scripts to purge the <code>\/var\/lib\/docker\/overlay2<\/code> directory across the cluster because <code>docker system prune<\/code> wasn&#8217;t enough to recover the nodes in their hung state. I had to stop the Docker daemon, manually unmount stuck overlay points, and pray that I didn&#8217;t corrupt the underlying XFS filesystem.<\/p>\n<p>We are moving to a strict policy. From now on, any image over 500MB gets automatically rejected by the admission controller. Any image using the <code>latest<\/code> tag will be deleted from the registry by a cron job every hour. Any container running as root will be killed by the Pod Security Admission controller.<\/p>\n<p>You want to be a rockstar? Start by acting like an engineer. Learn how the Linux kernel handles signals. Learn how the filesystem manages layers. Stop treating Docker like a &#8220;magic box&#8221; that hides your bad habits. <\/p>\n<p>I\u2019m going home now. I\u2019m going to sleep for fourteen hours. When I come back, if I see a 3GB image in the staging registry, I\u2019m not going to fix it. I\u2019m just going to point the PagerDuty alerts directly to your personal phone and see how much you enjoy the &#8220;rockstar&#8221; lifestyle at 4:00 AM.<\/p>\n<p>Go read the documentation. And don&#8217;t you dare use the word &#8220;optimized&#8221; in the stand-up tomorrow unless you&#8217;ve actually reduced the layer count.<\/p>\n<p>Actually, don&#8217;t bother. You&#8217;ll probably just find a way to include a 2GB machine learning model in a CSS-only microservice by next week anyway. I\u2019m updating my resume.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Related_Articles\"><\/span>Related Articles<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Explore more insights and best practices:<\/p>\n<ul>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/creating-and-assigning-custom-licensing-options-in-microsoft-office-365\/\">Creating And Assigning Custom Licensing Options In Microsoft Office 365<\/a><\/li>\n<li><a href=\"https:\/\/oracle.itsupportwale.com\/blog\/master-the-python-list-a-complete-guide-with-examples\/\">Master The Python List A Complete Guide With Examples<\/a><\/li>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/new-xiaomi-mi-color-watch-launching-in-january\/\">New Xiaomi Mi Color Watch Launching In January<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>text [2024-05-22 03:14:02] INFO: Deployment triggered by &#8216;Rockstar_Dev_69&#8217; [2024-05-22 03:15:44] ERROR: Failed to pull image &#8220;registry.internal\/awesome-app:latest&#8221; [2024-05-22 03:15:44] ERROR: RPC error: code = Unknown desc = failed to register layer: Error processing tar file(exit status 1): write \/usr\/src\/app\/node_modules\/huge-useless-library\/dist\/bundle.js: no space left on device [2024-05-22 03:16:10] CRITICAL: Node ip-10-0-42-12.ec2.internal is DiskPressure [2024-05-22 03:16:15] CRITICAL: Kubelet stopped &#8230; <a title=\"10 Docker Best Practices to Optimize Your Containers\" class=\"read-more\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\" aria-label=\"Read more  on 10 Docker Best Practices to Optimize Your Containers\">Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4482","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>10 Docker Best Practices to Optimize Your Containers - ITSupportWale<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"10 Docker Best Practices to Optimize Your Containers - ITSupportWale\" \/>\n<meta property=\"og:description\" content=\"text [2024-05-22 03:14:02] INFO: Deployment triggered by &#8216;Rockstar_Dev_69&#8217; [2024-05-22 03:15:44] ERROR: Failed to pull image &#8220;registry.internal\/awesome-app:latest&#8221; [2024-05-22 03:15:44] ERROR: RPC error: code = Unknown desc = failed to register layer: Error processing tar file(exit status 1): write \/usr\/src\/app\/node_modules\/huge-useless-library\/dist\/bundle.js: no space left on device [2024-05-22 03:16:10] CRITICAL: Node ip-10-0-42-12.ec2.internal is DiskPressure [2024-05-22 03:16:15] CRITICAL: Kubelet stopped ... Read more\" \/>\n<meta property=\"og:url\" content=\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\" \/>\n<meta property=\"og:site_name\" content=\"ITSupportWale\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Itsupportwale-298547177495978\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-26T15:38:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-17T10:27:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2021\/05\/android-chrome-512x512-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Techie\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Techie\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\"},\"author\":{\"name\":\"Techie\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d\"},\"headline\":\"10 Docker Best Practices to Optimize Your Containers\",\"datePublished\":\"2026-01-26T15:38:31+00:00\",\"dateModified\":\"2026-02-17T10:27:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\"},\"wordCount\":1454,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\",\"url\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\",\"name\":\"10 Docker Best Practices to Optimize Your Containers - ITSupportWale\",\"isPartOf\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#website\"},\"datePublished\":\"2026-01-26T15:38:31+00:00\",\"dateModified\":\"2026-02-17T10:27:18+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/itsupportwale.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"10 Docker Best Practices to Optimize Your Containers\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#website\",\"url\":\"https:\/\/itsupportwale.com\/blog\/\",\"name\":\"ITSupportWale\",\"description\":\"Tips, Tricks, Fixed-Errors, Tutorials &amp; Guides\",\"publisher\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/itsupportwale.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\",\"name\":\"itsupportwale\",\"url\":\"https:\/\/itsupportwale.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png\",\"contentUrl\":\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png\",\"width\":1119,\"height\":144,\"caption\":\"itsupportwale\"},\"image\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Itsupportwale-298547177495978\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d\",\"name\":\"Techie\",\"sameAs\":[\"https:\/\/itsupportwale.com\",\"iswblogadmin\"],\"url\":\"https:\/\/itsupportwale.com\/blog\/author\/iswblogadmin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"10 Docker Best Practices to Optimize Your Containers - ITSupportWale","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/","og_locale":"en_US","og_type":"article","og_title":"10 Docker Best Practices to Optimize Your Containers - ITSupportWale","og_description":"text [2024-05-22 03:14:02] INFO: Deployment triggered by &#8216;Rockstar_Dev_69&#8217; [2024-05-22 03:15:44] ERROR: Failed to pull image &#8220;registry.internal\/awesome-app:latest&#8221; [2024-05-22 03:15:44] ERROR: RPC error: code = Unknown desc = failed to register layer: Error processing tar file(exit status 1): write \/usr\/src\/app\/node_modules\/huge-useless-library\/dist\/bundle.js: no space left on device [2024-05-22 03:16:10] CRITICAL: Node ip-10-0-42-12.ec2.internal is DiskPressure [2024-05-22 03:16:15] CRITICAL: Kubelet stopped ... Read more","og_url":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/","og_site_name":"ITSupportWale","article_publisher":"https:\/\/www.facebook.com\/Itsupportwale-298547177495978","article_published_time":"2026-01-26T15:38:31+00:00","article_modified_time":"2026-02-17T10:27:18+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2021\/05\/android-chrome-512x512-1.png","type":"image\/png"}],"author":"Techie","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Techie","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#article","isPartOf":{"@id":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/"},"author":{"name":"Techie","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d"},"headline":"10 Docker Best Practices to Optimize Your Containers","datePublished":"2026-01-26T15:38:31+00:00","dateModified":"2026-02-17T10:27:18+00:00","mainEntityOfPage":{"@id":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/"},"wordCount":1454,"commentCount":0,"publisher":{"@id":"https:\/\/itsupportwale.com\/blog\/#organization"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/","url":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/","name":"10 Docker Best Practices to Optimize Your Containers - ITSupportWale","isPartOf":{"@id":"https:\/\/itsupportwale.com\/blog\/#website"},"datePublished":"2026-01-26T15:38:31+00:00","dateModified":"2026-02-17T10:27:18+00:00","breadcrumb":{"@id":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/itsupportwale.com\/blog\/10-docker-best-practices-to-optimize-your-containers\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/itsupportwale.com\/blog\/"},{"@type":"ListItem","position":2,"name":"10 Docker Best Practices to Optimize Your Containers"}]},{"@type":"WebSite","@id":"https:\/\/itsupportwale.com\/blog\/#website","url":"https:\/\/itsupportwale.com\/blog\/","name":"ITSupportWale","description":"Tips, Tricks, Fixed-Errors, Tutorials &amp; Guides","publisher":{"@id":"https:\/\/itsupportwale.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/itsupportwale.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/itsupportwale.com\/blog\/#organization","name":"itsupportwale","url":"https:\/\/itsupportwale.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png","contentUrl":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png","width":1119,"height":144,"caption":"itsupportwale"},"image":{"@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Itsupportwale-298547177495978"]},{"@type":"Person","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d","name":"Techie","sameAs":["https:\/\/itsupportwale.com","iswblogadmin"],"url":"https:\/\/itsupportwale.com\/blog\/author\/iswblogadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4482","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/comments?post=4482"}],"version-history":[{"count":3,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4482\/revisions"}],"predecessor-version":[{"id":4666,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4482\/revisions\/4666"}],"wp:attachment":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/media?parent=4482"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/categories?post=4482"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/tags?post=4482"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}