{"id":349570,"date":"2021-10-07T15:00:39","date_gmt":"2021-10-07T12:00:39","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/"},"modified":"2021-10-07T15:00:39","modified_gmt":"2021-10-07T12:00:39","slug":"7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/","title":{"rendered":"#7 Docker Anti-Patterns You Need to Avoid \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom 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-6a2fc22d41a48\" 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: #dd3333;color:#dd3333\" 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: #dd3333;color:#dd3333\" 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-6a2fc22d41a48\" checked 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:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#1_Applying_Updates_Inside_Containers\" >1. Applying Updates Inside Containers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#2_Running_Multiple_Services_Inside_One_Container\" >2. Running Multiple Services Inside One Container<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#3_Image_Builds_With_Side_Effects\" >3. Image Builds With Side Effects<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#4_Over-complicating_Your_Dockerfile\" >4. Over-complicating Your Dockerfile<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#5_Hardcoded_Configuration\" >5. Hardcoded Configuration<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#6_Separate_Development_and_Deployment_Images\" >6. Separate Development and Deployment Images<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#7_Storing_Data_Inside_Containers\" >7. Storing Data Inside Containers<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/7-docker-anti-patterns-you-need-to-avoid-cloudsavvy-it\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#7 Docker Anti-Patterns You Need to Avoid \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage aligncenter size-full wp-image-9034\" srcset=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=398&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 400w, https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1 1200w\" sizes=\"auto, 400w, 1200w\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1602\" height=\"902\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Docker has transformed software development with its simple model of containerization that lets you rapidly package workloads into reproducible units. While Docker\u2019s easy to get to grips with, there\u2019s more nuance to its usage than is always <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">app<\/a>arent. This is especially true when you\u2019re looking to optimize your Docker usage to increase efficiency and performance.<\/p>\n<p>Here are seven of the most common Docker anti-patterns you should look for and avoid. Although your containers and images might fulfill your im<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/social-mediaa\/\" data-internallinksmanager029f6b8e52c=\"1\" title=\"Social Media\" target=\"_blank\" rel=\"noopener\">media<\/a>te needs, the presence of any of these practices suggests you\u2019re deviating from containerization principles in a way which could be harmful further down the line.<\/p>\n<h2 id=\"applying-updates-inside-containers\"><span class=\"ez-toc-section\" id=\"1_Applying_Updates_Inside_Containers\"><\/span>1. Applying Updates Inside Containers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Arguably the most common Docker anti-pattern is trying to update containers using techniques carried over from traditional virtual machines. Container filesystems are ephemeral so all changes are lost when the container stops. Their state should be reproducible from the <code>Dockerfile<\/code> used to build the image.<\/p>\n<p>This means you shouldn\u2019t run an <code>apt upgrade<\/code> inside your containers. They\u2019d then differ from the image they were built from. Containers are intended to be freely interchangeable; separating your data from your code and dependencies lets you replace container instances at any time.<\/p>\n<p>Patches should be applied by periodically rebuilding your image, stopping existing containers, and starting new ones based on the revised image. Community toolchain projects are available to simplify this process and let you know of available upstream updates.<\/p>\n<h2 id=\"running-multiple-services-inside-one-container\"><span class=\"ez-toc-section\" id=\"2_Running_Multiple_Services_Inside_One_Container\"><\/span>2. Running Multiple Services Inside One Container<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Containers should be independent and focused on one particular function. Although you may previously have run your web and database servers on a single physical machine, a fully decoupled approach would see the two components separated into individual containers.<\/p>\n<p>This methodology prevents individual container images from becoming too large. You can inspect the logs from each service using built-in Docker commands and update them independently of each other.<\/p>\n<p>Multiple containers give you enhanced scalability as you can readily increase the replica count of individual parts of your stack. Database running slow? Use your container orchestrator to add a few more MySQL container instances, without allocating any extra resources to the components that are already running well.<\/p>\n<h2 id=\"image-builds-with-side-effects\"><span class=\"ez-toc-section\" id=\"3_Image_Builds_With_Side_Effects\"><\/span>3. Image Builds With Side Effects<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker image builds should be idempotent operations that always produce the same result. Running <code>docker build<\/code> shouldn\u2019t impact your broader environment in the slightest as its sole objective is to produce a container image.<\/p>\n<p>Nonetheless many teams create Dockerfiles that manipulate external resources. A Dockerfile can morph into a form of all-encompassing CI script that publishes releases, creates Git commits, and writes to external APIs or databases.<\/p>\n<p>These actions don\u2019t belong in a Dockerfile. Creating a Docker image is an independent operation which should be its own CI pipeline stage. Release preparation then occurs as a <em>separate<\/em> stage so you can always <code>docker build<\/code> without unexpectedly publishing a new tag.<\/p>\n<h2 id=\"over-complicating-your-dockerfile\"><span class=\"ez-toc-section\" id=\"4_Over-complicating_Your_Dockerfile\"><\/span>4. Over-complicating Your Dockerfile<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In a similar vein, it is possible for Dockerfiles to do too much. Limiting your Dockerfile to the bare minimum set of instructions you need minimizes your image size and enhances readability and maintainability.<\/p>\n<p>Problems can often occur when using multi-stage Docker builds. This feature makes it easy to develop complex build sequences referencing multiple base images. Many independent stages can be an indicator that you\u2019re mixing concerns and coupling processes too tightly together.<\/p>\n<p>Look for logical sections in your Dockerfile that serve specific purposes. Try to break these up into individual Dockerfiles, creating self-contained utility images that can run independently to fulfill parts of your broader pipeline.<\/p>\n<p>You could create a \u201cbuilder\u201d image with the dependencies needed to compile your source. Use this image as one stage in your CI pipeline, then feed its output as artifacts into the next stage. You might now copy the compiled binaries into a final Docker image which you use in production.<\/p>\n<h2 id=\"hardcoded-configuration\"><span class=\"ez-toc-section\" id=\"5_Hardcoded_Configuration\"><\/span>5. Hardcoded Configuration<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Container images which include credentials, secrets, or hardcoded configuration keys can cause serious headaches as well as security risks. Baking settings into your image compromises Docker\u2019s fundamental attraction, the ability to deploy the same thing into multiple environments.<\/p>\n<p>Use environment variables and declared Docker secrets to inject configuration at the point you start a container. This maintains images as reusable assets and limits sensitive data access to runtime only.<\/p>\n<p>This rule still applies to images that are intended for internal use only. Hardcoding secrets implies they\u2019re also committed to your version control software, potentially rendering them vulnerable to theft in the event of a server breach.<\/p>\n<h2 id=\"separate-development-and-deployment-images\"><span class=\"ez-toc-section\" id=\"6_Separate_Development_and_Deployment_Images\"><\/span>6. Separate Development and Deployment Images<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You should only build one container image for each change in your application. Maintaining multiple similar images for individual environments suggests you\u2019re not benefiting from Docker\u2019s \u201cruns anywhere\u201d mentality.<\/p>\n<p>It\u2019s best to promote a single image across your environments, from staging through to production. This gives you confidence you\u2019re running the exact same logical environment in each of your deployments, so what worked in staging will still run in production.<\/p>\n<p>Having a dedicated \u201cproduction\u201d image suggests you may be suffering from some of the other anti-patterns indicated above. You\u2019ve probably got a complex build sequence that could be broken up, or production-specific credentials hardcoded into your image. Images should be separated by development lifecycle stage, not by deployment environment. Handle differences between environments by injecting configuration using variables.<\/p>\n<h2 id=\"storing-data-inside-containers\"><span class=\"ez-toc-section\" id=\"7_Storing_Data_Inside_Containers\"><\/span>7. Storing Data Inside Containers<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The ephemeral nature of container filesystems means you shouldn\u2019t be writing data within them. Persistent data created by your application\u2019s users, such as uploads and databases, should be stored in Docker volumes or it will be lost when your containers restart.<\/p>\n<p>Other kinds of useful data should avoid writing to the filesystem wherever possible. Stream logs to your container\u2019s output stream, where they can be consumed via the <code>docker logs<\/code> command, instead of dumping them to a directory which would be lost after a container failure.<\/p>\n<p>Container filesystem writes can also incur a significant performance penalty when modifying existing files. Docker\u2019s use of the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/storage\/storagedriver\/\">\u201ccopy-on-write\u201d layering strategy<\/a> means files that exist in lower filesystem layers are read from that layer, rather than your image\u2019s final layer. If a change is made to the file, Docker must first copy it into the uppermost layer, then apply the change. This process could take several seconds for larger files.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Watching for these anti-patterns will make your Docker images more reusable and easier to maintain. They\u2019re the difference between merely using Docker containers and adopting a containerized workflow. You can easily write a functioning Dockerfile but a poorly planned one will restrict your ability to capitalize on all the potential benefits.<\/p>\n<p>Containers should be ephemeral, self-contained units of functionality created from a reproducible build process. They map to stages in your development process, not deployment environments, but don\u2019t directly facilitate that process themselves. Images should be the artifacts produced by a CI pipeline, not the mechanism defining that pipeline.<\/p>\n<p>Adopting containers requires a mindset shift. It\u2019s best to start from the fundamentals, be aware of the overarching objectives, then look at how you can incorporate them into your process. Using containers without due consideration of these aspects can end up creating a headache in the long-term, far from the increased flexibility and reliability touted by proponents of the approach.\n<\/p><\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/14343\/7-docker-anti-patterns-you-need-to-avoid\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#7 Docker Anti-Patterns You Need to Avoid \u2013 CloudSavvy IT&#8221; Docker has transformed software development with its simple model of containerization that lets you rapidly package workloads into reproducible units. While Docker\u2019s easy to get to grips with, there\u2019s more nuance to its usage than is always apparent. This is especially true when you\u2019re looking&#8230;<\/p>\n","protected":false},"author":1,"featured_media":349571,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-349570","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/349570","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=349570"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/349570\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/349571"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=349570"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=349570"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=349570"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}