{"id":467994,"date":"2022-06-26T18:03:56","date_gmt":"2022-06-26T15:03:56","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-run-multiple-services-in-one-docker-container\/"},"modified":"2022-06-26T18:03:56","modified_gmt":"2022-06-26T15:03:56","slug":"how-to-run-multiple-services-in-one-docker-container","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-run-multiple-services-in-one-docker-container\/","title":{"rendered":"#How to Run Multiple Services In One Docker Container"},"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-6a2b57d458998\" 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-6a2b57d458998\" 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-run-multiple-services-in-one-docker-container\/#%E2%80%9CHow_to_Run_Multiple_Services_In_One_Docker_Container%E2%80%9D\" >&#8220;How to Run Multiple Services In One Docker Container&#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-run-multiple-services-in-one-docker-container\/#Identifying_the_Problem\" >Identifying the Problem<\/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-run-multiple-services-in-one-docker-container\/#Wrapping_Multiple_Processes_in_One_Entrypoint\" >Wrapping Multiple Processes in One Entrypoint<\/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-run-multiple-services-in-one-docker-container\/#The_-init_Container_Option\" >The --init Container Option<\/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-run-multiple-services-in-one-docker-container\/#Using_a_Dedicated_Process_Manager\" >Using a Dedicated Process Manager<\/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\/how-to-run-multiple-services-in-one-docker-container\/#When_Should_You_Run_Multiple_Processes_In_a_Container\" >When Should You Run Multiple Processes In a Container?<\/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\/how-to-run-multiple-services-in-one-docker-container\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CHow_to_Run_Multiple_Services_In_One_Docker_Container%E2%80%9D\"><\/span>&#8220;How to Run Multiple Services In One Docker Container&#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-10864\" data-pagespeed-no-defer=\"\" src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/csit\/2021\/04\/075c8694.jpeg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Illustration showing the Docker logo\" width=\"1600\" height=\"900\"\/><\/p>\n<p>Docker is a <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/technology\/\" data-internallinksmanager029f6b8e52c=\"4\" title=\"Technology\" target=\"_blank\" rel=\"noopener\">technology<\/a> for packaging components of your stack as isolated containers. It\u2019s common practice to run each of your processes in its own container, creating a clean divide between components. This enhances modularity and lets you access the scalability benefits of containerization.<\/p>\n<p>There can still be situations where you want to run multiple services within a single container. While this doesn\u2019t come naturally in the Docker ecosystem, we\u2019ll show a few different <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>roaches you can use to create containers with more than one long-lived process.<\/p>\n<h2 id=\"identifying-the-problem\"><span class=\"ez-toc-section\" id=\"Identifying_the_Problem\"><\/span>Identifying the Problem<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker containers run a single foreground process. This is defined by the image\u2019s <code>ENTRYPOINT<\/code> and <code>CMD<\/code> instructions. <code>ENTRYPOINT<\/code> is set within an image\u2019s <code>Dockerfile<\/code> while <code>CMD<\/code> can be overridden when creating containers. Containers automatically stop when their foreground process exits.<\/p>\n<p>You can launch other processes from the <code>CMD<\/code> but the container will only stay running while the original foreground process is alive. Keeping the container operational through the combined lifespan of two independent services isn\u2019t directly possible using the <code>ENTRYPOINT\/CMD<\/code> mechanism.<\/p>\n<h2 id=\"wrapping-multiple-processes-in-one-entrypoint\"><span class=\"ez-toc-section\" id=\"Wrapping_Multiple_Processes_in_One_Entrypoint\"><\/span>Wrapping Multiple Processes in One Entrypoint<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Wrapper scripts are the simplest solution to the problem. You can write a script that starts all your processes and waits for them to finish. Setting the script as your Docker <code>ENTRYPOINT<\/code> will run it as the container\u2019s foreground process, keeping the container running until one of the wrapped scripts exits.<\/p>\n<pre>#!\/bin\/bash&#13;\n&#13;\n\/opt\/first-process &amp;&#13;\n&#13;\n\/opt\/second-process &amp;&#13;\n&#13;\nwait -n&#13;\n&#13;\nexit $?<\/pre>\n<p>This script starts the <code>\/opt\/first-process<\/code> and <code>\/opt\/second-process<\/code> binaries inside the container. The use of <code>&amp;<\/code> allows the script to continue without waiting for each process to exit. <code>wait<\/code> is used to suspend the script until one of the processes does terminate. The script then exits with the status code issued by the finished script.<\/p>\n<p>This model results in the container running both <code>first-process<\/code> and <code>second-process<\/code> until one of them exits. At that point, the container will stop, even though the other process may still be running.<\/p>\n<p>To use this script, modify your Docker image\u2019s <code>ENTRYPOINT<\/code> and <code>CMD<\/code> to make it the container\u2019s foreground process:<\/p>\n<pre>ENTRYPOINT [\"\/bin\/sh\"]&#13;\nCMD [\".\/path\/to\/script.sh\"]<\/pre>\n<h2 id=\"the---init-container-option\"><span class=\"ez-toc-section\" id=\"The_-init_Container_Option\"><\/span>The <code>--init<\/code> Container Option<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>One challenge with managing container processes is effectively cleaning up as they exit. Docker runs your <code>CMD<\/code> as process ID 1, making it responsible for handling signals and eliminating zombies. If your script doesn\u2019t have these capabilities, you could end up with orphaned child processes persisting inside your container.<\/p>\n<p>The <code>docker run<\/code> command has <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/config\/containers\/multi-service_container\/\">an <code>--init<\/code> flag<\/a> that modifies the entrypoint to use <code>tini<\/code> as PID 1. This is a minimal init process implementation which runs your <code>CMD<\/code>, handles signal forwarding, and continually reaps zombies.<\/p>\n<p>It\u2019s worthwhile using <code>--init<\/code> if you expect to be spawning many processes and don\u2019t want to manually handle the clean-up. <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/krallin\/tini\">Tini is a<\/a> lightweight init flavor that\u2019s designed for containers. It\u2019s much smaller than fully fledged alternatives like <code>systemd<\/code> and <code>upstart<\/code>.<\/p>\n<h2 id=\"using-a-dedicated-process-manager\"><span class=\"ez-toc-section\" id=\"Using_a_Dedicated_Process_Manager\"><\/span>Using a Dedicated Process Manager<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Manual scripting quickly becomes sub-optimal when you\u2019ve got a lot of processes to manage. Adopting a process manager is another way to run several services inside your Docker containers. The process manager becomes your <code>ENTRYPOINT<\/code> and has responsibility for starting, maintaining, and cleaning up after your worker processes.<\/p>\n<p>There are several options available when implementing this approach. <code>supervisord<\/code> is a popular choice which is easily configured via an <code>\/etc\/supervisor\/conf.d\/supervisord.conf<\/code> file:<\/p>\n<pre>[program:apache2]&#13;\ncommand=\/usr\/sbin\/apache2 -DFOREGROUND&#13;\n&#13;\n[program:mysqld]&#13;\ncommand=\/usr\/sbin\/mysqld_safe<\/pre>\n<p>This config file configures <code>supervisord<\/code> to start Apache and MySQL. To use it in a Docker container, add all the required packages to your image, then copy your <code>supervisord<\/code> config file to the correct location. Set <code>supervisord<\/code> as the image\u2019s <code>CMD<\/code> to run it automatically when containers start.<\/p>\n<pre>FROM ubuntu:latest&#13;\nRUN apt-get install -y apache2 mysql-server supervisor&#13;\nCOPY supervisord.conf \/etc\/supervisor\/conf.d\/supervisord.conf&#13;\nENTRYPOINT [\"\/bin\/sh\"]&#13;\nCMD [\"\/usr\/bin\/supervisord\"]<\/pre>\n<p>Because <code>supervisord<\/code> runs continually, it\u2019s not possible to stop the container when one of your monitored processes exits. An alternative option is <code>s6-overlay<\/code> which does have this capability. It uses a declarative service model where you place service scripts directly into <code>\/etc\/services.d<\/code>:<\/p>\n<pre># Add s6-overlay to your image&#13;\nADD https:\/\/github.com\/just-containers\/s6-overlay\/releases\/download\/v3.1.0.0\/s6-overlay-noarch.tar.xz \/tmp&#13;\nRUN tar -C \/ -Jxpf \/tmp\/s6-overlay-noarch.tar.xz&#13;\n&#13;\nRUN printf \"#!\/bin\/shn\/usr\/sbin\/apache2 -DFOREGROUND\" &gt; \/etc\/services.d\/first-service\/run&#13;\nRUN chmod +x \/etc\/services.d\/first-service\/run&#13;\n&#13;\n# Use s6-overlay as your image's entrypoint&#13;\nENTRYPOINT [\"\/init\"]<\/pre>\n<p>You can add an executable <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/just-containers\/s6-overlay#setting-the-exit-code-of-the-container-to-the-exit-code-of-your-main-service\"><code>finish<\/code> script<\/a> within your service directories to handle stopping the container with <code>docker stop<\/code>. <code>s6-overlay<\/code> will automatically run these scripts when its process receives a <code>TERM<\/code> signal due to the <code>stop<\/code> command.<\/p>\n<p>Finish scripts receive the exit code of their service as their first argument. The code is set to 256 when the service is killed due to an uncaught signal. The script needs to write the final exit code to <code>\/run\/s6-linux-init-container-results\/exitcode<\/code>; s6-overlay reads this file and exits with the value within, causing that code to be used as your container\u2019s stop code.<\/p>\n<pre>#!\/bin\/sh&#13;\necho \"$1\" &gt; \/run\/s6-linux-init-container-results\/exitcode<\/pre>\n<h2 id=\"when-should-you-run-multiple-processes-in-a-container\"><span class=\"ez-toc-section\" id=\"When_Should_You_Run_Multiple_Processes_In_a_Container\"><\/span>When Should You Run Multiple Processes In a Container?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This technique is best used with tightly coupled processes that you can\u2019t separate to run as independent containers. You might have a program that relies on a background helper utility or a monolithic application that performs its own management of individual processes. The techniques shown above can help you containerize these types of software.<\/p>\n<p>Running multiple processes in a container should still be avoided wherever possible. Sticking to a single foreground process maximizes isolation, prevents components interfering with each other, and improves your ability to debug and test specific pieces. You can scale components individually using container orchestrators, giving you the flexibility to run more instances of your most resource-intensive processes.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Containers usually have one foreground process and run for as long as it\u2019s alive. This model aligns with containerization best practices and lets you glean the most benefits from the technology.<\/p>\n<p>In some situations you might need multiple processes to run in a container. As all images ultimately have a single entrypoint, you must write a wrapper script or add a process manager that takes responsibility for starting your target binaries.<\/p>\n<p>Process managers give you everything you need but bloat your images with extra packages and configuration. Wrapper scripts are simpler but may need to be paired with Docker\u2019s <code>--init<\/code> flag to prevent zombie process proliferation.<\/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-run-multiple-services-in-one-docker-container\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;How to Run Multiple Services In One Docker Container&#8221; Docker is a technology for packaging components of your stack as isolated containers. It\u2019s common practice to run each of your processes in its own container, creating a clean divide between components. This enhances modularity and lets you access the scalability benefits of containerization. There can&#8230;<\/p>\n","protected":false},"author":1,"featured_media":467995,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.howtogeek.com\/wp-content\/uploads\/csit\/2021\/04\/075c8694.jpeg?height=200p&trim=2,2,2,2","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-467994","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\/467994","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=467994"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/467994\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/467995"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=467994"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=467994"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=467994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}