DEV Community

Cover image for Multi-host deployment and management using Portainer
Luke
Luke

Posted on • Edited on

Multi-host deployment and management using Portainer

TL;DR

I will simulate a multi-host environment using DinD and then use Portainer for deployment and management.

Prerequisite

  • Installed Docker (If you don't have it, follow the instructions for Windows or Linux)

  • Read previous post to know what I done

Architecture

I will migrate from a single-host to a multi-host architecture.

Architecture

Multi-host

Install Portainer

Step 1: Register 3 nodes free for portainer

  • Click on the link
  • Fill out the form
  • Get an email and save the license key

License Key

Email license key

Step 2: Create docker volume for portainer

docker volume create portainer_data 
Enter fullscreen mode Exit fullscreen mode

Step 3: Create network

docker network create portainer-network 
Enter fullscreen mode Exit fullscreen mode

Step 4: Run portainer with specify network

docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always --network portainer-network -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ee:lts 
Enter fullscreen mode Exit fullscreen mode

Step 5: Access portainer via localhost:9443/#!/endpoints to create account

register account

Register Account

Step 6: Register license key you get from email

register license key

Register key

home page

Home page

Push image to docker registry

Step 1: Open terminal and run (it will will be prompted to enter Docker ID (username) and password interactively)

docker login 
Enter fullscreen mode Exit fullscreen mode

Step 2: Tagging image with the following format <your-username-docker>/<application-name>:<version>. Your username should be the same display on docker

docker hub

For me, username is locnguyenpv

  • FE
docker tag project-management/client-app locnguyenpv/client-app:v1 
Enter fullscreen mode Exit fullscreen mode
  • BE
docker tag project-management/project-service locnguyenpv/project-service:v1 docker tag project-management/user-service locnguyenpv/user-service:v1 docker tag project-management/task-service locnguyenpv/task-service:v1 
Enter fullscreen mode Exit fullscreen mode

Step 3: Push image to registry by tag

  • FE
docker push locnguyenpv/client-app:v1 
Enter fullscreen mode Exit fullscreen mode
  • BE
docker push locnguyenpv/project-service:v1 docker push locnguyenpv/user-service:v1 docker push locnguyenpv/task-service:v1 
Enter fullscreen mode Exit fullscreen mode

Connect to DinD

Step 1: Create 2 DinD, one for FE, one for BE

  • FE:
docker run --privileged -d --name project-management-fe --network portainer-network -p 80:80 -p 9002:9001 -p 2377:2375 docker:dind 
Enter fullscreen mode Exit fullscreen mode
  • BE:
docker run --privileged -d --name project-management-be --network portainer-network -p 2376:2375 -p 9001:9001 -p 9099:9099 docker:dind 
Enter fullscreen mode Exit fullscreen mode

Step 2: SSH into each DinD to install Portainer Agent

  • FE:
docker exec -it project-management-fe sh docker run -d \ -p 9001:9001 \ --name portainer_agent \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/docker/volumes:/var/lib/docker/volumes \ -v /:/host \ portainer/agent:2.27.9 
Enter fullscreen mode Exit fullscreen mode
  • BE:
docker exec -it project-management-be sh docker run -d \ -p 9001:9001 \ --name portainer_agent \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/docker/volumes:/var/lib/docker/volumes \ -v /:/host \ portainer/agent:2.27.9 
Enter fullscreen mode Exit fullscreen mode

Step 3: Connect DinD with Portainer
Environment Dashboard

select environment

connect env

connect success

Connect Success

Update docker-compose

Now that I've pushed the image to the Docker registry, I can use it instead of building from source. Replace build from source to pull image from registry

  • FE:
services: client-service: image: locnguyenpv/client-app:v1 ports: - "80:80" restart: always 
Enter fullscreen mode Exit fullscreen mode
  • BE:
services: mysql-service: image: mysql:latest container_name: mysql-container environment: MYSQL_PASSWORD: 123123 ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql # create space for persistence data - ./database:/docker-entrypoint-initdb.d # Mount init file into container  healthcheck: # Check every 10s to make sure it work fine test: ["CMD-SHELL", "mysqladmin -u root -p$MYSQL_PASSWORD ping -h localhost || exit 1"] interval: 30s retries: 5 timeout: 10s start_period: 10s networks: - internal-network nginx: image: nginx:latest container_name: nginx-gateway ports: - "9099:9099" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro # Mount nginx config from local to container depends_on: # Start condition - project-service - user-service - task-service networks: - internal-network # Virtual network project-service: image: locnguyenpv/project-service:v1 container_name: project-service-container ports: - "8081:8081" environment: MYSQL_HOST: mysql-service MYSQL_PORT: 3306 MYSQL_USER: root MYSQL_PASSWORD: 123123 depends_on: mysql-service: condition: service_healthy networks: - internal-network # Virtual network user-service: image: locnguyenpv/user-service:v1 container_name: user-service-container ports: - "8082:8082" environment: MYSQL_HOST: mysql-service MYSQL_PORT: 3306 MYSQL_USER: root MYSQL_PASSWORD: 123123 depends_on: mysql-service: condition: service_healthy networks: - internal-network # Virtual network task-service: image: locnguyenpv/task-service:v1 container_name: task-service-container ports: - "8083:8083" environment: MYSQL_HOST: mysql-service MYSQL_PORT: 3306 MYSQL_USER: root MYSQL_PASSWORD: 123123 depends_on: mysql-service: condition: service_healthy networks: - internal-network # Virtual network networks: internal-network: driver: bridge name: internal-network volumes: mysql-data: 
Enter fullscreen mode Exit fullscreen mode

Deploy to DinD

Step 1: Go to home page and choose DinD

home page

Step 2: Choose stack

stack

Step 3: Add new stack

add stack

Step 4: Copy & paste docker-compose file into editor

stack editor

Step 5: Deploy

deploy stack

deploy success

Deploy success

Replace those steps for other DinD. All set!

Conclusion

I just show you the way how to simulate multi-host environment by DinD. After that, use Portainer for management and deployment.

Happy Coding

Top comments (0)