Skip to Content
All Blogs

GitHub Action to Publish Docker Images on Harbor

11/01/2023

Link

This task is part of the Custom CI/CD Pipeline for the application ChaturMail: AI Email Generator

The GitHub action does the following tasks:

  1. Builds & Pushes Docker Image to Harbor

  2. Update ArgoCD Config

tl;dr following is the complete YAML for the action followed by an explanation

name: BuildAndPushImageOnHarborAndUpdateArgoCDConfig

on:
  push:
    branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: docker/login-action@v1
      with:
        registry: harbor.example.com
        username: ${{ secrets.HARBOR_USERNAME  }}
        password: ${{ secrets.HARBOR_PASSWORD }}

    - uses: actions/checkout@v3
    - name: BuildAndPushImageOnHarbor
      run: |
        docker build ./ -t harbor.example.com/chaturmail/chaturmail-backend:${{ github.run_number }}
        docker push harbor.example.com/chaturmail/chaturmail-backend:${{ github.run_number }}

    - name: Clone Repository
      run: |
        git clone <argocd-config-repo-url>
    - name: Install yq
      run: |
        sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
        sudo chmod a+x /usr/local/bin/yq
    - name: Update YAML File
      run: |
        yq -i '.spec.template.spec.containers[0].image = "harbor.example.com/chaturmail/chaturmail-backend:${{ github.run_number }}"' 'argocd-configs/chaturmail-pod.yaml'

    - name: Push to Repo
      run: |
        git config --global user.name "${{secrets.USERNAME_GITHUB}}"
        git config --global user.email "${{secrets.EMAIL_GITHUB}}"
        cd argocd-test-configs
        git add .
        git commit -m "Updated by GitHub Actions"
        git push <argocd-config-repo-url> --all

Building and Pushing Docker Image to Harbor

Harbor is self-hosted on a VPS server and is exposed as a registry.

Logging in to Harbor

Login is done using the docker login action. The registry URI, username, and password need to be provided. Since Harbor is a docker registry the login works the same as for Docker Hub.

    - uses: docker/login-action@v1
      with:
        registry: harbor.example.com
        username: ${{ secrets.HARBOR_USERNAME  }}
        password: ${{ secrets.HARBOR_PASSWORD }}

Building & Pushing the Image

Shell commands are executed to update and push.

The image is tagged with the desired string which is of the format
<registry-uri>/<harbor-project-name>/<image-tag>:<github.run.number>

The github.run_number is added to keep the tags unique for each image.

Since the action runs on the master branch, the directory is specified as ./

    - uses: actions/checkout@v3
    - name: BuildAndPushImageOnHarbor
      run: |
        docker build ./ -t harbor.example.com/chaturmail/chaturmail-backend:${{ github.run_number }}
        docker push harbor.example.com/chaturmail/chaturmail-backend:${{ github.run_number }}

Updating ArgoCD Config

YAML config for ArgoCD to execute is maintained in a GitHub repo. ArgoCD watches the repo. Any changes to the master branch of the config repo trigger a deployment on the server.

The action updates the image name in the YAML config. ArgoCD detects this change and does a deployment using the config file with the new image name.

A shell utility yq is used to edit YAML.

    - name: Clone Repository
      run: |
        git clone <argocd-config-repo-url>

    - name: Install yq
      run: |
        sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
        sudo chmod a+x /usr/local/bin/yq

    - name: Update YAML File
      run: |
        yq -i '.spec.template.spec.containers[0].image = "harbor.example.com/chaturmail/chaturmail-backend:${{ github.run_number }}"' 'argocd-configs/chaturmail-pod.yaml'

Pushing ArgoCD config changes

Shell commands to login into GitHub, add changes to git staging, commit & push

    - name: Push to Repo
      run: |
        git config --global user.name "${{secrets.USERNAME_GITHUB}}"
        git config --global user.email "${{secrets.EMAIL_GITHUB}}"
        cd chaturmail-argocd-configs
        git add .
        git commit -m "Updated by GitHub Actions"
        git push <argocd-config-repo-url> --all

That's all. Check out the pipeline series of blogs.

Check out ChaturMail: AI Email Generator

Keep your secrets safe :-)