Total Pageviews

5,441,108

Sunday, 12 January 2025

GitHub Actions vs. GitLab CI/CD

 

I have used both of the popular services for work and quite recently I got my hands on GitHub Actions as well. So, I decided to present an opinionated comparison between CI/CD offerings from both in the context of simply building a docker image of an application and then pushing it to their respective container registry services.

.github/workflows/build-image.yml

name: Docker Image CI

on:
  push:
    branches: [ main ]

env:
  REGISTRY: ghcr.io

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Docker meta
      id: meta
      uses: docker/metadata-action@v3
      with:
        images: backend

    - name: Log in to the Container registry
      uses: docker/login-action@v1
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ github.token }}

    - name: Build and push Docker image
      uses: docker/build-push-action@v2
      with:
        context: ./backend
        push: true
        tags: ghcr.io/my-org/my-repo/backend:${{ github.run_number }}

.gitlab-ci.yml

image: docker:stable

services:
  - docker:dind

build-docker:
  only:
    - master
  tags:
    - docker
  script:
    - docker build -t registry.gitlab.com/my-org/my-repo .
    - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com
    - docker push registry.gitlab.com/my-org/my-repo
  • GitHub takes a more standard and verbose approach compared to GitLab in terms of their .yml file exposing more options for configuration which is why it might be a bit longer to look at.

  • GitHub brings the power of its open-source community by making the pipeline a plug-n-play system where you can bring in already available "actions" that someone else might have already built. In the above case, we are using actions built by docker themselves which is missing on the GitLab side. With GitLab you get more control by writing the commands manually but becomes a repetitive task as well.

  • In GitLab you might need to make some configuration changes from CI/CD settings to enable Shared GitLab Runners but in GitHub that's not required or visible.

  • GitLab will show you all the available runners but with GitHub its transparent and you choose the host os through the configuration yml file. GitHub also supports more host os like MacOS.

  • GitLab designed the pipeline system as a docker container so, in order to spawn our docker container we need a service like dind which stands for docker in docker but with GitHub all of that is abstracted away from us due to using already built actions.

  • You can have your own private hosted runners for both due to compliance reasons.

  • With GitLab you can make a move from their cloud to on-prem host everything on your own but with GitHub, since their platform is not open-source (ironic), you can move between cloud and enterprise on-prem hosting.

I particularly don't prefer one from the other. It basically depends on which service your organization is on. 

from https://mii.hashnode.dev/github-actions-vs-gitlab-cicd

----------------------------------------------------------------------------

Continuous Deployment with GitHub Actions

I decided to take my previous learning of GitHub Actions a bit further to deploy my application on a bare metal Linux server i.e. Continuous Deployment.

Basically following is what I wanted to achieve:

  1. Build and push latest images of my application to a container repository
  2. Docker-compose up the latest images from my server

The first step I had already done in my previous post. For the second step, I wanted to do it manually and then automate that process later.

Following is the manual step I was doing to run the applications on my server:

  1. Use SCP to copy docker-compose.yml file into my remote server from local
  2. SSH login into my server
  3. Docker login to ghcr.io repository where my images were pushed
  4. Docker-compose up the copied docker-compose.yml file

Thanks to already built GitHub Actions available in the marketplace, I was able to automate the above manual process:

name: CD

on:
  push:
    branches: [ main ]

env:
  REGISTRY: ghcr.io
  REPO: my-repo
  BE: backend
  FE: frontend
  ORG: my-org
  QA_DC: docker-compose-qa.yml

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Log in to the Container registry
      uses: docker/login-action@v1
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ github.token }}

    - name: Build Backend
      uses: docker/build-push-action@v2
      with:
        context: ./${{ env.BE }}
        push: true
        tags: ${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.REPO }}/${{ env.BE }}:latest,${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.REPO }}/${{ env.BE }}:${{ github.run_number }}

    - name: Build Frontend
      uses: docker/build-push-action@v2
      with:
        context: ./${{ env.FE }}
        push: true
        tags: ${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.REPO }}/${{ env.FE }}:latest,${{ env.REGISTRY }}/${{ env.ORG }}/${{ env.REPO }}/${{ env.FE }}:${{ github.run_number }}

    - name: Copy files to server
      uses: appleboy/scp-action@master
      with:
        host: ${{ secrets.QA_HOST }}
        username: ${{ secrets.QA_USERNAME }}
        password: ${{ secrets.QA_PASSWORD }}
        port: ${{ secrets.QA_PORT }}
        timeout: 120s
        rm: true
        source: "${{ env.QA_DC }}"
        target: "/${{ env.REPO }}"

    - name: Deploy to server
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.QA_HOST }}
        username: ${{ secrets.QA_USERNAME }}
        password: ${{ secrets.QA_PASSWORD }}
        port: ${{ secrets.QA_PORT }}
        script: |
          echo ${{ secrets.GHCR_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ secrets.GHCR_USERNAME }} --password-stdin
          cd /${{ env.REPO }}
          docker-compose -f ${{ env.QA_DC }} pull ${{ env.FE }} ${{ env.BE }}
          docker-compose -f ${{ env.QA_DC }} up -d --build

The file is pretty much self-explanatory. Using env variables made the script a bit more reusable which I can just copy-paste into my another CD build. secrets are something you would have to set manually in GitHub on organization or repository level. GitHub gives you a complete solution with Github Actions (CI/CD), Github Container Repository (ghcr.io) and Secrets Management as well.

from https://mii.hashnode.dev/continuous-deployment-with-github-actions

 

 

 

No comments:

Post a Comment