{"id":21696,"date":"2016-05-05T07:28:12","date_gmt":"2016-05-05T12:28:12","guid":{"rendered":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/"},"modified":"2016-05-05T07:28:12","modified_gmt":"2016-05-05T12:28:12","slug":"service-startup-and-docker-compose","status":"publish","type":"post","link":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/","title":{"rendered":"Service Startup and Docker Compose"},"content":{"rendered":"<figure><\/figure>\n<p><img class=\"lazyload\" alt=\"Docker\" height=\"137\" data-src=\"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png\">We make extensive use of Docker and Docker Compose at <a href=\"http:\/\/tasktop.com\">Tasktop<\/a> for building, testing and deploying our products. One of the pain points that we run in to is services that fail to start when other services are not available &#x2013; for example a web app that fails to start unless the database is already up and running. Apparently <a href=\"https:\/\/github.com\/docker\/compose\/issues\/374\">we&#x2019;re not the only ones<\/a>, so here&#x2019;s a bit of bash hackery to work around the problem:<\/p>\n<p>[code lang=text]<br \/>\nuntil nc -z -v -w5 $SERVICE_HOST $SERVICE_PORT;<br \/>\ndo<br \/>\necho &quot;waiting for service to become available on $SERVICE_HOST:$SERVICE_PORT&quot;<br \/>\nsleep 1<br \/>\ndone<br \/>\n[\/code]<\/p>\n<p>This hack uses netcat (nc) to wait for a socket accepting connections on the specified host and port. The <code>-z<\/code> flag causes netcat to detect the listening socket without actually sending any data.<\/p>\n<p>To make this work in a Docker container, you&#x2019;ll have to ensure that netcat is available:<\/p>\n<p>[code lang=text]<br \/>\nRUN apt-get update &amp;&amp; <br \/>\napt-get install -y <br \/>\nnetcat &amp;&amp; <br \/>\napt-get clean &amp;&amp; <br \/>\nrm -rf \/var\/lib\/apt\/lists\/*<br \/>\n[\/code]<\/p>\n<p>There are a few down sides to this approach, such as:<\/p>\n<ul>\n<li>the script will not terminate if the service isn&#x2019;t available &#x2013; there should be some kind of hard failure if the dependent service doesn&#x2019;t show up after awhile<\/li>\n<li>this hack ends up adding complexity to each Dockerfile that uses it<\/li>\n<li>some dependent services are still not &#x201C;ready&#x201D; even though they listen on a port &#x2013; those need a more sophisticated approach, something better than <code>sleep 30<\/code><\/li>\n<\/ul>\n<p>Despite the shortcomings, the approach works well enough to get us over the hump of service dependencies. Somehow, Docker has helped to reinvigorate shell scripting.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We make extensive use of Docker and Docker Compose at Tasktop for building, testing and deploying our products. One of the pain points that we run in to is services that fail to start when other services are not available &#x2013; for example a web app that fails to start unless the database is already&#8230;<\/p>\n","protected":false},"author":233,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","footnotes":""},"categories":[9548],"tags":[],"class_list":["post-21696","post","type-post","status-publish","format-standard","hentry","category-engineering-teams"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.8 (Yoast SEO v26.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Service Startup and Docker Compose | Tasktop Blog<\/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:\/\/blog.planview.com\/service-startup-and-docker-compose\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Service Startup and Docker Compose\" \/>\n<meta property=\"og:description\" content=\"We make extensive use of Docker and Docker Compose at Tasktop for building, testing and deploying our products. One of the pain points that we run in to is services that fail to start when other services are not available &#x2013; for example a web app that fails to start unless the database is already...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/\" \/>\n<meta property=\"og:site_name\" content=\"Planview Blog\" \/>\n<meta property=\"article:publisher\" content=\"http:\/\/www.facebook.com\/pages\/Planview-Inc\/89422974772\" \/>\n<meta property=\"article:published_time\" content=\"2016-05-05T12:28:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png\" \/>\n<meta name=\"author\" content=\"Tasktop Blogger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@Planview\" \/>\n<meta name=\"twitter:site\" content=\"@Planview\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tasktop Blogger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/\"},\"author\":{\"name\":\"Tasktop Blogger\",\"@id\":\"https:\/\/blog.planview.com\/#\/schema\/person\/35676ea677995199889c0b6456156ce2\"},\"headline\":\"Service Startup and Docker Compose\",\"datePublished\":\"2016-05-05T12:28:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/\"},\"wordCount\":298,\"publisher\":{\"@id\":\"https:\/\/blog.planview.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png\",\"articleSection\":[\"Engineering Teams\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/\",\"url\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/\",\"name\":\"Service Startup and Docker Compose | Tasktop Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.planview.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png\",\"datePublished\":\"2016-05-05T12:28:12+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage\",\"url\":\"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png\",\"contentUrl\":\"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.planview.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Service Startup and Docker Compose\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.planview.com\/#website\",\"url\":\"https:\/\/blog.planview.com\/\",\"name\":\"Planview Blog\",\"description\":\"Leading the conversation on digital connected work\",\"publisher\":{\"@id\":\"https:\/\/blog.planview.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.planview.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.planview.com\/#organization\",\"name\":\"Planview\",\"url\":\"https:\/\/blog.planview.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.planview.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.planview.com\/wp-content\/uploads\/2015\/06\/planview-logo-black.png\",\"contentUrl\":\"https:\/\/blog.planview.com\/wp-content\/uploads\/2015\/06\/planview-logo-black.png\",\"width\":280,\"height\":66,\"caption\":\"Planview\"},\"image\":{\"@id\":\"https:\/\/blog.planview.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"http:\/\/www.facebook.com\/pages\/Planview-Inc\/89422974772\",\"https:\/\/x.com\/Planview\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.planview.com\/#\/schema\/person\/35676ea677995199889c0b6456156ce2\",\"name\":\"Tasktop Blogger\",\"url\":\"https:\/\/blog.planview.com\/author\/tasktop-blogger\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Service Startup and Docker Compose | Tasktop Blog","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:\/\/blog.planview.com\/service-startup-and-docker-compose\/","og_locale":"en_US","og_type":"article","og_title":"Service Startup and Docker Compose","og_description":"We make extensive use of Docker and Docker Compose at Tasktop for building, testing and deploying our products. One of the pain points that we run in to is services that fail to start when other services are not available &#x2013; for example a web app that fails to start unless the database is already...","og_url":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/","og_site_name":"Planview Blog","article_publisher":"http:\/\/www.facebook.com\/pages\/Planview-Inc\/89422974772","article_published_time":"2016-05-05T12:28:12+00:00","og_image":[{"url":"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png","type":"","width":"","height":""}],"author":"Tasktop Blogger","twitter_card":"summary_large_image","twitter_creator":"@Planview","twitter_site":"@Planview","twitter_misc":{"Written by":"Tasktop Blogger","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#article","isPartOf":{"@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/"},"author":{"name":"Tasktop Blogger","@id":"https:\/\/blog.planview.com\/#\/schema\/person\/35676ea677995199889c0b6456156ce2"},"headline":"Service Startup and Docker Compose","datePublished":"2016-05-05T12:28:12+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/"},"wordCount":298,"publisher":{"@id":"https:\/\/blog.planview.com\/#organization"},"image":{"@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage"},"thumbnailUrl":"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png","articleSection":["Engineering Teams"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/","url":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/","name":"Service Startup and Docker Compose | Tasktop Blog","isPartOf":{"@id":"https:\/\/blog.planview.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage"},"image":{"@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage"},"thumbnailUrl":"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png","datePublished":"2016-05-05T12:28:12+00:00","breadcrumb":{"@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.planview.com\/service-startup-and-docker-compose\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#primaryimage","url":"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png","contentUrl":"https:\/\/media.planview.com\/tasktop_blog\/wp-content\/uploads\/2016\/05\/docker.png"},{"@type":"BreadcrumbList","@id":"https:\/\/blog.planview.com\/service-startup-and-docker-compose\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.planview.com\/"},{"@type":"ListItem","position":2,"name":"Service Startup and Docker Compose"}]},{"@type":"WebSite","@id":"https:\/\/blog.planview.com\/#website","url":"https:\/\/blog.planview.com\/","name":"Planview Blog","description":"Leading the conversation on digital connected work","publisher":{"@id":"https:\/\/blog.planview.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.planview.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/blog.planview.com\/#organization","name":"Planview","url":"https:\/\/blog.planview.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.planview.com\/#\/schema\/logo\/image\/","url":"https:\/\/blog.planview.com\/wp-content\/uploads\/2015\/06\/planview-logo-black.png","contentUrl":"https:\/\/blog.planview.com\/wp-content\/uploads\/2015\/06\/planview-logo-black.png","width":280,"height":66,"caption":"Planview"},"image":{"@id":"https:\/\/blog.planview.com\/#\/schema\/logo\/image\/"},"sameAs":["http:\/\/www.facebook.com\/pages\/Planview-Inc\/89422974772","https:\/\/x.com\/Planview"]},{"@type":"Person","@id":"https:\/\/blog.planview.com\/#\/schema\/person\/35676ea677995199889c0b6456156ce2","name":"Tasktop Blogger","url":"https:\/\/blog.planview.com\/author\/tasktop-blogger\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/posts\/21696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/users\/233"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/comments?post=21696"}],"version-history":[{"count":0,"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/posts\/21696\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/media?parent=21696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/categories?post=21696"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.planview.com\/wp-json\/wp\/v2\/tags?post=21696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}