Automate Docker Image Building , Tagging And Publishing With Github Actions
Tags: devops, docker, cicd, githubactions
Published: 2024-03-26 06:01:38

Hi devs, today, let's talk about how to automate the process of building and deploying Docker images, you can utilize GitHub Actions. This workflow allows you to:

- **Build a Docker image from your code.**
- **Tag the image with a version number, following semantic versioning principles.**
- **Publish the tagged image to your Docker Hub repository.**

Once you’ve set up this workflow in your GitHub repository, all you need to do is push a new tag to GitHub. The GitHub Action will then automatically build the Docker image, tag it with the same version as your GitHub tag, and push it to Docker Hub.

---

## Let's Start To Code
I use follwing Github Actions in this workflow

- [Docker Metadat Action](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fmarketplace%2Factions%2Fdocker-metadata-action)

- [Build And Push Docker Images](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fmarketplace%2Factions%2Fbuild-and-push-docker-images)

This is my folder and file structure. Dockerfile is in the project root.

```
MyApp
  |__ app/
  |__ Dockerfile
```

Now let's create the workflow file.

- Create a folder named `.github` in the project root
- Inside the `.github` folder, create another folder named `workflows`.
- Inside workflows folder, create a file named `docker_workflow.yaml` (this file can be named as you want. File extension should be .yaml)
- Go to your Github repo settings and create these repository secrets (Settings > Secrets And Variables > Actions > New repository secret. 

```
DOCKERHUB_USERNAME - Your Docker hub username.
DOCKERHUB_TOKEN - Your Dockerhub token 
DH_REPO_NAME - Dockerhub repository name
```

- Copy and paste this code into tha .yaml file
 

```yaml
#NAME
name: Build And Push Images to Dockerhub
#EVENT
on:
  push:
    tags:
      - 'v*'
#JOBS
jobs:
  build_docker_images:
    name: Build Docker Image To Dockerhub
    runs-on: [ubuntu-latest]
    steps:
      - name: Code Checkout
        uses: actions/checkout@v3

      - name: Extract Metadata
        uses: docker/metadata-action@v5
        id: meta
        with:
          images: |
            ${{secrets.DOCKERHUB_USERNAME}}/${{secrets.DH_REPO_NAME}}
          tags: |
            type=semver,pattern={{version}}

      - name: Docker Login
        uses: docker/login-action@v2
        with:
          username: ${{secrets.DOCKERHUB_USERNAME}}
          password: ${{secrets.DOCKERHUB_TOKEN}}
          logout: true

      - name: Build And Push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
```

- Push this code into master branch.

---

## How This Works?
When you want to build and push the Docker image to Docker Hub, simply create a tag with the version you need. This should be follow semantic versionning. For example, create a tag named v1.0.0 and push it.

```bash
git tag v1.0.0
git push origin --tags
```
Now the docker image will be build with the tags 1.0.0 , latest and push it into Docker Hub.

---

## Workflow Breakdown

```yaml
on:
  push:
    tags:
      - 'v*'
```
This section specifies when to trigger the workflow. If you prefer to use branches instead of tags, adjust the conditions accordingly. When a tag with a name starting from 'v' is pushed, the workflow will execute. If you prefer for branches, simply replace 'tags' with 'branches' in the trigger conditions.

```yaml
- name: Extract Metadata
  uses: docker/metadata-action@v5
  id: meta
  with:
    images: |
      ${{secrets.DOCKERHUB_USERNAME}}/${{secrets.DH_REPO_NAME}}
    tags: |
      type=semver,pattern={{version}}
```
Here I use a push event to trigger this workflow. Docker Metadata Action can extract metadata from push events. From the push event, it will get the tag version. Under images, we give a list of docker image names to use. Also I have given an id for this. It will be used in the next section. In the Tags section, we specify how the docker image tagging should happen. Here I used semantic versioning. You can use, branch names, commit hash and etc. Further details can be found on the documentation page of the respective tool or service.

```yaml
- name: Build And Push
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: ${{ steps.meta.outputs.tags }}
```
In this section, Docker images will be pushed into the Docker Hub repository with the tag. The 'context' parameter indicates the location of the Dockerfile. Tags for the Docker images are specified in the 'tags' section. We get the tag from an earlier meta section. That's why I gave an id, meta. Here, I used that id to get the tag.

---

That's all for now. I hope this article will help you. See you from another article. Happy Coding! If this blog is helpful to you, don't forget to give a like

<a href="https://www.buymeacoffee.com/hirushafernando" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png" alt="Buy Me A Coffee" style="height: 71px !important;width: 204px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

You can reach me on

- [My Portfolio](https://hirushafernando.com/)

- [Github](https://github.com/HRS0986)

- [Medium](https://medium.com/@heshanhfernando)

- [LinkedIn](https://www.linkedin.com/in/hirusha-fernando-webdev/)