{"id":476967,"date":"2022-07-23T09:02:09","date_gmt":"2022-07-23T06:02:09","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-make-docker-compose-wait-for-dependency-containers\/"},"modified":"2022-07-23T09:02:09","modified_gmt":"2022-07-23T06:02:09","slug":"how-to-make-docker-compose-wait-for-dependency-containers","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-make-docker-compose-wait-for-dependency-containers\/","title":{"rendered":"#How to Make Docker Compose Wait for Dependency Containers"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 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-6a2409e35251b\" 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-6a2409e35251b\" 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-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-make-docker-compose-wait-for-dependency-containers\/#%E2%80%9CHow_to_Make_Docker_Compose_Wait_for_Dependency_Containers%E2%80%9D\" >&#8220;How to Make Docker Compose Wait for Dependency Containers&#8221;<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-make-docker-compose-wait-for-dependency-containers\/#The_Basics\" >The Basics<\/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\/how-to-make-docker-compose-wait-for-dependency-containers\/#Waiting_for_Readiness\" >Waiting for Readiness<\/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\/how-to-make-docker-compose-wait-for-dependency-containers\/#Waiting_for_a_Successful_Container_Exit\" >Waiting for a Successful Container Exit<\/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\/how-to-make-docker-compose-wait-for-dependency-containers\/#Summary\" >Summary<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CHow_to_Make_Docker_Compose_Wait_for_Dependency_Containers%E2%80%9D\"><\/span>&#8220;How to Make Docker Compose Wait for Dependency Containers&#8221;<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<div>\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage aligncenter size-full wp-image-9034\" data-pagespeed-no-defer=\"\" src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/csit\/2021\/01\/6dc7b5a0.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1602\" height=\"902\"\/><br \/>Docker Compose lets you start multiple containers by running a single command. This simplifies bringing up complex services formed from several independent components.<\/p>\n<p>This isn\u2019t always good enough though. Some of your containers might have dependencies on each other that break the <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>lication if they can\u2019t be fulfilled. In this guide, we\u2019ll show how you can configure your Compose services to accommodate these dependencies, making it possible to start containers in order.<\/p>\n<h2 id=\"the-basics\"><span class=\"ez-toc-section\" id=\"The_Basics\"><\/span>The Basics<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker Compose supports a <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/compose\/compose-file\/#depends_on\"><code>depends_on<\/code> field<\/a> in <code>docker.compose.yml<\/code> files. Services can include the names of their siblings in <code>depends_on<\/code>. This prevents the container from starting until the depended-on services are up.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"yaml\">\n<pre class=\"de1\"><span class=\"co4\">services<\/span>:<span class=\"co4\">\n  api<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/api:latest<span class=\"co4\">\n    depends_on<\/span><span class=\"sy2\">:\n<\/span>      - db<span class=\"co4\">\n  web-app<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/web-app:latest<span class=\"co4\">\n    depends_on<\/span><span class=\"sy2\">:\n<\/span>      - api<span class=\"co4\">\n  db<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>mysql:8.0<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>In this example, the <code>depends_on<\/code> fields cause the services to start in the following order:<\/p>\n<p>Each service\u2019s dependencies are resolved recursively. The service that defines each <code>depends_on<\/code> field is started last, at the very end of the chain. When a service depends on multiple other containers, they\u2019ll be started in the order they\u2019re listed in the <code>depends_on<\/code> field.<\/p>\n<p>The chain of services is used in reverse when you stop a stack with <code>docker-compose stop<\/code>. With the example above, the <code>web-app<\/code> container will be deleted first, then <code>api<\/code> and <code>db<\/code>. This prevents requests to the <code>web-app<\/code> container from failing as a tear-down operation commences.<\/p>\n<h2 id=\"waiting-for-readiness\"><span class=\"ez-toc-section\" id=\"Waiting_for_Readiness\"><\/span>Waiting for Readiness<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The default <code>depends_on<\/code> configuration only waits for dependent containers to <em>start<\/em>. In the example above, Compose can create the <code>api<\/code> container as soon as <code>db<\/code> is running, even if the database server inside the container isn\u2019t ready to receive connections. This means <code>depends_on<\/code> is rarely sufficient on its own.<\/p>\n<p>You can combine the feature with healthchecks to prevent containers from starting until their dependencies are actually ready. To use this capability, nest a <code>condition<\/code> field under <code>depends_on<\/code> with <code>service_healthy<\/code> as its value:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"yaml\">\n<pre class=\"de1\"><span class=\"co4\">services<\/span>:<span class=\"co4\">\n  api<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/api:latest<span class=\"co4\">\n    depends_on<\/span><span class=\"sy2\">:\n<\/span>      - db<span class=\"co4\">\n    healthcheck<\/span>:<span class=\"co3\">\n      test<\/span><span class=\"sy2\">: <\/span>curl --fail http:\/\/127.0.0.1 || exit 1<span class=\"co3\">\n      interval<\/span><span class=\"sy2\">: <\/span>10s<span class=\"co3\">\n      retries<\/span><span class=\"sy2\">: <\/span>5<span class=\"co3\">\n      start_period<\/span><span class=\"sy2\">: <\/span>5s<span class=\"co3\">\n      timeout<\/span><span class=\"sy2\">: <\/span>10s<span class=\"co4\">\n  web-app<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/web-app:latest<span class=\"co4\">\n    depends_on<\/span>:<span class=\"co4\">\n      api<\/span>:<span class=\"co3\">\n        condition<\/span><span class=\"sy2\">: <\/span>service_healthy<span class=\"co4\">\n  db<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>mysql:8.0<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Now the <code>api<\/code> container has a healthcheck command attached. The <code>web-app<\/code> service is instructed not to start until <code>api<\/code> has been created with a successful healthcheck result. This will be once the API starts responding to requests and the <code>curl<\/code> command exits with a zero status code.<\/p>\n<h2 id=\"waiting-for-a-successful-container-exit\"><span class=\"ez-toc-section\" id=\"Waiting_for_a_Successful_Container_Exit\"><\/span>Waiting for a Successful Container Exit<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In some cases your dependency might be a single-use container that you want to run to completion. You can wait on this kind of dependency by setting the <code>condition<\/code> field to <code>service_completed_successfully<\/code>. This is useful when you\u2019ve got a first-run setup script that executes in another container.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"yaml\">\n<pre class=\"de1\"><span class=\"co4\">services<\/span>:<span class=\"co4\">\n  app<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/app:latest<span class=\"co4\">\n    depends_on<\/span>:<span class=\"co4\">\n      config_builder<\/span>:<span class=\"co3\">\n        condition<\/span><span class=\"sy2\">: <\/span>service_completed_successfully<span class=\"co4\">\n    volumes<\/span><span class=\"sy2\">:\n<\/span>      - config:\/opt\/app\/config<span class=\"co4\">\n  config_builder<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/config_builder:latest<span class=\"co4\">\n    env<\/span><span class=\"sy2\">:\n<\/span>      - EXAMPLE_KEY\n      - ANOTHER_KEY<span class=\"co4\">\n    volumes<\/span><span class=\"sy2\">:\n<\/span>      - config:\/output<span class=\"co4\">\nvolumes<\/span><span class=\"sy2\">:\n<\/span>  config:<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This example shows how a dependent image could run a command that writes a config file to a volume shared by <code>app<\/code>. After the data\u2019s been written, the <code>config_builder<\/code> container stops with a zero exit code. Compose then automatically starts the <code>app<\/code> service as its dependency condition has been met.<\/p>\n<p>In some situations <code>depends_on<\/code> with a <code>condition<\/code> might still not be enough to accommodate your use case. You can add external tools to manually implement health checks and handle links between containers.<\/p>\n<p><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/vishnubob\/wait-for-it\">Wait-for-It<\/a> is a utility script which wraps another process. It\u2019ll run the command you specify after a certain condition is met. This can be used to define healthcheck procedures independently of Docker\u2019s built-in support.<\/p>\n<p>Here\u2019s how to use <code>healthcheck<\/code> to wait for a linked container port to become accessible:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"yaml\">\n<pre class=\"de1\"><span class=\"co4\">services<\/span>:<span class=\"co4\">\n  api<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/api:latest<span class=\"co4\">\n    depends_on<\/span><span class=\"sy2\">:\n<\/span>      - db<span class=\"co4\">\n  web-app<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>example.com\/web-app:latest<span class=\"co4\">\n    depends_on<\/span><span class=\"sy2\">:\n<\/span>      - api<span class=\"co3\">\n    command<\/span><span class=\"sy2\">: <\/span><span class=\"br0\">[<\/span><span class=\"st0\">\".\/wait-for-it.sh\"<\/span>, <span class=\"st0\">\"api:8080\"<\/span>, <span class=\"st0\">\"--\"<\/span>, <span class=\"st0\">\"node\"<\/span>, <span class=\"st0\">\"app.js\"<\/span><span class=\"br0\">]<\/span><span class=\"co4\">\n  db<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>mysql:8.0<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Here we\u2019ve reverted to only making Docker Compose wait for the <code>api<\/code> container to <em>start<\/em>. The <code>web-app<\/code> service accepts responsibility for checking whether <code>api<\/code> is healthy. It uses the Wait-for-It script to detect when the container is accessible on port 8080. Wait-for-It will then launch the web app container\u2019s real command, defined as <code>node app.js<\/code>.<\/p>\n<p>This approach is best reserved for specific situations where you can\u2019t set up a proper healthcheck with Docker. It might be necessary when you\u2019re using a third-party image that can\u2019t be configured to run a healthcheck command. Wait-for-It provides a way of detecting whether a port\u2019s serving traffic as a stand-in replacement. While not infallible, this is often a good indicator of a container\u2019s healthiness.<\/p>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker Compose defaults to simultaneously starting all the services in your stack. This is often undesirable when links between the services create parent-child dependency relationships.<\/p>\n<p>The <code>depends_on<\/code> field lets you define a startup sequence for your services. Compose will create each new container in order, guaranteeing the previous one has started before the next container is added.<\/p>\n<p>You can wait for the previous container to exit or report a positive healthcheck by adding a <code>condition<\/code> to the dependency definition. In situations where healthchecks can\u2019t be used, you can defer to tools like Wait-for-It to have parent containers detect when their dependencies are ready.<\/p>\n<\/div>\n<p><script>\n setTimeout(function(){\n  !function(f,b,e,v,n,t,s)\n  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?\n  n.callMethod.apply(n,arguments):n.queue.push(arguments)};\n  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';\n  n.queue=[];t=b.createElement(e);t.async=!0;\n  t.src=v;s=b.getElementsByTagName(e)[0];\n  s.parentNode.insertBefore(t,s) } (window, document,'script',\n  'https:\/\/connect.facebook.net\/en_US\/fbevents.js');\n   fbq('init', '335401813750447');\n   fbq('track', 'PageView');\n  },3000);\n<\/script><\/p>\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.howtogeek.com\/devops\/how-to-make-docker-compose-wait-for-dependency-containers\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;How to Make Docker Compose Wait for Dependency Containers&#8221; Docker Compose lets you start multiple containers by running a single command. This simplifies bringing up complex services formed from several independent components. This isn\u2019t always good enough though. Some of your containers might have dependencies on each other that break the application if they can\u2019t&#8230;<\/p>\n","protected":false},"author":1,"featured_media":476968,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.howtogeek.com\/wp-content\/uploads\/csit\/2021\/01\/6dc7b5a0.jpeg?height=200p&trim=2,2,2,2","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-476967","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\/476967","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=476967"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/476967\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/476968"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=476967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=476967"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=476967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}