{"id":10735,"date":"2014-03-11T14:48:24","date_gmt":"2014-03-11T13:48:24","guid":{"rendered":"https:\/\/blog.trifork.com\/?p=10735"},"modified":"2014-03-11T14:48:24","modified_gmt":"2014-03-11T13:48:24","slug":"using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/","title":{"rendered":"Using Supervisor with Docker to manage processes (supporting image inheritance)"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" style=\"float: left;margin: 10px 25px 20px 0\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png\" alt=\"Docker-logo\" width=\"250\" height=\"208\"><\/p>\n<p>In August I wrote a <a title=\"Using Docker to efficiently create multiple tomcat instances\" href=\"https:\/\/blog.trifork.com\/2013\/08\/15\/using-docker-to-efficiently-create-multiple-tomcat-instances\/\">blog post<\/a> on the creation of tomcat images. Since then, Docker has evolved much, and so has my own knowledge of it. I&#8217;d like to update you on what I found to be a good way to manage container processes. After reading this article, I hope you will find good use of the Supervisor image that you can find in <a href=\"https:\/\/github.com\/Krijger\/docker-cookbooks\">my repository on github<\/a>.<\/p>\n<h2>The Docker command<\/h2>\n<p>One of the points that came up in aforementioned post was that Docker (only) supports running a single foreground process. We are generally accustomed to something like upstart to have services be initialized at start up, but Docker does not run anything by default, which may be somewhat unexpected if you start out with Docker. <!--more--> You have to specify the proces you want to run. This behavior is contrary to that of a virtual machine an the advantage is that this keeps the container as lightweight as possible. You can start the container specifying the command option at the end of the run command, e.g,<\/p>\n<p><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">docker run ubuntu echo &quot;hello world&quot;<\/pre><\/p>\n<p>Alternatively, you can use the <a href=\"http:\/\/docs.docker.io\/en\/latest\/reference\/builder\/#cmd\">CMD<\/a> directive in a Dockerfile to have Docker run a command by default. E.g. if you build the image <code>hello_world_printer<\/code> using<\/p>\n<p><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">docker build -t &quot;hello_world_printer&quot; .<\/pre><\/p>\n<p>from the directory containing the Dockerfile<\/p>\n<p><pre class=\"brush: plain; title: Dockerfile; notranslate\" title=\"Dockerfile\">&lt;br&gt;\nFROM ubuntu&lt;br&gt;\nCMD echo &quot;hello world&quot;&lt;br&gt;\n<\/pre><\/p>\n<p>you would achieve &nbsp;exactly the same by running<\/p>\n<p><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">docker run hello_world_printer<\/pre><\/p>\n<p>Note that, since you can override the CMD directive command line, this really is a run time directive. Fun fact is that on a Linux container you could just invoke upstart and get much of the same behavior as a regular virtual machine.<\/p>\n<h2>Running multiple commands<\/h2>\n<p>A common wish is to run multiple processes. E.g. an ssh server (to be able to connect to the running container) and your actual application. You <em>could<\/em> run the container with something like<\/p>\n<p><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">docker run ... \/usr\/sbin\/sshd &amp;amp;amp;&amp;amp;amp; run_your_app_in_foreground<\/pre><\/p>\n<p>which might come in handy during development. Now, when the application process quits, the container is automatically shut down since that was our only foreground process. While you can fix that using <code>\/usr\/bin\/sshd -D<\/code> the important point here is that setting up the initialization in the run command is not very neat. And, when your container becomes more complicated, the run command tends to grow.<\/p>\n<p>So, to run more complicated containers, many people use complicated bash scripts. The bash script typically runs a foreground process and often spawns one or more (renegade) daemon processes. A major improvement of this approach over only using the Docker CLI is that the bash scripts are source controlled: the start-up scripts live in your Docker image, which is the new deliverable of you software project. Still, managing processes in bash scripts is simply no fun at all and prone to errors.<\/p>\n<h2>&#8230; using Supervisor<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"float: left;margin: 10px 25px 20px 0\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2014\/01\/logo_supervisor.gif\" alt=\"Supervisor-logo\" width=\"201\" height=\"60\"><br \/>\nA better way is to use <a href=\"http:\/\/supervisord.org\/\">Supervisor<\/a>. Supervisor allows for better control of our processes: it is very simple and clear code; it can restart processes after a crash; it allows for restartable process groups and a command line or web interface to manage processes. Of course, with great power comes great responsibility: extensively using Supervisor features is a code smell indicating that you might be better off chopping up your image into several smaller ones.<\/p>\n<p>Personally, I like how Supervisor allows me to cleanly code the process start-up. The clearest use case as I see it arises when child images expand the process set. For instance, if you often use SSH, it might be logical to have an SSH base image. In that case, implementing start-up of the SSH daemon in all the extending images is a form of code duplication. I&#8217;ll now show you what I found to be a good way to approach this.<\/p>\n<h2>The Supervisor base image<\/h2>\n<p>First of all, since I am now using Supervisor by default all my images extend from a base image containing only Supervisor and an updated version of Ubuntu. You can find the Dockerfile <a href=\"https:\/\/github.com\/Krijger\/docker-cookbooks\/blob\/master\/supervisor\/Dockerfile\">here<\/a>. This base image contains a configuration file \/etc\/supervisor.conf:<\/p>\n<p><pre class=\"brush: plain; title: supervisor.conf; notranslate\" title=\"supervisor.conf\">&lt;br&gt;\n&#x5B;supervisord]&lt;br&gt;\nnodaemon=true&lt;\/p&gt;\n&lt;p&gt;&#x5B;include]&lt;br&gt;\nfiles = \/etc\/supervisor\/conf.d\/*.conf&lt;br&gt;\n<\/pre><\/p>\n<p>This configuration makes Supervisor itself run as a foreground process, which will keep our containers up and running. Secondly, it includes all <code>conf<\/code> files in the <code>\/etc\/supervisor\/conf.d\/<\/code> directory, starting whatever programs are defined in there.<\/p>\n<h2>Extending the base image<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"float: right;margin: 10px 0 20px 25px\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2014\/02\/tomcat-stack-164x300.png\" alt=\"tomcat-stack\" width=\"164\" height=\"300\"><\/p>\n<p>So, the idea is simple. All child containers add their service to the supervisor configuration by adding their specific <code>service.sv.conf<\/code> to the specified directory. Then, starting the container using\n<\/p><div style=\"width: 375px\">\n<p><pre class=\"brush: bash; title: ; notranslate\" title=\"\">docker run child_image_name &quot;supervisor -c \/etc\/supervisor.conf&quot;<\/pre><\/p>\n<\/div>\n<p>automatically starts all the specified processes. You can extend the image with multiple layers, each time having the option of adding one or more services to the configuration directory. Effectively, the Supervisor start command replaces upstart in a Docker compliant fashion.<\/p>\n<p>As an example, let&#8217;s take a look at the Tomcat stack from aforementioned blog post, which is now updated.<\/p>\n<ol>\n<li>Firstly, as discussed, we have the Supervisor base image extending from Ubuntu<\/li>\n<li>Then, we have a&nbsp;<a href=\"https:\/\/github.com\/Krijger\/docker-cookbooks\/tree\/master\/jdk7-oracle\">JDK image<\/a>, which installs Java on top of Supervisor. Java is just a library for other services, so we do not define a service in this layer. Common tasks as setting the JAVA_HOME environment variable are the responsibility of this layer.<\/li>\n<li>The Tomcat image install Tomcat onto the stack and exposes port 8080. This layer does include a service, namely Tomcat, which is defined in <a href=\"https:\/\/github.com\/Krijger\/docker-cookbooks\/blob\/master\/tomcat7\/tomcat.sv.conf\">tomcat.sv.conf<\/a>:<pre class=\"brush: plain; title: tomcat.sv.conf; notranslate\" title=\"tomcat.sv.conf\">&lt;br&gt;\n&#x5B;program:webapp]&lt;br&gt;\ncommand=\/bin\/bash -c &quot;env &amp;amp;gt; \/tmp\/tomcat.env &amp;amp;amp;&amp;amp;amp; cat \/etc\/default\/tomcat7 &amp;amp;gt;&amp;amp;gt; \/tmp\/tomcat.env &amp;amp;amp;&amp;amp;amp; mv \/tmp\/tomcat.env \/etc\/default\/tomcat7 &amp;amp;amp;&amp;amp;amp; service tomcat7 start&quot;&lt;br&gt;\nredirect_stderr=true&lt;br&gt;\n<\/pre><p><\/p>\n<p>The run command for the Tomcat service is not as clean as I&#8217;d like it to be and could very well be put in a dedicated script. What it does is prepending the environment variables, such as <a href=\"http:\/\/docs.docker.io\/en\/latest\/use\/working_with_links_names\/\">container linking<\/a> parameters, to <code>\/etc\/default\/tomcat7<\/code>, so we can use those in following configuration lines as in the following example. It might be more neat to use an available key-value store such as etcd, but that is beyond the scope of this article.<br \/>\nOf course, we only have the default installation files in here, and no actual web application yet.<\/p><\/li>\n<li>Your web application would extend Tomcat with an actual application installation. When starting Supervisor, it will automatically start Tomcat.<\/li>\n<\/ol>\n<h2>Example Tomcat webapp Dockerfile<\/h2>\n<p>An actual web application installation is beyond the scope of this article, but as a finishing touch, let me give a partial example Dockerfile of how to use this stack. This example is pretty Java Tomcat specific, so if you&#8217;re not interested in that, stop reading now and have fun with other stuff \ud83d\ude42<\/p>\n<p>Suppose, we have a web app that uses Elasticsearch:<\/p>\n<p><pre class=\"brush: plain; title: ; notranslate\" title=\"\">&lt;br&gt;\nFROM quintenk\/tomcat:7&lt;\/p&gt;\n&lt;p&gt;# Install dependencies for project that do not change per check-in&lt;br&gt;\n# RUN apt-get -y install ...&lt;\/p&gt;\n&lt;p&gt;RUN rm -rf \/var\/lib\/tomcat7\/webapps\/*&lt;\/p&gt;\n&lt;p&gt;# append configuration to \/etc\/default\/tomcat7, such as:&lt;br&gt;\n...&lt;br&gt;\nRUN echo 'DOCKER_OPTS=&quot;-DELASTICSEARCH_SERVER_URL=${ELASTICSEARCH_PORT_9200_TCP_ADDR}&quot;' &amp;amp;gt;&amp;amp;gt; \/etc\/default\/tomcat7&lt;br&gt;\nRUN echo 'CATALINA_OPTS=&quot;... ${DOCKER_OPTS}&quot;' &amp;amp;gt;&amp;amp;gt; \/etc\/default\/tomcat7&lt;\/p&gt;\n&lt;p&gt;# add configuration files such as log4j.properties and chown root:tomcat7 them&lt;\/p&gt;\n&lt;p&gt;# Assume the project has been built and that ROOT.war is in our Docker build directory (containing the Dockerfile). For caching purposes, add this as one of the last steps&lt;br&gt;\nADD ROOT.war \/var\/lib\/tomcat7\/webapps\/&lt;br&gt;\nRUN chown root:tomcat7 \/var\/lib\/tomcat7\/webapps\/ROOT.war&lt;\/p&gt;\n&lt;p&gt;CMD supervisord -c \/etc\/supervisor.conf&lt;br&gt;\n<\/pre><\/p>\n<p>In this code, the variables for elasticsearch (a search index), are set because the Supervisor configuration for Tomcat prepends all variables to the <code>\/etc\/default\/tomcat7<\/code> file at start-up time. Of course, we would need to start the webapp with a link to the elasticsearch container: e.g.<\/p>\n<p><pre class=\"brush: bash; gutter: false; title: ; notranslate\" title=\"\">docker run -link name_of_elasticsearch_instance:elasticsearch -d name_of_webapp_image &quot;supervisor -c \/etc\/supervisor.conf&quot;<\/pre><\/p>\n<p>You now end up with a web application that has access to the ELASTICSEARCH_SERVER_URL. You can use this in a properties file like<\/p>\n<p><pre class=\"brush: plain; gutter: false; title: ; notranslate\" title=\"\">elastic.unicast.hosts=${ELASTICSEARCH_SERVER_URL}<\/pre><\/p>\n<p>which exposes the property to your application. If you are a Java developer and have read through the last section as well, this is the time where I wish you happy coding!<\/p>\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/bit.ly\/3BAo305\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"256\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-1024x256.png\" alt=\"\" class=\"wp-image-20303\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-1024x256.png 1024w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-300x75.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-768x192.png 768w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-1536x384.png 1536w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-2048x512.png 2048w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/02\/Blog-Banner-1-1920x480.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In August I wrote a blog post on the creation of tomcat images. Since then, Docker has evolved much, and so has my own knowledge of it. I&#8217;d like to update you on what I found to be a good way to manage container processes. After reading this article, I hope you will find good [&hellip;]<\/p>\n","protected":false},"author":96,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[88,105,10],"tags":[362,86,104,363,216],"class_list":["post-10735","post","type-post","status-publish","format-standard","hentry","category-devops","category-docker-2","category-development","tag-container","tag-devops","tag-docker","tag-supervisor","tag-tomcat"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using Supervisor with Docker to manage processes (supporting image inheritance) - Trifork 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:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Supervisor with Docker to manage processes (supporting image inheritance) - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"In August I wrote a blog post on the creation of tomcat images. Since then, Docker has evolved much, and so has my own knowledge of it. I&#8217;d like to update you on what I found to be a good way to manage container processes. After reading this article, I hope you will find good [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-03-11T13:48:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png\" \/>\n<meta name=\"author\" content=\"Quinten Krijger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Quinten Krijger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/\",\"url\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/\",\"name\":\"Using Supervisor with Docker to manage processes (supporting image inheritance) - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png\",\"datePublished\":\"2014-03-11T13:48:24+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/b2ec66380e0b7928cf65435b1a0de4a9\"},\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#primaryimage\",\"url\":\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png\",\"contentUrl\":\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Supervisor with Docker to manage processes (supporting image inheritance)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/b2ec66380e0b7928cf65435b1a0de4a9\",\"name\":\"Quinten Krijger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1355ede8846f168a19eb9b316834d945?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1355ede8846f168a19eb9b316834d945?s=96&d=mm&r=g\",\"caption\":\"Quinten Krijger\"},\"url\":\"https:\/\/trifork.nl\/blog\/author\/quintenk\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using Supervisor with Docker to manage processes (supporting image inheritance) - Trifork 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:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/","og_locale":"en_US","og_type":"article","og_title":"Using Supervisor with Docker to manage processes (supporting image inheritance) - Trifork Blog","og_description":"In August I wrote a blog post on the creation of tomcat images. Since then, Docker has evolved much, and so has my own knowledge of it. I&#8217;d like to update you on what I found to be a good way to manage container processes. After reading this article, I hope you will find good [&hellip;]","og_url":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/","og_site_name":"Trifork Blog","article_published_time":"2014-03-11T13:48:24+00:00","og_image":[{"url":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png","type":"","width":"","height":""}],"author":"Quinten Krijger","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Quinten Krijger","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/","url":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/","name":"Using Supervisor with Docker to manage processes (supporting image inheritance) - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#primaryimage"},"image":{"@id":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#primaryimage"},"thumbnailUrl":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png","datePublished":"2014-03-11T13:48:24+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/b2ec66380e0b7928cf65435b1a0de4a9"},"breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#primaryimage","url":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png","contentUrl":"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2013\/08\/Docker-logo.png"},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Supervisor with Docker to manage processes (supporting image inheritance)"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/b2ec66380e0b7928cf65435b1a0de4a9","name":"Quinten Krijger","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1355ede8846f168a19eb9b316834d945?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1355ede8846f168a19eb9b316834d945?s=96&d=mm&r=g","caption":"Quinten Krijger"},"url":"https:\/\/trifork.nl\/blog\/author\/quintenk\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/10735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/96"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=10735"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/10735\/revisions"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=10735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=10735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=10735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}