Docker Stack

Till now we had deployed services in a docker using the docker-compose file. But this file only creates the resources on the single node docker host.

Now suppose there are multiple services to be deployed on multiple nodes.

root@master:~# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
buc72h0hyo66gcilq7melh9pq *   master     Ready     Active         Leader           20.10.11
xvdyauu8t83r3udrqh6c5w8a8     worker01   Ready     Active                          20.10.11
xctiaq0n14aew1falekqybq53     worker02   Ready     Active                          20.10.11
root@master:~#

In such a case manually starting services is not feasible. If we run the below docker-compose file, it will create the containers only on the docker host along with a warning saying 'The Docker engine you are using is running in swarm mode'

root@master:~# cat docker-compose.yaml
version: "3.9"
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
root@master:~#
root@master:~# docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Creating network "root_default" with the default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
a10c77af2613: Pull complete
2e35f83a12e9: Pull complete
Digest: sha256:7a3a7b7a29e6fbff433c339fc52245435fa2c308586481f2f92ab1df239d6a29
Status: Downloaded newer image for mysql:5.7
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
69fce6e644d9: Pull complete
Digest: sha256:e7b40265f5d72fc74fb73683a60f5d3de9787a6467b87b78ee742645807d8463
Status: Downloaded newer image for wordpress:latest
Creating root_db_1 ... done
Creating root_wordpress_1 ... done
root@master:~#
root@master:~#
root@master:~#
root@master:~# docker container ls
CONTAINER ID   IMAGE              COMMAND                  CREATED              STATUS              PORTS                                   NAMES
54ccfed35f94   wordpress:latest   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:8000->80/tcp, :::8000->80/tcp   root_wordpress_1
8be5aa3f0626   mysql:5.7          "docker-entrypoint.s…"   About a minute ago   Up About a minute   3306/tcp, 33060/tcp                     root_db_1
root@master:~#
root@master:~#
root@master:~#
root@master:~# docker service ls
ID        NAME      MODE      REPLICAS   IMAGE     PORTS
root@master:~#

The task is to create services on all the nodes rather than on a single node. For this purpose, the docker stack comes in handy. Docker stack is used to perform actions on the entire cluster.

The YAML file for both docker-compose and docker stack is similar, just that there are few parameters that are supported in compose file and not in stack file and vice versa.

Consider the below docker-compose.yml file-

root@master:~# cat docker-compose.yaml
version: "3.9"
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
root@master:~#

To deploy this file, use below command -

$docker stack deploy - c [filename] [stackname]
root@master:~# docker stack deploy -c docker-compose.yaml wordpress
Ignoring unsupported options: restart
Creating network wordpress_default
Creating service wordpress_db
Creating service wordpress_wordpress

To list all the services, use the below command-

root@master:~# docker stack ls
NAME        SERVICES   ORCHESTRATOR
wordpress   2          Swarm
root@master:~#

To list all the processes in the stack -

root@master:~# docker stack ps wordpress
ID             NAME                    IMAGE              NODE       DESIRED STATE   CURRENT STATE                ERROR     PORTS
ncokkcihxs68   wordpress_db.1          mysql:5.7          worker02   Running         Running 1 second ago
n82stx6br45d   wordpress_wordpress.1   wordpress:latest   master     Running         Running about a minute ago
root@master:~#

To list the services in the stack -

root@master:~# docker stack services wordpress
ID             NAME                  MODE         REPLICAS   IMAGE              PORTS
sgrg12tosxjq   wordpress_db          replicated   1/1        mysql:5.7
mnsz9wmjflux   wordpress_wordpress   replicated   1/1        wordpress:latest   *:8000->80/tcp
root@master:~#

And to remove the services, use the below command -

root@master:~# docker stack rm wordpress
Removing service wordpress_db
Removing service wordpress_wordpress
Removing network wordpress_default
root@master:~#