{"id":765,"date":"2020-07-11T09:21:56","date_gmt":"2020-07-11T09:21:56","guid":{"rendered":"https:\/\/blog.samarthya.me\/wps\/?p=765"},"modified":"2020-07-13T11:02:03","modified_gmt":"2020-07-13T11:02:03","slug":"docker-ubuntu-a-refresher","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2020\/07\/11\/docker-ubuntu-a-refresher\/","title":{"rendered":"Docker &#8211; Ubuntu a refresher"},"content":{"rendered":"<p>Usually I use Centos, but this time I wanted to try out docker swarm and ubuntu was the preferred option due to the options and supporting blogs available.<\/p>\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Do read &#8211; https:\/\/docs.docker.com\/get-started\/#containers-and-virtual-machines<\/p><cite>docker.com<\/cite><\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/docs.docker.com\/images\/Container%402x.png\" width=\"928\" height=\"832\"><\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1<\/h3>\n\n\n\n<p>Updating the system and installing required dependencies<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt-get update\n\nsudo apt-get -y install \\\n  apt-transport-https \\\n  ca-certificates \\\n  curl \\\n  gnupg-agent \\\n  software-properties-common<\/code><\/pre>\n\n\n\n<p>The version of Ubuntu I am using is as under<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> cat \/etc\/issue\nUbuntu 18.04.4 LTS \\n \\l<\/code><\/pre>\n\n\n\n<p>Add the GPG key and repository.  Finally install docker <code>community edition<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg | sudo apt-key add -\n\nsudo apt-key fingerprint 0EBFCD88\n\nsudo add-apt-repository \\\n   \"deb &#91;arch=amd64] https:\/\/download.docker.com\/linux\/ubuntu \\\n   $(lsb_release -cs) \\\n   stable\"\n\nsudo apt-get update\n\nsudo apt-get install -y docker-ce=5:18.09.5~3-0~ubuntu-bionic docker-ce-cli=5:18.09.5~3-0~ubuntu-bionic containerd.io<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker info\nContainers: 0\n Running: 0\n Paused: 0\n Stopped: 0\nImages: 0\nServer Version: 18.09.5\nStorage Driver: overlay2\n Backing Filesystem: extfs\n Supports d_type: true\n Native Overlay Diff: true\nLogging Driver: json-file\nCgroup Driver: cgroupfs\nPlugins:\n Volume: local\n Network: bridge host macvlan null overlay\n Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog\nSwarm: inactive\nRuntimes: runc\nDefault Runtime: runc\nInit Binary: docker-init\ncontainerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429\nrunc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd\ninit version: fec3683\nSecurity Options:\n apparmor\n seccomp\n  Profile: default\nKernel Version: 5.3.0-1023-aws\nOperating System: Ubuntu 18.04.4 LTS\nOSType: linux\nArchitecture: x86_64\nCPUs: 2\nTotal Memory: 3.798GiB\nName: samarthya2c.mylabserver.com\nID: R4OG:F2YR:VRTY:XFRM:4QXX:JWN6:Y2YS:OA5M:7YCJ:OMFR:BXP5:HKXO\nDocker Root Dir: \/var\/lib\/docker\nDebug Mode (client): false\nDebug Mode (server): false\nRegistry: https:\/\/index.docker.io\/v1\/\nLabels:\nExperimental: false\nInsecure Registries:\n 127.0.0.0\/8\nLive Restore Enabled: false\nProduct License: Community Engine\n\nWARNING: No swap limit support<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><code>docker version<\/code><\/h2>\n\n\n\n<p>Now time to check the version. <code>docker version<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nClient:\n Version:           18.09.5\n API version:       1.39\n Go version:        go1.10.8\n Git commit:        e8ff056\n Built:             Thu Apr 11 04:43:57 2019\n OS\/Arch:           linux\/amd64\n Experimental:      false\n\nServer: Docker Engine - Community\n Engine:\n  Version:          18.09.5\n  API version:      1.39 (minimum version 1.12)\n  Go version:       go1.10.8\n  Git commit:       e8ff056\n  Built:            Thu Apr 11 04:10:53 2019\n  OS\/Arch:          linux\/amd64\n  Experimental:     false\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2<\/h3>\n\n\n\n<p>Time to install docker swarm. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker swarm init<\/code><\/pre>\n\n\n\n<p>On the machine that you use the command above it will be the designated swarm manager.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Options &#8211; For Init<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>docker swarm init --help\n\nUsage:\tdocker swarm init &#91;OPTIONS]\n\nInitialize a swarm\n\nOptions:\n      --advertise-addr string                  Advertised address (format: &lt;ip|interface>&#91;:port])\n      --autolock                               Enable manager autolocking (requiring an unlock key to start a stopped manager)\n      --availability string                    Availability of the node (\"active\"|\"pause\"|\"drain\") (default \"active\")\n      --cert-expiry duration                   Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)\n      --data-path-addr string                  Address or interface to use for data path traffic (format: &lt;ip|interface>)\n      --default-addr-pool ipNetSlice           default address pool in CIDR format (default &#91;])\n      --default-addr-pool-mask-length uint32   default address pool subnet mask length (default 24)\n      --dispatcher-heartbeat duration          Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)\n      --external-ca external-ca                Specifications of one or more certificate signing endpoints\n      --force-new-cluster                      Force create a new cluster from current state\n      --listen-addr node-addr                  Listen address (format: &lt;ip|interface>&#91;:port]) (default 0.0.0.0:2377)\n      --max-snapshots uint                     Number of additional Raft snapshots to retain\n      --snapshot-interval uint                 Number of log entries between Raft snapshots (default 10000)\n      --task-history-limit int                 Task history retention limit (default 5)<\/code><\/pre>\n\n\n\n<p>If you are deploying it on a cloud or a hosted VM, you need to be cautious of which ports are accessible to the nodes who will be joining in the swarm.<\/p>\n\n\n\n<p>For my case I have a <code>public<\/code> and <code>private<\/code> <strong>ip<\/strong> that my machine has, and I will be using the private ip for the option <code>--advertise-addr<\/code> and that has no restrictions in terms of port.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker swarm init --advertise-addr 172.31.0.1\nSwarm initialized: current node (a0zuhhhc0mjnm322gadntwsrwe) is now a manager.\n\nTo add a worker to this swarm, run the following command:\n\n    docker swarm join --token SWMTKN-1-417pmtvy5vtzui4lmf023jhr4q50tekzzgsf8evgy4emtykvs4-exobuyup2mro23r32aursfzxw 172.31.0.1:2377\n\nTo add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.<\/code><\/pre>\n\n\n\n<p><code>docker info<\/code> should return some information about the swarm<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Swarm: active\n NodeID: a0zuhhhc0mjnm322gadntwsrwe\n Is Manager: true\n ClusterID: uym09dgerjhhkasf\n Managers: 1\n Nodes: 1\n Default Address Pool: 100.0.0.0\/8  <\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Namespace isolation provides a secure environment.<\/p><cite>linux<\/cite><\/blockquote>\n\n\n\n<p><code>docker node ls<\/code> is another command that can be used to see the nodes in the swarm.<\/p>\n\n\n\n<p>Once the docker swarm manager is ready you can add  slave nodes to the swarm.<\/p>\n\n\n\n<p>In the slave nodes wherever we have deployed docker and is supposed to work as the slave node, you need to fire the command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker swarm join --token SWMTKN-1-417pmtvy5vtzui4lmf023jhr4q50tekzzgsf8evgy4emtykvs4-exobuyup2mro23r32aursfzxw 172.31.0.1:2377<\/code><\/pre>\n\n\n\n<p>If it is successful, the following output will be shown.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>This node joined a swarm as a worker<\/code><\/pre>\n\n\n\n<p>If you run <code>docker node ls<\/code> again, you will be see the nodes in the swarm<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker node ls\nID                            HOSTNAME                      STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION\nmauqklyumsaqs     samarthya1c.samarthya.com   Ready               Active                                  18.09.5\nkilop2sdhc0m *   samarthya2c.samarthya.com   Ready               Active              Leader              18.09.5\nvg890hdgd333     samarthya3c.samarthya.com   Ready               Active                                  18.09.5\ncsl8igcknj28c     samarthya4c.samarthya.com   Ready               Active                                  18.09.5<\/code><\/pre>\n\n\n\n<p>You can see the designated leader in the swarm. The leader assigns work to the worker nodes.<\/p>\n\n\n\n<p>You can output the join token in master\/manager node using<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker swarm join-token worker<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>root@master>docker swarm join-token worker\nTo add a worker to this swarm, run the following command:\n\n    docker swarm join \\\n    --token SWMTKN-1-21wvlfoixago56zx0dbpznq8la36he9blrdyoyhosm4u02kvzk-bltrqgg1qiyrnr48xs1g5sybn \\\n    172.31.0.1:2377<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Flattening the layers &#8211; Docker<\/h2>\n\n\n\n<p>In this section we will be using <code>directives<\/code> instructions used in <code>Dockerfile<\/code> to create an image and flatten it to a single image instead of multiple.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Docker can build images automatically by reading the instructions from a\u00a0<code>Dockerfile<\/code>.<\/p><\/blockquote>\n\n\n\n<p> Consider a small docker container created as under<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM golang:1.13.11 AS builder\nWORKDIR \/helloworld\nCOPY goworld.go .\nRUN GOOS=linux go build -a -installsuffix cgo -o goworld .\n\nFROM alpine:3.9.3\nWORKDIR \/root\nCOPY --from=builder \/helloworld\/goworld .\nCMD &#91;\".\/goworld\"]<\/code><\/pre>\n\n\n\n<p>It just creates compiles a hello world go lang program and then executes it to print the output<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package main\nimport (\"fmt\")\n\nfunc main() {\n  fmt.Println(\" Hello World!\")\n}<\/code><\/pre>\n\n\n\n<p>If I look at the layers of the image<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;\n    {\n        \"Id\": \"sha256:2be60e641422227cd8caeb65894f66c63d08c514019e296dc32aae7f935f3076\",\n        \"RepoTags\": &#91;\n            \"efficient:latest\"\n        ],\n        \"RepoDigests\": &#91;],\n        \"Parent\": \"sha256:192c03c1f3fa07ed20b20b2b4f73a60fcb42dc6d910e47b13b2cd0e060961452\",\n        \"Comment\": \"\",\n        \"Created\": \"2020-07-11T18:35:55.800402558Z\",\n        \"Container\": \"b0a931821260361263ce15240238476813e7a84d3a32b9e773dcab24f956ce3f\",\n        \"ContainerConfig\": {\n            \"Hostname\": \"b0a931821260\",\n            \"Domainname\": \"\",\n            \"User\": \"\",\n            \"AttachStdin\": false,\n            \"AttachStdout\": false,\n            \"AttachStderr\": false,\n            \"Tty\": false,\n            \"OpenStdin\": false,\n            \"StdinOnce\": false,\n            \"Env\": &#91;\n                \"PATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin\"\n            ],\n            \"Cmd\": &#91;\n                \"\/bin\/sh\",\n                \"-c\",\n                \"#(nop) \",\n                \"CMD &#91;\\\".\/goworld\\\"]\"\n            ],\n            \"Image\": \"sha256:192c03c1f3fa07ed20b20b2b4f73a60fcb42dc6d910e47b13b2cd0e060961452\",\n            \"Volumes\": null,\n            \"WorkingDir\": \"\/root\",\n            \"Entrypoint\": null,\n            \"OnBuild\": null,\n            \"Labels\": {}\n        },\n        \"DockerVersion\": \"19.03.12\",\n        \"Author\": \"\",\n        \"Config\": {\n            \"Hostname\": \"\",\n            \"Domainname\": \"\",\n            \"User\": \"\",\n            \"AttachStdin\": false,\n            \"AttachStdout\": false,\n            \"AttachStderr\": false,\n            \"Tty\": false,\n            \"OpenStdin\": false,\n            \"StdinOnce\": false,\n            \"Env\": &#91;\n                \"PATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin\"\n            ],\n            \"Cmd\": &#91;\n                \".\/goworld\"\n            ],\n            \"Image\": \"sha256:192c03c1f3fa07ed20b20b2b4f73a60fcb42dc6d910e47b13b2cd0e060961452\",\n            \"Volumes\": null,\n            \"WorkingDir\": \"\/root\",\n            \"Entrypoint\": null,\n            \"OnBuild\": null,\n            \"Labels\": null\n        },\n        \"Architecture\": \"amd64\",\n        \"Os\": \"linux\",\n        \"Size\": 7541995,\n        \"VirtualSize\": 7541995,\n        \"GraphDriver\": {\n            \"Data\": {\n                \"LowerDir\": \"\/var\/lib\/docker\/overlay2\/2f6641cf733d78bc0ad8d6f0bad7c4436f01bf978bed3f1a9b41d7ec06af0244\/diff\",\n                \"MergedDir\": \"\/var\/lib\/docker\/overlay2\/3d38a55e5cd0e6dc257dd9ef2aa90b5d2b8a98ae55937a6ce37edf821c893e95\/merged\",\n                \"UpperDir\": \"\/var\/lib\/docker\/overlay2\/3d38a55e5cd0e6dc257dd9ef2aa90b5d2b8a98ae55937a6ce37edf821c893e95\/diff\",\n                \"WorkDir\": \"\/var\/lib\/docker\/overlay2\/3d38a55e5cd0e6dc257dd9ef2aa90b5d2b8a98ae55937a6ce37edf821c893e95\/work\"\n            },\n            \"Name\": \"overlay2\"\n        },\n        \"RootFS\": {\n            \"Type\": \"layers\",\n            \"Layers\": &#91;\n                \"sha256:a464c54f93a9e88fc1d33df1e0e39cca427d60145a360962e8f19a1dbf900da9\",\n                \"sha256:7bf030eb44f162731c1d17a4a3d5af128818f938997709309c13653780c15cd6\"\n            ]\n        },\n        \"Metadata\": {\n            \"LastTagTime\": \"2020-07-12T08:28:11.850260882Z\"\n        }\n    }\n]<\/code><\/pre>\n\n\n\n<p>We will flatten it to <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;\n    {\n        \"Id\": \"sha256:b9038e8380fe786207d091bd9e313e867198d44f985d149685bcb6c6fbbf333b\",\n        \"RepoTags\": &#91;\n            \"flat:latest\"\n        ],\n        \"RepoDigests\": &#91;],\n        \"Parent\": \"\",\n        \"Comment\": \"Imported from -\",\n        \"Created\": \"2020-07-12T09:04:40.856766368Z\",\n        \"Container\": \"\",\n        \"ContainerConfig\": {\n            \"Hostname\": \"\",\n            \"Domainname\": \"\",\n            \"User\": \"\",\n            \"AttachStdin\": false,\n            \"AttachStdout\": false,\n            \"AttachStderr\": false,\n            \"Tty\": false,\n            \"OpenStdin\": false,\n            \"StdinOnce\": false,\n            \"Env\": null,\n            \"Cmd\": null,\n            \"Image\": \"\",\n            \"Volumes\": null,\n            \"WorkingDir\": \"\",\n            \"Entrypoint\": null,\n            \"OnBuild\": null,\n            \"Labels\": null\n        },\n        \"DockerVersion\": \"19.03.12\",\n        \"Author\": \"\",\n        \"Config\": {\n            \"Hostname\": \"\",\n            \"Domainname\": \"\",\n            \"User\": \"\",\n            \"AttachStdin\": false,\n            \"AttachStdout\": false,\n            \"AttachStderr\": false,\n            \"Tty\": false,\n            \"OpenStdin\": false,\n            \"StdinOnce\": false,\n            \"Env\": null,\n            \"Cmd\": null,\n            \"Image\": \"\",\n            \"Volumes\": null,\n            \"WorkingDir\": \"\",\n            \"Entrypoint\": null,\n            \"OnBuild\": null,\n            \"Labels\": null\n        },\n        \"Architecture\": \"amd64\",\n        \"Os\": \"linux\",\n        \"Size\": 7541906,\n        \"VirtualSize\": 7541906,\n        \"GraphDriver\": {\n            \"Data\": {\n                \"MergedDir\": \"\/var\/lib\/docker\/overlay2\/efd29f53d69a47bc7b983c9da58a7985afaf3b354800c13da8fd3ef0e7f8dea6\/merged\",\n                \"UpperDir\": \"\/var\/lib\/docker\/overlay2\/efd29f53d69a47bc7b983c9da58a7985afaf3b354800c13da8fd3ef0e7f8dea6\/diff\",\n                \"WorkDir\": \"\/var\/lib\/docker\/overlay2\/efd29f53d69a47bc7b983c9da58a7985afaf3b354800c13da8fd3ef0e7f8dea6\/work\"\n            },\n            \"Name\": \"overlay2\"\n        },\n        \"RootFS\": {\n            \"Type\": \"layers\",\n            \"Layers\": &#91;\n                \"sha256:3aa6e339ec7bf27f61646f33b8532bff0de532c8072847f7e1d268ad51e0e358\"\n            ]\n        },\n        \"Metadata\": {\n            \"LastTagTime\": \"2020-07-12T09:04:40.859989787Z\"\n        }\n    }\n]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Docker Service<\/h3>\n\n\n\n<p>To deploy an image when docker is in swarm mode you can use <code>docker service<\/code>. When service is created, you specify which container image to use and which commands to execute inside running containers.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Refer to more information <a href=\"https:\/\/docs.docker.com\/engine\/reference\/commandline\/service\/#child-commands\">here<\/a><\/p><\/blockquote>\n\n\n\n<p>Minimum version required to use <code>docker service<\/code> is 1.24. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/docs.docker.com\/engine\/swarm\/images\/services-diagram.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service create --help\n\nUsage:  docker service create &#91;OPTIONS] IMAGE &#91;COMMAND] &#91;ARG...]\n\nCreate a new service\n\nOptions:\n      --config config                      Specify configurations to expose to the service\n      --constraint list                    Placement constraints\n      --container-label list               Container labels\n      --credential-spec credential-spec    Credential spec for managed service account (Windows only)\n  -d, --detach                             Exit immediately instead of waiting for the service to converge\n      --dns list                           Set custom DNS servers\n      --dns-option list                    Set DNS options\n      --dns-search list                    Set custom DNS search domains\n      --endpoint-mode string               Endpoint mode (vip or dnsrr) (default \"vip\")\n      --entrypoint command                 Overwrite the default ENTRYPOINT of the image\n  -e, --env list                           Set environment variables\n      --env-file list                      Read in a file of environment variables\n      --generic-resource list              User defined resources\n      --group list                         Set one or more supplementary user groups for the container\n      --health-cmd string                  Command to run to check health\n      --health-interval duration           Time between running the check (ms|s|m|h)\n      --health-retries int                 Consecutive failures needed to report unhealthy\n      --health-start-period duration       Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)\n      --health-timeout duration            Maximum time to allow one check to run (ms|s|m|h)\n      --host list                          Set one or more custom host-to-IP mappings (host:ip)\n      --hostname string                    Container hostname\n      --init                               Use an init inside each service container to forward signals and reap processes\n      --isolation string                   Service container isolation mode\n  -l, --label list                         Service labels\n      --limit-cpu decimal                  Limit CPUs\n      --limit-memory bytes                 Limit Memory\n      --log-driver string                  Logging driver for service\n      --log-opt list                       Logging driver options\n      --mode string                        Service mode (replicated or global) (default \"replicated\")\n      --mount mount                        Attach a filesystem mount to the service\n      --name string                        Service name\n      --network network                    Network attachments\n      --no-healthcheck                     Disable any container-specified HEALTHCHECK\n      --no-resolve-image                   Do not query the registry to resolve image digest and supported platforms\n      --placement-pref pref                Add a placement preference\n  -p, --publish port                       Publish a port as a node port\n  -q, --quiet                              Suppress progress output\n      --read-only                          Mount the container's root filesystem as read only\n      --replicas uint                      Number of tasks\n      --reserve-cpu decimal                Reserve CPUs\n      --reserve-memory bytes               Reserve Memory\n      --restart-condition string           Restart when condition is met (\"none\"|\"on-failure\"|\"any\") (default \"any\")\n      --restart-delay duration             Delay between restart attempts (ns|us|ms|s|m|h) (default 5s)\n      --restart-max-attempts uint          Maximum number of restarts before giving up\n      --restart-window duration            Window used to evaluate the restart policy (ns|us|ms|s|m|h)\n      --rollback-delay duration            Delay between task rollbacks (ns|us|ms|s|m|h) (default 0s)\n      --rollback-failure-action string     Action on rollback failure (\"pause\"|\"continue\") (default \"pause\")\n      --rollback-max-failure-ratio float   Failure rate to tolerate during a rollback (default 0)\n      --rollback-monitor duration          Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h) (default 5s)\n      --rollback-order string              Rollback order (\"start-first\"|\"stop-first\") (default \"stop-first\")\n      --rollback-parallelism uint          Maximum number of tasks rolled back simultaneously (0 to roll back all at once) (default 1)\n      --secret secret                      Specify secrets to expose to the service\n      --stop-grace-period duration         Time to wait before force killing a container (ns|us|ms|s|m|h) (default 10s)\n      --stop-signal string                 Signal to stop the container\n  -t, --tty                                Allocate a pseudo-TTY\n      --update-delay duration              Delay between updates (ns|us|ms|s|m|h) (default 0s)\n      --update-failure-action string       Action on update failure (\"pause\"|\"continue\"|\"rollback\") (default \"pause\")\n      --update-max-failure-ratio float     Failure rate to tolerate during an update (default 0)\n      --update-monitor duration            Duration after each task update to monitor for failure (ns|us|ms|s|m|h) (default 5s)\n      --update-order string                Update order (\"start-first\"|\"stop-first\") (default \"stop-first\")\n      --update-parallelism uint            Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)\n  -u, --user string                        Username or UID (format: &lt;name|uid>&#91;:&lt;group|gid>])\n      --with-registry-auth                 Send registry authentication details to swarm agents\n  -w, --workdir string                     Working directory inside the container<\/code><\/pre>\n\n\n\n<p>Simply using <code>docker service create<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service create --name mynginx nginx<\/code><\/pre>\n\n\n\n<p>the parameter <code>--name<\/code> defines the service name and the last param is the image to be used for the service.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ls\nID                  NAME                  MODE                REPLICAS            IMAGE                                         PORTS\ntp2szq0s5hbi        mynginx               replicated          1\/1                 nginx:latest                                  <\/code><\/pre>\n\n\n\n<p>See I have not exposed any port, and replicas are also only one.<\/p>\n\n\n\n<p>How can I scale it?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service scale mynginx=3\nmynginx scaled to 3\noverall progress: 3 out of 3 tasks \n1\/3: running   &#91;==================================================>] \n2\/3: running   &#91;==================================================>] \n3\/3: running   &#91;==================================================>] \nverify: Service converged <\/code><\/pre>\n\n\n\n<p>How should I update to expose a port<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service update --help\n\nUsage:  docker service update &#91;OPTIONS] SERVICE\n\nUpdate a service\n\nOptions:\n      --args command                       Service command args\n      --config-add config                  Add or update a config file on a service\n      --config-rm list                     Remove a configuration file\n      --constraint-add list                Add or update a placement constraint\n      --constraint-rm list                 Remove a constraint\n      --container-label-add list           Add or update a container label\n      --container-label-rm list            Remove a container label by its key\n      --credential-spec credential-spec    Credential spec for managed service account (Windows only)\n  -d, --detach                             Exit immediately instead of waiting for the service to converge\n      --dns-add list                       Add or update a custom DNS server\n      --dns-option-add list                Add or update a DNS option\n      --dns-option-rm list                 Remove a DNS option\n      --dns-rm list                        Remove a custom DNS server\n      --dns-search-add list                Add or update a custom DNS search domain\n      --dns-search-rm list                 Remove a DNS search domain\n      --endpoint-mode string               Endpoint mode (vip or dnsrr)\n      --entrypoint command                 Overwrite the default ENTRYPOINT of the image\n      --env-add list                       Add or update an environment variable\n      --env-rm list                        Remove an environment variable\n      --force                              Force update even if no changes require it\n      --generic-resource-add list          Add a Generic resource\n      --generic-resource-rm list           Remove a Generic resource\n      --group-add list                     Add an additional supplementary user group to the container\n      --group-rm list                      Remove a previously added supplementary user group from the container\n      --health-cmd string                  Command to run to check health\n      --health-interval duration           Time between running the check (ms|s|m|h)\n      --health-retries int                 Consecutive failures needed to report unhealthy\n      --health-start-period duration       Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)\n      --health-timeout duration            Maximum time to allow one check to run (ms|s|m|h)\n      --host-add list                      Add a custom host-to-IP mapping (host:ip)\n      --host-rm list                       Remove a custom host-to-IP mapping (host:ip)\n      --hostname string                    Container hostname\n      --image string                       Service image tag\n      --init                               Use an init inside each service container to forward signals and reap processes\n      --isolation string                   Service container isolation mode\n      --label-add list                     Add or update a service label\n      --label-rm list                      Remove a label by its key\n      --limit-cpu decimal                  Limit CPUs\n      --limit-memory bytes                 Limit Memory\n      --log-driver string                  Logging driver for service\n      --log-opt list                       Logging driver options\n      --mount-add mount                    Add or update a mount on a service\n      --mount-rm list                      Remove a mount by its target path\n      --network-add network                Add a network\n      --network-rm list                    Remove a network\n      --no-healthcheck                     Disable any container-specified HEALTHCHECK\n      --no-resolve-image                   Do not query the registry to resolve image digest and supported platforms\n      --placement-pref-add pref            Add a placement preference\n      --placement-pref-rm pref             Remove a placement preference\n      --publish-add port                   Add or update a published port\n      --publish-rm port                    Remove a published port by its target port\n  -q, --quiet                              Suppress progress output\n      --read-only                          Mount the container's root filesystem as read only\n      --replicas uint                      Number of tasks\n      --reserve-cpu decimal                Reserve CPUs\n      --reserve-memory bytes               Reserve Memory\n      --restart-condition string           Restart when condition is met (\"none\"|\"on-failure\"|\"any\")\n      --restart-delay duration             Delay between restart attempts (ns|us|ms|s|m|h)\n      --restart-max-attempts uint          Maximum number of restarts before giving up\n      --restart-window duration            Window used to evaluate the restart policy (ns|us|ms|s|m|h)\n      --rollback                           Rollback to previous specification\n      --rollback-delay duration            Delay between task rollbacks (ns|us|ms|s|m|h)\n      --rollback-failure-action string     Action on rollback failure (\"pause\"|\"continue\")\n      --rollback-max-failure-ratio float   Failure rate to tolerate during a rollback\n      --rollback-monitor duration          Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h)\n      --rollback-order string              Rollback order (\"start-first\"|\"stop-first\")\n      --rollback-parallelism uint          Maximum number of tasks rolled back simultaneously (0 to roll back all at once)\n      --secret-add secret                  Add or update a secret on a service\n      --secret-rm list                     Remove a secret\n      --stop-grace-period duration         Time to wait before force killing a container (ns|us|ms|s|m|h)\n      --stop-signal string                 Signal to stop the container\n  -t, --tty                                Allocate a pseudo-TTY\n      --update-delay duration              Delay between updates (ns|us|ms|s|m|h)\n      --update-failure-action string       Action on update failure (\"pause\"|\"continue\"|\"rollback\")\n      --update-max-failure-ratio float     Failure rate to tolerate during an update\n      --update-monitor duration            Duration after each task update to monitor for failure (ns|us|ms|s|m|h)\n      --update-order string                Update order (\"start-first\"|\"stop-first\")\n      --update-parallelism uint            Maximum number of tasks updated simultaneously (0 to update all at once)\n  -u, --user string                        Username or UID (format: &lt;name|uid>&#91;:&lt;group|gid>])\n      --with-registry-auth                 Send registry authentication details to swarm agents\n  -w, --workdir string                     Working directory inside the container<\/code><\/pre>\n\n\n\n<p>Adding <code>8082<\/code> as a published port to expose the port <code>80<\/code> of <code>nginx<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service update mynginx --publish-add 8082:80\nmynginx\noverall progress: 3 out of 3 tasks \n1\/3: running   &#91;==================================================>] \n2\/3: running   &#91;==================================================>] \n3\/3: running   &#91;==================================================>] \nverify: Service converged <\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>docker service ls\nID                  NAME                  MODE                REPLICAS            IMAGE                                         PORTS\ntp2szq0s5hbi        mynginx               replicated          3\/3                 nginx:latest                                  *:8082->80\/tcp<\/code><\/pre>\n\n\n\n<p>Simple check<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl localhost:8082<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\n&lt;!DOCTYPE html>\n&lt;html>\n&lt;head>\n&lt;title>Welcome to nginx!&lt;\/title>\n&lt;style>\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n&lt;\/style>\n&lt;\/head>\n&lt;body>\n&lt;h1>Welcome to nginx!&lt;\/h1>\n&lt;p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.&lt;\/p>\n\n&lt;p>For online documentation and support please refer to\n&lt;a href=\"http:\/\/nginx.org\/\">nginx.org&lt;\/a>.&lt;br\/>\nCommercial support is available at\n&lt;a href=\"http:\/\/nginx.com\/\">nginx.com&lt;\/a>.&lt;\/p>\n\n&lt;p>&lt;em>Thank you for using nginx.&lt;\/em>&lt;\/p>\n&lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<p>When running Docker Engine in swarm mode, you can use\u00a0<code>docker stack deploy<\/code>\u00a0to deploy a complete application stack to the swarm. It accepts instructions form a compose file.<\/p>\n\n\n\n<p>The Compose file is a\u00a0<a href=\"http:\/\/yaml.org\/\">YAML<\/a>\u00a0file defining\u00a0<a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/#service-configuration-reference\">services<\/a>,\u00a0<a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/#network-configuration-reference\">networks<\/a>\u00a0and\u00a0<a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/#volume-configuration-reference\">volumes<\/a>.\u00a0<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Supports version 3 and upwards.<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Docker services allows replication of a single service across nodes in a docker swarm, and Docker stack allows more deployment of more complex application of interrelated services and to be scaled as a unit.<\/p><\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Helpful link<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/docs.docker.com\/engine\/swarm\/how-swarm-mode-works\/services\/\">https:\/\/docs.docker.com\/engine\/swarm\/how-swarm-mode-works\/services\/<\/a><\/li><li><a href=\"https:\/\/docs.docker.com\/engine\/swarm\/admin_guide\/#back-up-the-swarm\">https:\/\/docs.docker.com\/engine\/swarm\/admin_guide\/#back-up-the-swarm<\/a><\/li><li><a href=\"https:\/\/docs.docker.com\/get-started\/swarm-deploy\/\">https:\/\/docs.docker.com\/get-started\/swarm-deploy\/<\/a><\/li><li>https:\/\/www.toptal.com\/linux\/separation-anxiety-isolating-your-system-with-linux-namespaces<\/li><li><a href=\"https:\/\/docs.docker.com\/get-started\/#containers-and-virtual-machines\">https:\/\/docs.docker.com\/get-started\/#containers-and-virtual-machines<\/a><\/li><li><a href=\"https:\/\/docs.docker.com\/engine\/swarm\/swarm-tutorial\/add-nodes\/\">https:\/\/docs.docker.com\/engine\/swarm\/swarm-tutorial\/add-nodes\/<\/a><\/li><li><a href=\"https:\/\/docs.docker.com\/engine\/reference\/builder\/\">https:\/\/docs.docker.com\/engine\/reference\/builder\/<\/a><\/li><li><a href=\"https:\/\/helm.sh\/docs\/topics\/charts\/\">https:\/\/helm.sh\/docs\/topics\/charts\/<\/a><\/li><li><a href=\"https:\/\/docs.docker.com\/compose\/compose-file\/\">https:\/\/docs.docker.com\/compose\/compose-file\/<\/a><\/li><\/ul>\n\n\n\n<p>Next, I might look into Helm.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><a href=\"https:\/\/helm.sh\/\">Helm<\/a>&nbsp;is the package manager for the <strong>Kubernetes<\/strong>&nbsp; &amp; in this approach, Kubernetes could be considered as an operating system.<\/p><\/blockquote>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Usually I use Centos, but this time I wanted to try out docker swarm and ubuntu was the preferred option due to the options and supporting blogs available. Do read &#8211; https:\/\/docs.docker.com\/get-started\/#containers-and-virtual-machines docker.com Step 1 Updating the system and installing required dependencies The version of Ubuntu I am using is as under Add the GPG [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":766,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"quote","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[1,34],"tags":[82,83,84],"class_list":["post-765","post","type-post","status-publish","format-quote","has-post-thumbnail","hentry","category-others","category-technical","tag-docker","tag-swarm","tag-ubuntu","post_format-post-format-quote"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/765","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=765"}],"version-history":[{"count":0,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/765\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/766"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}