{"id":227470,"date":"2021-04-15T15:00:52","date_gmt":"2021-04-15T12:00:52","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-use-docker-app-to-containerise-an-entire-application-stack\/"},"modified":"2021-04-15T15:00:52","modified_gmt":"2021-04-15T12:00:52","slug":"how-to-use-docker-app-to-containerise-an-entire-application-stack","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-use-docker-app-to-containerise-an-entire-application-stack\/","title":{"rendered":"#How to Use Docker App to Containerise an Entire Application Stack"},"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-6a2e402774e01\" 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-6a2e402774e01\" 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\/how-to-use-docker-app-to-containerise-an-entire-application-stack\/#Why_Use_Docker_App\" >Why Use Docker App?<\/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\/how-to-use-docker-app-to-containerise-an-entire-application-stack\/#Creating_a_Docker_App_Stack\" >Creating a Docker App Stack<\/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-use-docker-app-to-containerise-an-entire-application-stack\/#Building_App_Images\" >Building App Images<\/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-use-docker-app-to-containerise-an-entire-application-stack\/#Running_App_Images\" >Running App Images<\/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-use-docker-app-to-containerise-an-entire-application-stack\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Use Docker <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> to Containerise an Entire Application Stack&#8221;<\/strong><br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9034\" src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=1200&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Docker\" width=\"1602\" height=\"902\" \/><\/p>\n<p>Docker App is an experimental Docker feature which lets you build and publish application stacks consisting of multiple containers. It aims to let you share Docker Compose stacks with the same ease of use as regular Docker containers.<\/p>\n<h2 id=\"why-use-docker-app\"><span class=\"ez-toc-section\" id=\"Why_Use_Docker_App\"><\/span>Why Use Docker App?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker App <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/docs.docker.com\/app\/working-with-app\">brings the Docker container experience<\/a> to entire application stacks. Many popular software projects now have official Docker images. They might not necessarily work as-is though: WordPress, for example, needs a database connection to run.<\/p>\n<p>Containerisation advocates the separation of each service in an app stack into its own container. A Dockerised WordPress installation should consist of a WordPress container running a web server, PHP and WordPress, and a dedicated MySQL database container.<\/p>\n<p>Running <code>docker run -d -p 80:80 wordpress:latest<\/code> isn&#8217;t sufficient to get this up-and-running. You&#8217;ll have WordPress live but no database connection. You can use Docker Compose to setup a stack with a WordPress container and a MySQL container. The onus is on you to create and maintain the Compose file, even though every user will need to do something similar.<\/p>\n<p>Docker App attempts to solve this problem. It lets you create and run &#8220;app packages&#8221; of multiple containers. These can be pushed to Docker registries in the same way as individual containers. Other users can then pull down and run your app stack without having to write their own Docker Compose file.<\/p>\n<p>Internally Docker App implements the Cloud Native Application Bundle (<a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/cnab.io\">CNAB<\/a>) specification. This is a cross-industry effort to make it simpler to define, share and install multi-container cloud native apps. It includes support for peripheral resources such as volumes and networks.<\/p>\n<p>CNAB clients like Docker App create CNAB app bundles which can be published to <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/cnab.io\/registries\">supporting registries<\/a>. A CNAB bundle is an abstraction which encapsulates multiple containers but is treated similarly to a single container when pushed to a registry.<\/p>\n<p>Docker App is currently experimental. It&#8217;s been included with the Docker CLI since version 19.03 but may change or be removed in the future. The project has changed direction in the past and its current development status <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/docker\/app\/issues\/799\">is uncertain<\/a>. Nonetheless, the version included with Docker today can already be used to distribute multi-container app stacks.<\/p>\n<h2 id=\"creating-a-docker-app-stack\"><span class=\"ez-toc-section\" id=\"Creating_a_Docker_App_Stack\"><\/span>Creating a Docker App Stack<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You can use the Docker CLI to initialise a new app stack.<\/p>\n<pre>docker app init --single-file example-app<\/pre>\n<p>This will create a new file called <code>example-app.dockerapp<\/code> in your working directory. The <code>--single-file<\/code> argument instructed Docker App to merge all the project files into the one <code>example-app.dockerapp<\/code> file. Without this argument, you&#8217;d see three separate files: <code>docker-compose.yml<\/code>, <code>metadata.yml<\/code> and <code>parameters.yml<\/code>.<\/p>\n<p>Each constituent file is represented in the merged single file as a YAML section. We&#8217;re using a single file to aid clarity in this article&#8217;s code snippets; if you&#8217;re planning a complex app stack, using multiple files will aid maintainability.<\/p>\n<p>Here&#8217;s what each of the three sections do:<\/p>\n<ul>\n<li><strong><code>docker-compose.yml<\/code><\/strong> &#8211; This is a regular Docker Compose file defining the containers which make up your app.<\/li>\n<li><strong><code>metadata.yml<\/code><\/strong> &#8211; This sets basic metadata about your app, such its name, version and description. You use this to describe your entire app stack, rather than any one container.<\/li>\n<li><strong><code>parameters.yml<\/code><\/strong> &#8211; This sets up default parameters for variables used in your Docker Compose file. Parameters are defined as simple key-value pairs. Your stack will use these default parameters unless the user overrides them with custom values.<\/li>\n<\/ul>\n<p>The only additional configuration needed beyond a regular Docker Compose file is the metadata section. If you already have a Docker Compose file, you can use <code>docker app init<\/code> with the <code>--compose-file<\/code> flag to import it:<\/p>\n<pre>docker app init --compose-file docker-compose.yml example-app<\/pre>\n<p>Update the manifest section with your app&#8217;s name, version and description. You can then proceed to run and publish your app!<\/p>\n<p>If you&#8217;ve not got a Docker Compose file ready, add some container definitions to the Compose section of the configuration now.<\/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=\"co1\"># Application services - equivalent to docker-compose.yml.<\/span>\n<span class=\"sy1\">---<\/span><span class=\"co4\">\nservices<\/span>:<span class=\"co4\">\n  apache<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>httpd:latest<span class=\"co4\">\n    ports<\/span><span class=\"sy2\">:\n<\/span>      - $<span class=\"br0\">&#123;<\/span>apache_port<span class=\"br0\">&#125;<\/span>:80<span class=\"co4\">\n  mysql<\/span>:<span class=\"co3\">\n    image<\/span><span class=\"sy2\">: <\/span>mysql:latest<span class=\"co4\">\n    ports<\/span><span class=\"sy2\">:\n<\/span>      - $<span class=\"br0\">&#123;<\/span>mysql_port<span class=\"br0\">&#125;<\/span>:3306<span class=\"co4\">\n    environment<\/span><span class=\"sy2\">:\n<\/span>      - MYSQL_ROOT_PASSWORD=$<span class=\"br0\">&#123;<\/span>mysql_root_password<span class=\"br0\">&#125;<\/span>\n<span class=\"sy1\">---<\/span>\n<span class=\"co1\"># Default application parameters - equivalent to parameters.yml.<\/span><span class=\"co3\">\napache_port<\/span><span class=\"sy2\">: <\/span>80<span class=\"co3\">\nmysql_port<\/span><span class=\"sy2\">: <\/span>3306<span class=\"co3\">\nmysql_root_password<\/span><span class=\"sy2\">: <\/span>mysql<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This simple stack creates Apache and MySQL containers. Each container needs to be configured with the host port to bind to. The MySQL container also needs a value for the <code>MYSQL_ROOT_PASSWORD<\/code> variable. This is used by MySQL during first-run to set the password for the initial <code>root<\/code> user.<\/p>\n<p>Default values for these variables are provided in the <code>parameters<\/code> section of the Docker App file. These values will be used unless you override them when spinning up your app stack.<\/p>\n<h2 id=\"building-app-images\"><span class=\"ez-toc-section\" id=\"Building_App_Images\"><\/span>Building App Images<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The next step is to build your Docker App stack into a CNAB-compliant bundle.<\/p>\n<pre>docker app build . -f example-app.dockerapp -t example-user\/example-app:latest<\/pre>\n<p>This command functions similarly to <code>docker build<\/code>. It&#8217;ll create an app bundle tagged as <code>example-user\/example-app:latest<\/code>. You can now push this bundle to Docker Hub!<\/p>\n<pre>docker app push example-user\/example-app:latest<\/pre>\n<p>You&#8217;ve successfully published your first multi-container app stack, without having to manually share a Docker Compose file.<\/p>\n<h2 id=\"running-app-images\"><span class=\"ez-toc-section\" id=\"Running_App_Images\"><\/span>Running App Images<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The final piece is to run an instance of your stack:<\/p>\n<pre>docker app run example-user\/example-app:latest --name my-app<\/pre>\n<p>Docker App will start new containers based on the definition in your app bundle. The app bundle itself will be pulled from Docker Hub if it doesn&#8217;t already exist on your machine.<\/p>\n<p>If your Compose file included resources like volumes and networks, they&#8217;ll be created and linked to the containers. The whole operation is akin to using <code>docker-compose up<\/code> without having to download the <code>docker-compose.yml<\/code> file first.<\/p>\n<p>The app will be launched with the default variables defined in its <code>parameters.yml<\/code> file. You can override any variables you need with the <code>--set<\/code> flag:<\/p>\n<pre>docker app run example-user\/example-app:latest --name my-app --set mysql_root_password=mysql<\/pre>\n<p>You can change the variables of a running app using <code>docker app update<\/code>:<\/p>\n<pre>docker app update my-app --set my_variable=new_value<\/pre>\n<p>Once an app&#8217;s running, you can use <code>docker app ls<\/code> to inspect its details. Use <code>docker app rm my-app<\/code> to destroy a specific app by its name. This will remove all the resources associated with the app.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Docker App is a promising approach to defining, sharing and running multi-container application stacks with the Docker CLI. The project implements the Cloud Native Application Bundle specification while providing a friendly abstracted interface to users.<\/p>\n<p>Adoption of Docker App is likely to remain low until its status in the Docker ecosystem has been confirmed. If it graduates from its experimental position, Docker App should fill the gap between single-container registries and complex cloud native deployment solutions such as <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/helm.sh\">Helm<\/a>.<\/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.cloudsavvyit.com\/10673\/how-to-use-docker-app-to-containerise-an-entire-application-stack\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Use Docker App to Containerise an Entire Application Stack&#8221; Docker App is an experimental Docker feature which lets you build and publish application stacks consisting of multiple containers. It aims to let you share Docker Compose stacks with the same ease of use as regular Docker containers. Why Use Docker App? Docker App&#8230;<\/p>\n","protected":false},"author":1,"featured_media":227471,"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?width=1200&trim=1,1&bg-color=000&pad=1,1","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-227470","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\/227470","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=227470"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/227470\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/227471"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=227470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=227470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=227470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}