Introduction
Continuous Integration and Continuous Deployment (CI/CD) pipelines are essential for modern DevOps workflows. Traditionally, Jenkins has been a go-to tool for CI/CD, but it requires multiple VMs, plugin management, and extensive setup. On the other hand, GitLab CI/CD integrates seamlessly with GitLab repositories, offering a more streamlined and efficient approach. In this blog, we compare GitLab CI/CD with Jenkins, set up a GitLab private runner, and build a full-stack CI/CD pipeline.
Why GitLab CI/CD Over Jenkins?
Jenkins, while powerful, has challenges such as:
Complex setup requiring multiple virtual machines and plugins.
External repository management, as it doesn’t natively store source code.
Higher maintenance effort, especially when integrating various tools.
GitLab CI/CD, on the other hand, offers:
Seamless integration with GitLab repositories, where source code and pipelines exist together.
Built-in security and reliability with centralized control.
Efficient runner management with shared and private runners.
GitLab Runners: Shared vs. Private
GitLab provides two types of runners for executing CI/CD jobs:
Shared Runners: Provided by GitLab, ideal for basic CI/CD workflows.
Private Runners: Custom virtual machines controlled by the user, offering greater flexibility and security.
In enterprise environments, private runners are preferred for better control over dependencies, security, and performance tuning.
Setting Up a Private Runner in GitLab
Step 1: Create a GitLab Project
Log in to GitLab.
Create a new project or use an existing one.
Navigate to Settings > CI/CD > Runners.
Name Runner and create
Select Linux as a platform for runner
Copy command and register runner when we create our Virtual machine
Step 2: Setup a Virtual Machine for Runner
Provision a VM t2.large with the required OS (Ubuntu recommended).
Install jdk-11, maven, trivy,Kubectl,Docker
Install tools
sudo apt update -y #install JDK-11 sudo apt install -y openjdk17-jre-headless #install maven sudo apt install -y maven #install docker sudo apt install -y docker.io && sudo chmod 666 var/run/docker.sock # install trivy sudo apt-get install wget apt-transport-https gnupg lsb-release -y wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list sudo apt-get update sudo apt-get install trivy -y #install kubectl sudo snap install kubectl --classsic
Install GitLab Runner:
# Download the binary for your system sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64 # Give it permission to execute sudo chmod +x /usr/local/bin/gitlab-runner # Create a GitLab Runner user sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash # Install and run as a service sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner sudo gitlab-runner start
Register the runner with GitLab:
Use above commands to register runner with virtual machine
gitlab-runner register --url https://gitlab.com --token glrt-t3_btz1jMFsgJjhe3D_5s5x
Provide GitLab instance URL.
Enter the registration token from GitLab.
Choose an executor (e.g.,
docker
orshell
).
Start the runner:
sudo gitlab-runner run
Building a Full-Stack CI/CD Pipeline
Our pipeline consists of:
Tool Installation – Ensuring dependencies are available.
Unit Testing – Running automated tests.
Dependency Checking – Ensuring dependencies are up to date.
SonarQube Code Quality & Coverage Analysis – Checking code standards.
Docker Image Building – Packaging the application.
Image Scanning with Trivy – Ensuring security compliance.
Deployment to Kubernetes – Deploying the application.
Sample .gitlab-ci.yml
Configuration
stages:
- setup
- test
- build
- security
- deploy
setup:
stage: setup
script:
- echo "Installing dependencies..."
- apt-get update && apt-get install -y curl jq
unit_test:
stage: test
script:
- echo "Running unit tests..."
- pytest tests/
code_quality:
stage: test
script:
- sonar-scanner -Dsonar.projectKey=my_project
build:
stage: build
script:
- docker build -t myapp:latest .
- docker push myrepo/myapp:latest
security_scan:
stage: security
script:
- trivy image myrepo/myapp:latest
deploy:
stage: deploy
script:
- kubectl apply -f k8s/deployment.yaml
Conclusion
GitLab CI/CD simplifies the CI/CD process by integrating directly with GitLab repositories, eliminating the complexity of managing external tools like Jenkins. With a private runner setup and a well-structured pipeline, you can ensure a secure, efficient, and scalable deployment process. If you're looking for a modern, integrated CI/CD approach, GitLab CI/CD is a great choice.
Are you using GitLab CI/CD or Jenkins in your projects? Let us know your thoughts in the comments below!