Deploy docker swarm from Gitlab CI

July 1, 2020 Docker Deploy Gitlab Ci/Cd


Deploy docker swarm from Gitlab CI

Docker container deployment has many advantages over binary deployment. Let’s dive into advantages and see how we can implement docker container deployment from Gitlab CI. Let’s talk standard docker can help us. Any docker orchestration tools (Kubernetes, for example) will be observed in future articles.

Recently we discussed a binary file deployment via SSH.

Now we are discussing Docker container deployment with Gitlab CI.

Docker advantages

There are some of them against binary file deployment:

We don’t need a software to start/restart our service besides docker utility. When using binary file deployment we need an additional software like systemd or supervisor. No need to install any additional software directly on the server where docker container is going to be started (again, besides docker utility.) All necessary additional programs could be installed inside our docker container during docker image build. Docker container’s short lifetime allows us to change the docker image how and when we want to. We could install/update software in docker image, even change base OS of docker image. We don’t have to care about old container — we just rebuild new container and deploy it. The old container will be replaced by the new one. Simplified hosting deployment — docker is a standard tool and many modern hosting providers (AWS, Microsoft Azure, Google Cloud) provide us with docker hosting options. Docker has health checking logic to monitor, start and restart containers; horizontal and vertical scaling; load balancing between containers in single service; DNS (services could access each other by short names) — all of these make docker suitable tool for any kind of modern applications. Docker image building Recently we discussed minimal docker image building for GO program. Let’s continue to use that approach.

Deployment

We are going to use only standard docker utility options. We intentionally ignore any external orchestration tools like kubernetes or nomad; We won’t use any cloud docker provider, for example, Google Cloud — all of it we’ll discuss in future articles.

Docker swarm

We choose docker swarm, it is a part of standard docker utility. Swarm allows us to manage containers on a remote server that is previously configured with docker swarm init or docker swarm join commands. These commands change docker service mode to swarm.

SSH access to the target server is not required, which is an advantage. docker stack deploy updates containers using file in docker-compose format, so we even don’t need to install docker-compose.

When using docker stack deploy, which is accessible when docker service runs in swarm mode, we can pass the exact order in which we want our containers to be updated and many other deployment options. By this we can provides smooth update without downtime. Also, features like scaling, load balancing and DNS, which i highlighted before, are accessible only in swarm mode.

Target server preparation We have to access target server via SSH and change it’s mode to swarm:

docker swarm init

This command also prints tokens which can be used later from other servers to join the swarm by using docker swarm join –token xxx command. But in this article, we only have one server and we are not going to use docker swarm join.

We are going to use remote connection from Gitlab CI to our docker service on target server. So we are changing docker service configuration to make docker service remotely accessible. To do this create/change docker service configuration for systemd:

sudo -s
mkdir -p /etc/systemd/system/docker.service.d
touch /etc/systemd/system/docker.service.d/startup_options.conf

startup_options.conf contents:

[Service]
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376

Restart systemd and docker service:

systemctl daemon-reload

Now docker service is remotely accessible.

.gitlab-ci.yml preparation deploy_docker_stage: environment: name: stage url: https://someurl image: docker:19.03.1 services: — docker:19.03.1-dind stage: deploy variables: DOCKER_HOST: “tcp://${DOCKER_HOST}:2376” before_script: — apk add jq — docker login -u $USER -p $PASSWORD $DOCKER_REPO script:

  • export CONFIG=$(echo $CONFIG1_STAGE | jq -c) && docker stack deploy –with-registry-auth -c ./docker/stage/app.yml app We changed the DOCKER_HOST varaible to make docker command access our remote server which we configured previously.

Our image is stored in private repository, to access which we used docker login command. To make docker stack deploy command use authorization granted by docker login, –with-registry-auth parameter is set.

yaml configuration file ./docker/stage/app.yml contents:

version: '3.8'
services:
app:
image: ${DOCKER_REPO}/${DOCKER_IMAGE}
environment:
— CONFIG
ports:
— "9091:9091"
— "8444:8444"
depends_on:
— postgres
— redis
deploy:
replicas: 3
update_config:
parallelism: 2
delay: 3s
order: start-first
failure_action: rollback
monitor: 1m
restart_policy:
max_attempts: 3

docker stack deploy is very helpful because it uses environment variables to fill the configuration. We use ${DOCKER_REPO}, ${DOCKER_IMAGE} и CONFIG.

Deploy structure in yaml sets up deployment:

order: start-first makes new container start before old container is stopped which makes our deploy downtime-less. parallelism: 2 sets how many container pairs are going to be updated in one time, which affect on server load during the update. monitor: 1m sets the time which docker service will monitor new containers to make decision if update is successful. failure_action: rollback sets behaviour if one of new containers is failed — rollback is chosen.

Tags:

Related Articles

1 Jul 2020

Remote debugging with Delve

Previously we discussed local debugging with GoLand IDE. Now we’ll discuss how to remotely debug a program running inside a Docker container using Visual Studio Code and GoLand IDE.

Read More → Docker Debugger Delve Vscode Goland
30 Jun 2020

net-wait-go utility / library

net-wait-go utility / library

Both utility and Go package to wait for ports to open (TCP, UDP).

Read More → Tcp Udp Docker
29 Jun 2020

Building Minimal Docker Images for Go Applications

Building Minimal Docker Images for Go Applications

Let’s discuss how to build a minimal Docker image for a Go program.

Read More → Docker Compilation Upx Ldflags
8 May 2020

Compilation and deploy via SSH in Gitlab CI

Compilation and deploy via SSH in Gitlab CI

Let’s take a look at how Go compilation works and how to use GitLab CI for that.

Read More → Gitlab Compilation Deploy Ssh Modules Vendor Ci/Cd