Highly Available Docker Registry on AWS with Nexus

Have you ever wondered how you can build a highly available & resilient Docker Repository to store your Docker Images ?

Résultat de recherche d'images pour "you came to the right place meme"

In this post, we will setup an EC2 instance inside a Security Group and create an A record pointing to the server Elastic IP address as follow:

To provision the infrastructure, we will use Terraform as IaC (Infrastructure as Code) tool. The advantage of using this kind of tools is the ability to spin up a new environment quickly in different AWS region (or different IaaS provider) in case of incident (Disaster recovery).

Start by cloning the following Github repository:

Inside docker-registry folder, update the variables.tfvars with your own AWS credentials (make sure you have the right IAM policies).

I specified a shell script to be used as user_data when launching the instance. It will simply install the latest version of Docker CE and turn the instance to Docker Swarm Mode (to benefit from replication & high availability of Nexus container)

Note: Surely, you can use a Configuration Management Tools like Ansible or Chef to provision the server once created.

Then, issue the following command to create the infrastructure:

Once created, you should see the Elastic IP of your instance:

Connect to your instance via SSH:

Verify that the Docker Engine is running in Swarm Mode:

Check if Nexus service is running:

If you go back to your AWS Management Console. Then, navigate to Route53 Dashboard, you should see a new A record has been created which points to the instance IP address.

Point your favorite browser to the Nexus Dashboard URL (registry.slowcoder.com:8081). Login and create a Docker hosted registry as below:

Edit the /etc/docker/daemon.json file, it should have the following content:

Note: For production it’s highly recommended to secure your registry using a TLS certificate issued by a known CA.

Restart Docker for the changes to take effect:

Login to your registry with Nexus Credentials (admin/admin123):

In order to push a new image to the registry:

Verify that the image has been pushed to the remote repository:

To pull the Docker image:

Note: Sometimes you end up with many unused & dangling images that can quickly take significant amount of disk space:

You can either use the Nexus CLI tool or create a Nexus Task to cleanup old Docker Images:

Populate the form as below:

The task above will run everyday at midnight to purge unused docker images from “mlabouardy” registry.

Exploring Swarm & Container Overview Dashboard in Grafana

In my previous post, your learnt how to monitor your Swarm Cluster with TICK Stack. In this part, I will show you how to use the same Stack but instead of using Chronograf as our visualization and exploration tool we will use Grafana.

Connect to your manager node via SSH, and clone the following Github repository:

Use the docker-compose.yml below to setup the monitoring stack:

Then, issue the following command to deploy the stack:

Once deployed, you should see the list of services running on the cluster:

Point your browser to http://IP:3000, you should be able to reach the Grafana Dashboard:

The default username & password are admin. Go ahead and log in.

Go to “Data Sources” and create 2 InfluxDB data sources:

  • Vms: pointing to your Cluster Nodes metrics database.
  • Docker: pointing to your Docker Services metrics database.

Finally, import the dashboard by hitting the “import” button:

From here, you can upload the dashboard.json, then pick the data sources you created earlier:

You will end up with an interactive and dynamic dashboard:

Cleanup old Docker images from Nexus Repository

Many of us, are using Nexus as a repository to publish Docker Images. Typically we build images tagged with the commit hash (or using semver ideally) after SCM change automatically in CI and we push them to registry. As result there are many “unneeded” & “old” images that in our case take significant amount of disk space.

I looked around the graphical interface of Nexus and there’s apparently nothing to remove several Docker images at the same time. Or even, a scheduled task  to clean up old hosted Docker images, and to also clean up layers which are no longer used by any hosted images.

So I have come up with a simple bash script which uses Docker Registry API to purge Docker images and keep the last X images and delete all other. But, is there a better solution ? YES ! I built a Nexus CLI

To install Nexus CLI, find the appropriate package for your system and download it. For linux:

After downloading Nexus CLI. Add the execution permission to the binary:

Note: For Windows make sure that nexus-cli binary is available on the PATHThis page contains instructions for setting the PATH on Windows.

After installing, verify the installation worked, by opening a new terminal session and checking if nexus-cli is available :

Once done, configure the Nexus credentials:

Through nexus-cli configure, the Nexus CLI will prompt you for four pieces of information. The Username and Password are your account credentials. Nexus Hostname & Docker repository name.

That should be it. Try out the following command from your cmd prompt and, if you have any images, you should see them listed

Display image tags:

Image description:

To remove a specific image:

To keep only the last X images and delete all other:

That’s it ! Let’s go back to Nexus Dashboard:

As you can see, Nexus kept only the last 4 images and deleted the others.

Résultat de recherche d'images pour "awesome meme"

The CLI is still in its early stages, so you are welcome to contribute to the project in Github.

Docker Swarm Networking and Dynamic Reverse Proxy

This post will show you how to setup a Swarm Cluster, deploy a couple of microservices, and create a Reverse Proxy Service (with Traefik) in charge of routing requests on their base URLs.

Résultat de recherche d'images pour "microservices memes"

If you haven’t already, create a Swarm cluster, you could use the shell script below to setup a cluster with 3 nodes (1 Manager & 2 Workers)

Issue the following command to execute the script:

The output of the above command is as follows:

At this moment, we have 3 nodes:

Our example microservice application consists of two parts. The Books API and the Movies API. For both parts I have prepared images for you that can be pulled from the DockerHub.

The Dockerfiles for both images can be found on my Github.

Create docker-compose.yml file with the following content:

  • We use an overlay network named traefik-net, on which we add the services we want to expose to Traefik.
  • We use constraints to deploy the APIs on workers & Traefik on Swarm manager.
  • Traefik container is configured to listen on port 80 for the standard HTTP traffic, but also exposes port 8080 for a web dashboard.
  • The use of docker socket (/var/run/docker.sock) allows Traefik to listen to Docker Daemon events, and reconfigure itself when containers are started/stopped.
  • The label traefik.frontend.rule is used by Træfik to determine which container to use for which Request Path.
  • The configs part create a configuration file for Traefik from config.toml (it enables the Docker backend)

In order to deploy our stack, we should execute the following command:

Let’s check the overlay network:

Traefik configuration:

To display the configuration content:

And finally, to list all the services:

In the list of above, you can see that the 3 containers are being running on node-1, node-2 & node-3 :

If you point your favorite browser (not you IE 😂) to the Traefik Dashboard URL (http://MANAGER_NODE_IP:8080) you should see that the frontends and backends are well defined:

If you check http://MANAGER_NODE_IP/books, you will get a list of books

If you replace the base URL with /movies:

What happens if we want to scale out the books & movies APIs. With the docker service scale command:

We can confirm that:

Obviously Traefik did recognise that we started more containers and made them available to the right frontend automatically:

In the diagram below, you will find that the manager has decied to schedule the new containers on node-2 (3 of them) and node-3 (4 of them) using the Round Robin strategy

Pushing a Docker Image to the EC2 Container Registry

In this quick post, I will show you how to setup a Docker Registry on AWS using EC2 Container Registry (ECR) service and how to push & pull an image from Amazon ECR.

1 – Configure Repository

First login to your AWS Management Console then navigate to ECR:

Click on “Get Started“:

Choose a name for your repository, then click on “Next“:

At this point, you will be taken to the Repositories Dashboard:

Congratulation ! you have created your first AWS Docker Registry.

In order to push & pull docker images from/to ECR, we need to get docker login from AWS CLI:

Run the following command to push it to the repository:

Let’s check the repository: