How to use docker compose with docker swarm?

Hello,
I have three servers and I ran the following command on the manager node:

# docker swarm init --advertise-addr 172.20.2.53

I ran the following command on the other two nodes:

# docker swarm join --token SWMTKN-1-0rmswotsbvzaybcujrveigtr7ln5fcywsjtdn02gwdykpt468m-8skbceyft79pho1gz6xh74gx6 172.20.2.53:2377

I got the following message on both nodes:

This node joined a swarm as a worker.

The final result is as follows:

# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
jd3rf7qz4hnzb9c2z1zh006l1 *   Manager    Ready     Active         Leader           26.1.3
trazxqj2wvg47as0ogr5kv2ow     Node1      Ready     Active                          26.1.3
0rlvf0m07bkuleuwhxf28k9xj     Node2      Ready     Active                          26.1.1

I executed the following command on the manager node:

# docker service create --name Swarm_Mode --replicas 3 -p 80:80 nginx

The result is as follows:

# docker service create --name Swarm_Mode --replicas 3 -p 80:80 nginx
owu0svssay8gue7auwmkga6ch
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service owu0svssay8gue7auwmkga6ch converged 

After this, I checked the running services on all three servers:

On manager:
# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS     NAMES
da8c79a563ef   nginx:latest   "/docker-entrypoint.…"   29 seconds ago       Up 22 seconds       80/tcp    Swarm_Mode.2.xp650jms8broke4vg5grjr8bx
8d2cb2e3aed4   nginx:latest   "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp    Swarm_Mode.3.9o3zi2ls2xybqwovti3lq62in

On Node1:
# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
365eca9ef5af   nginx:latest   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   80/tcp    Swarm_Mode.1.y4d3h522jhpfv00gq5pdj4d9e

On Node2:
# docker ps
#

I have some questions:

1- Why is there no container running on Node2?

2- I have a YAML file like below:

services:
    nodejs-1:
      container_name: Node-Micro1
      hostname: Node1
      build:
         context: .
         dockerfile: Dockerfile1
      command: npm start
      volumes:
        - ./www:/usr/src/app
        - "/var/run/docker.sock:/var/run/docker.sock"
      expose:
        - "3000"
      ports:
        - '3000:3000'

    nodejs-2:
      container_name: Node-Micro2
      hostname: Node2
      build:
         context: .
         dockerfile: Dockerfile2
      command: npm start
      volumes:
        - ./www:/usr/src/app
        - "/var/run/docker.sock:/var/run/docker.sock"
      expose:
        - "3000"
      ports:
        - '3001:3000'

    nginx:
      image: nginx:latest
      container_name: Nginx-Micro
      ports:
        - '80:80'
      volumes:
        - ./default.conf:/etc/nginx/conf.d/default.conf
        - "/var/run/docker.sock:/var/run/docker.sock"
        - ./www:/usr/share/nginx/html
      depends_on:
        - nodejs-1
        - nodejs-2
      links:
        - nodejs-1
        - nodejs-2

Should the YAML file and project source code be on the manager node?

Thank you.

To deploy a compose file to Swarm, you need to run docker swarm deploy.

This only works on manager nodes, so compose file is needed on manager.

Swarm deploy will not build images from Dockerfile, so you need to create the images up front and push them to a repository, then reference by image name.

Building and pushing can be done on any type of node.

depends_on and links does not work in Swarm over multiple nodes.

1 Like

Hello,
Thank you so much for your reply.
You said:

Swarm deploy will not build images from Dockerfile, so you need to create the images up front and push them to a repository, then reference by image name.

What do you mean by create the images up front and push them to a repository?

build: is not available for docker swarm deploy, you can only use image:.

So you need to build and push to a registry (to be downloaded later) via a separate process. Search Internet for “docker build push” to find a tutorial.

You can run your own registry or use (paid) offering. When using your own, make sure it’s not accessible from public or user user/pass.

1 Like

Hi,
Thanks again.
So I need a DockerHub account. It’s like turning my website into a docker image. Is it correct?
I use GitLab Runner. So whenever a change is made to the website, this image needs to be rebuilt and uploaded to DockerHub. I think it is a little unreasonable.
Is there another way to HA containers?

Hello,
Any idea about it?

Thanks.

You need a Docker image registry for hosting the images, so all nodes can pull from it.

You can use Docker Hub, Github container registry, other providers or run your own.

1 Like

Hi,
Thanks again.
Isn’t it time consuming to push and pull images?

To run an image, you need to pull it anyway.

Using a build section in compose is even building the image first, which will pull base images and run the Dockerfile commands, which should usually take longer.

It is recommended to use small images anyway, which will speed up the process. Most base images provide some kind of alpine or light/small tag for smaller images.

Smaller images will usually also decrease your m attack surface, as there is fewer software included, that could be abused by an attacker trying to hack your containers.