Push multiple docker container images using a loop – Azure DevOps

On a pipeline that I was creating I wanted to push multiple docker images on an Azure container registry based on a list. In order to do that I used the docker@2 task on a loop providing the images that I had to push as a parameter. Code is attached below.

trigger:
– none
pr: none
parameters:
– name: containerlist
type: object
default: ["core/image1","core/image2","core/image3","core/image4"]
– name: DockerPushID
type: string
pool:
name: demo-app
stages:
– stage: containers
displayName: Push containers to container registry $(registry)
jobs:
– job: pushcontainers
displayName: Push containers on testexample.azurecr.io
steps:
– checkout: none
– ${{ each container in parameters.containerlist }}:
– task: Docker@2
displayName: pushing image ${{container}}
inputs:
containerRegistry: 'registryconnection'
repository: '${{container}}'
command: 'push'
tags: |
current-${{parameters.DockerPushID}}
current-latest

This task will run steps based on the images you provide on the parameters list. An important note is that you need to have the image named accordingly in order to get a successful result. For example if you need to push on geralexgr.azurecr.io you will need to have your images named as below.

geralexgr.azurecr.io/image1:current-latest
geralexgr.azurecr.io/image2:current-latest

Else you may notice some failures indicating the below.

The push refers to repository [***/kati/image1] 
An image does not exist locally with the tag: ***/kati/image1

A successful run of the pipeline.

Additional information regarding loops and expressions on Azure DevOps pipelines:

https://docs.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops#functions

Video tutorial on YouTube:

Deploy wordpress with mysql in less than a minute using docker containers

For testing purposes I had to deploy a wordpress installation and perform some work. As the standalone installation with wamp/mamp/xampp software would require time, I chose docker and containers for the deployment.

You can use the below docker-compose.yml file and have a working site stack in less than a minute.

version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: host.docker.internal
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:latest
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: user1
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: password
    ports:
      - 3306:3306
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

You can run the above composer file with:

docker compose up -d

In order to access the new wordpress installation you should go to 0.0.0.0:8080 or localhost:8080

You can clone the code from the below repository:

https://github.com/geralexgr/wordpress-mysql-containers/

Create a build pipeline and push Image to external repository with Azure Devops

Azure Devops is the powerful Microsoft product for Devops solutions. In this article I will explain how you can create a build pipeline using predefined actions and tools provided in order to push an image to an external repository like Docker hub.

As a first step you should create two new service connections. As I am using Github, the one will be a github connection and a docker hub connection. To accomplish that you should go to project settings -> service connections and connect your accounts with your password credentials.

When you complete this step, the connected accounts will appear.

Then you should go to pipelines menu and create a new one. My pipeline has the name main-pipeline.

Azure Devops provides a large list of predefined tasks that will make your implementation easier and quicker. In my case I selected the build of a Dockerfile that will be listed in the Github repository.

In more detail the code will be checkout from the repository and the image will be created using a building machine that Azure provides from a shared pool of agents.

You can find the pipeline code below:

# Docker
# Build a Docker image
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:
  tag: 'latest'

stages:
- stage: Build
  displayName: Build image
  jobs:
  - job: pushToDocker
    displayName: pushToDocker
    steps:
    - task: Docker@2
      displayName: Build an image
      inputs:
        containerRegistry: 'geralexgr-docker-repo'
        repository: 'geralexgr/aksjavarepo'
        command: 'buildAndPush'
        Dockerfile: '**/Dockerfile'
        tags: latest
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: '$(Build.ArtifactStagingDirectory)'
        ArtifactName: 'drop'
        publishLocation: 'Container'

A successful run of the pipeline is shown below. As the code indicates the tag of the image should be the latest.

The created image will be stored on docker hub as indicated in the instructions.

You can then go and pull your image locally to test the result. In my case I would use:

docker pull geralexgr/aksjavarepo:latest

Create a CI/CD pipeline with Gitlab on container deployments

In order to create a CI/CD pipeline with gitlab built-in functionality you should firstly create the appropriate .gitlab-ci.yml file. This is the file on which the steps will be described for the pipeline.

This file should be placed on the root structure of the branch and every time a commit is pushed on the remote repository the steps will run. Instructions have been provided from gitlab and can be found here

For this example I chose gitlab runner as the building tool and the deployment method of a docker container.

In order to install gitlab runner as a container perform the below steps:

Download the image.

 docker run -d --name gitlab-runner --restart always \
     -v /srv/gitlab-runner/config:/etc/gitlab-runner \
     -v /var/run/docker.sock:/var/run/docker.sock \
     gitlab/gitlab-runner:latest

Create a persistent volume

docker volume create gitlab-runner-config

Stop the container if already started from previous step and run it again with the mapped volume

docker run -d --name gitlab-runner --restart always \     -v /var/run/docker.sock:/var/run/docker.sock \     -v gitlab-runner-config:/etc/gitlab-runner \     gitlab/gitlab-runner:latest

You will see the container running

Register gitlab with your runner. You should get the registration token and runner url from your repository settings.

Inspect container and press gitlab-runner register

Start the runner

gitlab-runner start

The runner should have been registered on your gitlab environment

Perform a commit and push changes to your repository

The run task should have started

Check the pipeline and see its status

The job was not succesful and by checking the logs I could verify that DNS resolution could not be enstablished.

In order to fix that you should add an entry for your named gitlab container to your gitlab runner. Unfortunately there are no tools like vim, nano installed on gitlab-runner. However you can bypass this by echoing a value in your /etc/hosts file.

It is also important that your local computer can resolve by fqdn your gitlab deployment. This is necessary because docker should be able to read this entry and perform actions on it.

After those changes you will be able to run your pipeline successfully.