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 fordocker 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:
- Build and push latest images of my application to a container repository
- 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:
- Use SCP to copy
docker-compose.yml
file into my remote server from local - SSH login into my server
- Docker login to
ghcr.io
repository where my images were pushed - 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