{"id":15359,"date":"2023-01-29T08:33:57","date_gmt":"2023-01-29T05:33:57","guid":{"rendered":"https:\/\/kifarunix.com\/?p=15359"},"modified":"2024-03-09T23:37:32","modified_gmt":"2024-03-09T20:37:32","slug":"how-to-deploy-an-application-in-a-docker-swarm-cluster","status":"publish","type":"post","link":"https:\/\/kifarunix.com\/how-to-deploy-an-application-in-a-docker-swarm-cluster\/","title":{"rendered":"How to Deploy an Application in a Docker Swarm Cluster"},"content":{"rendered":"\n<p>How do I deploy an application to a swarm cluster? In this tutorial, you will learn how to deploy an application in a Docker swarm cluster. Normally, you would simply fire up your containerized application using <strong><code>docker run<\/code><\/strong> command and specifying related options and docker images to create the container from. However, when you are running a Docker swarm cluster, things are a little bit different.<\/p>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#deploying-an-application-in-a-docker-swarm-cluster\">Deploying an Application in a Docker Swarm Cluster<\/a><ul><li><a href=\"#setup-a-swarm-cluster\">Setup a swarm Cluster<\/a><\/li><li><a href=\"#create-docker-swarm-local-registry\">Create Docker Swarm Local Registry<\/a><\/li><li><a href=\"#deploying-application-in-a-docker-swarm\">Deploying Application in a Docker Swarm<\/a><\/li><li><a href=\"#simulate-auto-reschedule-on-node-failure\">Simulate Auto-Reschedule on Node Failure<\/a><\/li><li><a href=\"#other-tutorials\">Other Tutorials<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"deploying-an-application-in-a-docker-swarm-cluster\">Deploying an Application in a Docker Swarm Cluster<\/h2>\n\n\n\n<p>You need to create a service for the specific application you want to run as a swarm. A swarm service is a group of tasks. A task on the other hand is a running container created by a service. A task consists of the container image, command to run inside container, environment variables e.t.c.<\/p>\n\n\n\n<p>We will use one of the custom images that we created in our previous tutorial on <a href=\"https:\/\/kifarunix.com\/deploy-nagios-as-a-docker-container\/\" target=\"_blank\" rel=\"noreferrer noopener\">how to deploy Nagios as a Docker container<\/a> to deploy a swarm service<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker images<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>REPOSITORY    TAG       IMAGE ID       CREATED       SIZE\nnagios-core   4.4.9     fc672f3a3f3e   2 weeks ago   753MB<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"setup-a-swarm-cluster\">Setup a swarm Cluster<\/h3>\n\n\n\n<p>Before you can proceed, you need to have a running Docker swarm cluster.<\/p>\n\n\n\n<p>You can follow tutorial below to learn how to setup a Docker swarm cluster.<\/p>\n\n\n\n<p><a href=\"https:\/\/kifarunix.com\/how-to-setup-three-node-docker-swarm-cluster-on-ubuntu\/\" target=\"_blank\" rel=\"noreferrer noopener\">How to Setup Three Node Docker Swarm Cluster on Ubuntu 22.04<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"create-docker-swarm-local-registry\">Create Docker Swarm Local Registry<\/h3>\n\n\n\n<p>Consider the above image. It is a local image and is only available on our swarm01 manager node image cache.<\/p>\n\n\n\n<p>Thus, let&#8217;s create a local registry that can be easily accessed by other nodes on the swarm cluster. In this local registry, we will store any of our custom images we would like to use to deploy our custom applications in a Docker swarm cluster.<\/p>\n\n\n\n<p>Note that for production environment, the registry node need to be running on node separate from the swarm cluster.<\/p>\n\n\n\n<p>To create a docker swarm local registry;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service create \\\n-p 5000:5000 \\\n--mount type=bind,src=\/mnt\/local-images,dst=\/var\/lib\/registry \\\n--name registry \\\nregistry:2<\/code><\/pre>\n\n\n\n<p>So what does this command do exactly;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong>docker service create<\/strong><\/code>: Creates a new swarm service<\/li>\n\n\n\n<li><strong><code>-p 5000:5000<\/code><\/strong>: Exposes a service port on the node.<\/li>\n\n\n\n<li><strong><code>--mount type=bind,src=\/mnt\/local-images,dst=\/var\/lib\/registry<\/code><\/strong>: Attaches a filesystem mount to the service. A&nbsp;<strong>bind mount<\/strong>&nbsp;(type=bind) makes a file or directory on the host available to the service it is mounted within.\n<ul class=\"wp-block-list\">\n<li>For this type of mount (bind), the host-path must refer to an&nbsp;<em>existing<\/em>&nbsp;path on every swarm node.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong><code>--name<\/code><\/strong>: Name given to the service to be created.<\/li>\n\n\n\n<li><strong><code>registry<\/code><\/strong>: Image to be used for creating the service.<\/li>\n<\/ul>\n\n\n\n<p>Listing available services on swarm manager;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ls<\/code><\/pre>\n\n\n\n<pre class=\"scroll-sz\"><code>ID             NAME       MODE         REPLICAS   IMAGE             PORTS\nirngg0gn9pkk   registry   replicated   1\/1        registry:2   *:5000-&gt;5000\/tcp\n<\/code><\/pre>\n\n\n\n<p>So, now let&#8217;s tag and push our Nagios image, <strong><code>nagios-core:4.4.9<\/code><\/strong>, into the local registry.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker image tag nagios-core:4.4.9 localhost:5000\/nagios-core:4.4.9<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker image push localhost:5000\/nagios-core:4.4.9<\/code><\/pre>\n\n\n\n<p>All the nodes in the cluster should now have port 5000\/tcp opened and listening. And thus, they can access the local registry.<\/p>\n\n\n\n<p>You should also see the repository created on the local host mount, <strong><code>\/mnt\/local-images<\/code><\/strong>.<\/p>\n\n\n\n<p>List images in the local registry;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl localhost:5000\/v2\/_catalog<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"repositories\":&#91;\"nagios-core\"]}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"deploying-application-in-a-docker-swarm\">Deploying Application in a Docker Swarm<\/h3>\n\n\n\n<p>So the custom image is now available in our local registry<\/p>\n\n\n\n<p>We will create a Nagios server service, which will be deployed across all the nodes in the swarm cluster.<\/p>\n\n\n\n<p>Below is the command we use to create Nagios swarm service;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service create \\\n-p 80:80 \\\n--mount type=bind,src=\/opt\/nagios-core-docker\/etc,target=\/usr\/local\/nagios\/etc \\\n--name nagios-server \\\nlocalhost:5000\/nagios-core:4.4.9<\/code><\/pre>\n\n\n\n<p>As you can see above, we are mounting our Nagios configuration files under the <strong><code>\/opt\/nagios-core-docker\/etc<\/code><\/strong> directory on the Docker host into the swarm service directory, <strong><code>\/usr\/local\/nagios\/etc<\/code><\/strong>. The source configurations directory, MUST exists on all the Docker swarm nodes. Otherwise, the service will fail.<\/p>\n\n\n\n<p>Listing swarm services;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ls<\/code><\/pre>\n\n\n\n<p>Sample output;<\/p>\n\n\n\n<pre class=\"scroll-sz\"><code>ID             NAME            MODE         REPLICAS   IMAGE                              PORTS\nptcbzei0vlex   nagios-server   replicated   1\/1        localhost:5000\/nagios-core:4.4.9   *:80-&gt;80\/tcp\nirngg0gn9pkk   registry        replicated   1\/1        registry:2                         *:5000-&gt;5000\/tcp\n<\/code><\/pre>\n\n\n\n<p>As you can see from the output, the service has a single replica.<\/p>\n\n\n\n<p>List swarm service tasks;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ps nagios-server<\/code><\/pre>\n\n\n\n<pre class=\"scroll-sz\"><code>ID             NAME              IMAGE                              NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS\n2swi5yqeqwad   nagios-server.1   localhost:5000\/nagios-core:4.4.9   swarm03   Running         Running 3 minutes ago\n<\/code><\/pre>\n\n\n\n<p>The single replica is running on swarm03 node.<\/p>\n\n\n\n<p>Now, let us scale this service to 3 replicas;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service scale nagios-server=3<\/code><\/pre>\n\n\n\n<p>Output;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>nagios-server scaled to 3\noverall progress: 3 out of 3 tasks \n1\/3: running   [==================================================&gt;] \n2\/3: running   [==================================================&gt;] \n3\/3: running   [==================================================&gt;] \nverify: Service converged \n<\/code><\/pre>\n\n\n\n<p>List the services;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ls<\/code><\/pre>\n\n\n\n<pre class=\"scroll-sz\"><code>ID             NAME            MODE         REPLICAS   IMAGE                              PORTS\nptcbzei0vlex   nagios-server   <strong>replicated   3\/3<\/strong>        localhost:5000\/nagios-core:4.4.9   *:80-&gt;80\/tcp\nirngg0gn9pkk   registry        replicated   1\/1        registry:2                         *:5000-&gt;5000\/tcp\n<\/code><\/pre>\n\n\n\n<p>Again, list the nagios-server service tasks;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ps nagios-server<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>ID             NAME              IMAGE                              NODE      DESIRED STATE   CURRENT STATE            ERROR     PORTS\n2swi5yqeqwad   nagios-server.1   localhost:5000\/nagios-core:4.4.9   swarm03   Running         Running 11 minutes ago             \nte8pgkeigcdv   nagios-server.2   localhost:5000\/nagios-core:4.4.9   swarm01   Running         Running 11 seconds ago             \nlf4bj1hq1crd   nagios-server.3   localhost:5000\/nagios-core:4.4.9   swarm02   Running         Running 11 seconds ago\n<\/code><\/pre>\n\n\n\n<p>We now have our Nagios server application replicated across the three Docker swarm nodes.<\/p>\n\n\n\n<p>You can also display detailed information about a service;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service inspect nagios-server<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>[\n    {\n        \"ID\": \"ptcbzei0vlexkqzmrlvkfk1w7\",\n        \"Version\": {\n            \"Index\": 479\n        },\n        \"CreatedAt\": \"2023-01-29T12:13:33.231199034Z\",\n        \"UpdatedAt\": \"2023-01-29T12:24:26.611553811Z\",\n        \"Spec\": {\n            \"Name\": \"nagios-server\",\n            \"Labels\": {},\n            \"TaskTemplate\": {\n                \"ContainerSpec\": {\n                    \"Image\": \"localhost:5000\/nagios-core:4.4.9@sha256:63190b0c0831f5af89168948085a841f4b23d01498e9edbf4a1f4033b85f2e3a\",\n                    \"Init\": false,\n                    \"Mounts\": [\n                        {\n                            \"Type\": \"bind\",\n                            \"Source\": \"\/opt\/nagios-core-docker\/etc\",\n                            \"Target\": \"\/usr\/local\/nagios\/etc\"\n                        }\n                    ],\n                    \"StopGracePeriod\": 10000000000,\n                    \"DNSConfig\": {},\n                    \"Isolation\": \"default\"\n                },\n                \"Resources\": {\n                    \"Limits\": {},\n                    \"Reservations\": {}\n                },\n                \"RestartPolicy\": {\n                    \"Condition\": \"any\",\n                    \"Delay\": 5000000000,\n                    \"MaxAttempts\": 0\n                },\n                \"Placement\": {\n                    \"Platforms\": [\n                        {\n                            \"Architecture\": \"amd64\",\n                            \"OS\": \"linux\"\n                        }\n                    ]\n                },\n                \"ForceUpdate\": 0,\n                \"Runtime\": \"container\"\n            },\n            \"Mode\": {\n                \"Replicated\": {\n                    \"Replicas\": 3\n                }\n            },\n            \"UpdateConfig\": {\n                \"Parallelism\": 1,\n                \"FailureAction\": \"pause\",\n                \"Monitor\": 5000000000,\n                \"MaxFailureRatio\": 0,\n                \"Order\": \"stop-first\"\n            },\n            \"RollbackConfig\": {\n                \"Parallelism\": 1,\n                \"FailureAction\": \"pause\",\n                \"Monitor\": 5000000000,\n                \"MaxFailureRatio\": 0,\n                \"Order\": \"stop-first\"\n            },\n            \"EndpointSpec\": {\n                \"Mode\": \"vip\",\n                \"Ports\": [\n                    {\n                        \"Protocol\": \"tcp\",\n                        \"TargetPort\": 80,\n                        \"PublishedPort\": 80,\n                        \"PublishMode\": \"ingress\"\n                    }\n                ]\n            }\n        },\n        \"PreviousSpec\": {\n            \"Name\": \"nagios-server\",\n            \"Labels\": {},\n            \"TaskTemplate\": {\n                \"ContainerSpec\": {\n                    \"Image\": \"localhost:5000\/nagios-core:4.4.9@sha256:63190b0c0831f5af89168948085a841f4b23d01498e9edbf4a1f4033b85f2e3a\",\n                    \"Init\": false,\n                    \"Mounts\": [\n                        {\n                            \"Type\": \"bind\",\n                            \"Source\": \"\/opt\/nagios-core-docker\/etc\",\n                            \"Target\": \"\/usr\/local\/nagios\/etc\"\n                        }\n                    ],\n                    \"DNSConfig\": {},\n                    \"Isolation\": \"default\"\n                },\n                \"Resources\": {\n                    \"Limits\": {},\n                    \"Reservations\": {}\n                },\n                \"Placement\": {\n                    \"Platforms\": [\n                        {\n                            \"Architecture\": \"amd64\",\n                            \"OS\": \"linux\"\n                        }\n                    ]\n                },\n                \"ForceUpdate\": 0,\n                \"Runtime\": \"container\"\n            },\n            \"Mode\": {\n                \"Replicated\": {\n                    \"Replicas\": 1\n                }\n            },\n            \"EndpointSpec\": {\n                \"Mode\": \"vip\",\n                \"Ports\": [\n                    {\n                        \"Protocol\": \"tcp\",\n                        \"TargetPort\": 80,\n                        \"PublishedPort\": 80,\n                        \"PublishMode\": \"ingress\"\n                    }\n                ]\n            }\n        },\n        \"Endpoint\": {\n            \"Spec\": {\n                \"Mode\": \"vip\",\n                \"Ports\": [\n                    {\n                        \"Protocol\": \"tcp\",\n                        \"TargetPort\": 80,\n                        \"PublishedPort\": 80,\n                        \"PublishMode\": \"ingress\"\n                    }\n                ]\n            },\n            \"Ports\": [\n                {\n                    \"Protocol\": \"tcp\",\n                    \"TargetPort\": 80,\n                    \"PublishedPort\": 80,\n                    \"PublishMode\": \"ingress\"\n                }\n            ],\n            \"VirtualIPs\": [\n                {\n                    \"NetworkID\": \"vnw4s5xs0gr0bx19rwyy7gwea\",\n                    \"Addr\": \"10.0.0.7\/24\"\n                }\n            ]\n        }\n    }\n]\n<\/code><\/pre>\n\n\n\n<p>I am now able to access my Nagios server on any of the node in my cluster!<\/p>\n\n\n\n<div><a href=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/deploy-app-on-docker-swarm.png\" class=\"td-modal-image\"><figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1898\" height=\"865\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/deploy-app-on-docker-swarm.png\" alt=\"How to Deploy an Application in a Docker Swarm Cluster\" class=\"wp-image-15384\" title=\"\" srcset=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/deploy-app-on-docker-swarm.png?v=1674998939 1898w, https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/deploy-app-on-docker-swarm-768x350.png?v=1674998939 768w, https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/deploy-app-on-docker-swarm-1536x700.png?v=1674998939 1536w\" sizes=\"(max-width: 1898px) 100vw, 1898px\" \/><\/figure><\/a><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"simulate-auto-reschedule-on-node-failure\">Simulate Auto-Reschedule on Node Failure<\/h3>\n\n\n\n<p>What happens to the services running on one of the swarm nodes if the node goes down?<\/p>\n\n\n\n<p>Well, let us change the state of our swarm02 to drain. In drain state, a node is not accepting new tasks, but existing tasks will continue to run until completion.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker node update --availability drain swarm02<\/code><\/pre>\n\n\n\n<p>Next, check the status of the services;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> docker service ps nagios-server<\/code><\/pre>\n\n\n\n<p>See how services are rescheduled to other nodes;<\/p>\n\n\n\n<pre class=\"scroll-box\"><code>ID             NAME                  IMAGE                              NODE      DESIRED STATE   CURRENT STATE                 ERROR     PORTS\n2swi5yqeqwad   nagios-server.1       localhost:5000\/nagios-core:4.4.9   swarm03   Running         Running 33 minutes ago                  \nte8pgkeigcdv   nagios-server.2       localhost:5000\/nagios-core:4.4.9   swarm01   Running         Running 23 minutes ago                  \n<strong>dwb5m8x707ig   nagios-server.3       localhost:5000\/nagios-core:4.4.9   swarm01   Running         Running about a minute ago              \nlf4bj1hq1crd    \\_ nagios-server.3   localhost:5000\/nagios-core:4.4.9   swarm02   Shutdown        Shutdown about a minute ago  <\/strong>           \n<strong>rvofkkt34l4i   nagios-server.4       localhost:5000\/nagios-core:4.4.9   swarm03   Running         Running about a minute ago              \nd8fq6ostem99    \\_ nagios-server.4   localhost:5000\/nagios-core:4.4.9   swarm02   Shutdown        Shutdown about a minute ago  <\/strong>           \nymie19t5cqq0   nagios-server.5       localhost:5000\/nagios-core:4.4.9   swarm01   Running         Running about a minute ago              \no6m2d84dzhig   nagios-server.6       localhost:5000\/nagios-core:4.4.9   swarm03   Running         Running about a minute ago \n<\/code><\/pre>\n\n\n\n<p>Services on swarm02 node rescheduled to node 01 and 03.<\/p>\n\n\n\n<p>You can bring back up the node;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker node update --availability active swarm02<\/code><\/pre>\n\n\n\n<p>Check node status;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker node inspect swarm02 --pretty<\/code><\/pre>\n\n\n\n<pre class=\"scroll-box\"><code>ID:\t\t\tyzp9ppjxte94w3hk1bvy1bc6p\nHostname:              \tswarm02\nJoined at:             \t2023-01-28 10:57:08.345699794 +0000 utc\nStatus:\n<strong> State:\t\t\tReady\n Availability:         \tActive<\/strong>\n Address:\t\t192.168.10.20\nManager Status:\n Address:\t\t192.168.10.20:2377\n Raft Status:\t\tReachable\n Leader:\t\tNo\nPlatform:\n<\/code><\/pre>\n\n\n\n<p>So, when there are new tasks to be carried out, the node will be able to accept the instructions from the scheduler.<\/p>\n\n\n\n<p>That concludes our guide on deploying an application in a Docker swarm cluster.<\/p>\n\n\n\n<p>If you want, you can deploy the Docker visualizer. Somebody has made an opensource simple web UI application that shows basic information about nodes and containers in a Docker swarm.<\/p>\n\n\n\n<p>To deploy this visualizer on your docker swarm manager nodes;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service create \\\n--name=visualizer \\\n--publish=8180:8080 \\\n--constraint=node.role==manager \\\n--mount=type=bind,src=\/var\/run\/docker.sock,dst=\/var\/run\/docker.sock \\\ndockersamples\/visualizer<\/code><\/pre>\n\n\n\n<p>Confirm;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ls<\/code><\/pre>\n\n\n\n<pre class=\"scroll-sz\"><code>ID             NAME            MODE         REPLICAS   IMAGE                              PORTS\nptcbzei0vlex   nagios-server   replicated   6\/6        localhost:5000\/nagios-core:4.4.9   *:80-&gt;80\/tcp\nirngg0gn9pkk   registry        replicated   1\/1        registry:2                         *:5000-&gt;5000\/tcp\nz6701u6ggnty   visualizer      replicated   1\/1        dockersamples\/visualizer:latest    *:8180-&gt;8080\/tcp\n<\/code><\/pre>\n\n\n\n<p>Open port 8180 on firewall to allow you access the service externally.<\/p>\n\n\n\n<p>http:\/\/&lt;IP&gt;:8180<\/p>\n\n\n\n<div><a href=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/docker-swarm-visualizer.png\" class=\"td-modal-image\"><figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1757\" height=\"1217\" src=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/docker-swarm-visualizer.png\" alt=\"How to Deploy an Application in a Docker Swarm Cluster\" class=\"wp-image-15385\" title=\"\" srcset=\"https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/docker-swarm-visualizer.png?v=1674999084 1757w, https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/docker-swarm-visualizer-768x532.png?v=1674999084 768w, https:\/\/kifarunix.com\/wp-content\/uploads\/2023\/01\/docker-swarm-visualizer-1536x1064.png?v=1674999084 1536w\" sizes=\"(max-width: 1757px) 100vw, 1757px\" \/><\/figure><\/a><\/div>\n\n\n\n<p>And it is a wrap!<\/p>\n\n\n\n<p>Read more on deploying <a href=\"https:\/\/docs.docker.com\/engine\/swarm\/swarm-tutorial\/deploy-service\/\" target=\"_blank\" rel=\"noreferrer noopener\">docker swarm service<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"other-tutorials\">Other Tutorials<\/h3>\n\n\n\n<p><a href=\"https:\/\/kifarunix.com\/install-guacamole-as-docker-container-on-rocky-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">Install Guacamole as Docker Container on Rocky Linux<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/kifarunix.com\/install-modsecurity-3-with-apache-in-a-docker-container\/\" target=\"_blank\" rel=\"noreferrer noopener\">Install ModSecurity 3 with Apache in a Docker Container<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How do I deploy an application to a swarm cluster? In this tutorial, you will learn how to deploy an application in a Docker swarm<\/p>\n","protected":false},"author":10,"featured_media":15387,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[121,1076,1077],"tags":[6336,6334,6337,6338],"class_list":["post-15359","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howtos","category-containers","category-docker","tag-deploy-application-in-docker-swarm","tag-deploy-docker-swarm-service","tag-docker-swarm-visualizer","tag-what-do-you-create-to-deploy-an-application-image-when-docker-engine-is-in-swarm-mode","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-50","resize-featured-image"],"_links":{"self":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/15359"}],"collection":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/comments?post=15359"}],"version-history":[{"count":16,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/15359\/revisions"}],"predecessor-version":[{"id":20670,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/posts\/15359\/revisions\/20670"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media\/15387"}],"wp:attachment":[{"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/media?parent=15359"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/categories?post=15359"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kifarunix.com\/wp-json\/wp\/v2\/tags?post=15359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}