From .gitlab-ci.yml basics to production pipelines with security scanning, Docker builds, and Kubernetes deployments for every tech stack.
12
Chapters
30+
Pipelines
100%
Free
01🦊
Introduction to GitLab
All-in-One DevOps Platform
GitLab is a complete DevOps platform in a single application — Git repos, CI/CD pipelines, container registry, security scanning, project management, and monitoring. Unlike Jenkins (CI/CD only) or GitHub (repos + basic actions), GitLab has EVERYTHING built-in. Many enterprises choose GitLab because one tool replaces 5-6 separate tools.
GitLab vs GitHub vs Jenkins
Feature
GitLab
GitHub
Jenkins
CI/CD
Built-in (.gitlab-ci.yml)
GitHub Actions (.yml)
Jenkinsfile (Groovy)
Container Registry
Built-in
GitHub Packages
External (ECR/ACR)
Security Scanning
Built-in (SAST, DAST, SCA)
Third-party Actions
Plugins
Self-Hosted
Yes (GitLab CE/EE)
GitHub Enterprise
Always self-hosted
Project Boards
Built-in
GitHub Projects
None
Best For
Enterprise all-in-one
Open source + community
Max customization
02📝
Pipeline Basics
Your First .gitlab-ci.yml
Every GitLab pipeline is defined in a file called .gitlab-ci.yml at the root of your repository. When you push code, GitLab reads this file and executes the pipeline automatically. Think of it as a recipe — stages are chapters, jobs are steps within each chapter.
Simplest Pipeline
GITLAB-CI.YML# .gitlab-ci.yml — lives in repo root
stages: # Order of execution
- build
- test
- deploy
build-job: # Job name (you choose)
stage: build # Which stage this belongs to
script: # Commands to run
- echo "Building the app..."
- mvn clean package
test-job:
stage: test
script:
- echo "Running tests..."
- mvn test
deploy-job:
stage: deploy
script:
- echo "Deploying to production..."
only:
- main # Only run on main branch
Pipeline Hierarchy
Level
Contains
Example
Pipeline
Stages
One push = one pipeline run
Stage
Jobs
build, test, security, deploy
Job
Scripts + Config
build-java, test-unit, deploy-k8s
Script
Shell commands
mvn package, npm ci, docker build
💡 Key Rule
Jobs in the SAME stage run in parallel. Stages run in order. So all test jobs run simultaneously, but deploy only starts after ALL test jobs pass.
03🚀
Advanced Pipeline Features
Rules, Needs, Cache & Artifacts
Production pipelines need conditional execution, dependency management, caching, and artifact passing between jobs.
rules — Modern Conditional Execution
YAMLdeploy-production:
stage: deploy
script: kubectl apply -f k8s/
rules:
- if: $CI_COMMIT_BRANCH == "main" # Only on main branch
when: manual # Require manual click
- if: $CI_MERGE_REQUEST_ID # On merge requests
when: never # Never deploy from MR
# rules replaces the older only/except syntax
# Common variables:
# $CI_COMMIT_BRANCH → branch name
# $CI_COMMIT_TAG → tag name (v1.0.0)
# $CI_MERGE_REQUEST_ID → MR number
# $CI_PIPELINE_SOURCE → push, merge_request_event, schedule
artifacts — Pass Files Between Jobs
YAMLbuild-app:
stage: build
script:
- mvn clean package -DskipTests
artifacts:
paths:
- target/*.jar # Save the JAR file
expire_in: 1 hour # Auto-delete after 1 hour
deploy-app:
stage: deploy
script:
- ls target/ # JAR is available here!
- cp target/app.jar /opt/app/
needs: [build-app] # Only depends on build-app, not entire stage
cache — Speed Up Builds
YAML# Cache downloads dependencies so they don't re-download every build
build-java:
stage: build
cache:
key: ${CI_COMMIT_REF_SLUG} # Cache per branch
paths:
- .m2/repository/ # Maven dependencies
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
script:
- mvn clean package
build-node:
stage: build
cache:
key:
files: [package-lock.json] # Cache busts when lock file changes
paths:
- node_modules/
script:
- npm ci
- npm run build
04🔐
Variables & Secrets
Configure Pipelines Securely
Variables store configuration values and secrets. Define them in .gitlab-ci.yml (non-sensitive) or in GitLab UI Settings (passwords, tokens, API keys).
GitLab provides 50+ predefined variables: $CI_COMMIT_SHA (commit hash), $CI_REGISTRY (container registry URL), $CI_PROJECT_NAME, $CI_PIPELINE_ID, $CI_JOB_TOKEN (auto-generated token). You never need to configure registry credentials manually!
05🔨
CI Pipeline Examples
Build Every Stack — Java, Node, React, Python, Flutter
Here are production-ready CI pipelines for every major tech stack. Each shows: what the build command does, what artifact it produces, and where to find the output.
After building your app, you package it into a Docker image and push it to a container registry. GitLab has a built-in container registry — no external setup needed.
Build → Push → Deploy Flow
FLOW# The full journey of your code:
# 1. Source code → Build (mvn package / npm build)
# 2. Build artifact → Docker image (COPY jar/dist into container)
# 3. Docker image → Registry (push to GitLab/ECR/ACR)
# 4. Registry → Kubernetes (pull image and run)
Security scanning catches vulnerabilities BEFORE code reaches production. In enterprise CI/CD, every pipeline has security stages between build and deploy. The three main types: SAST (code analysis), SCA (dependency vulnerabilities), and DAST (runtime testing).
Security Scanning Types
🔍
SAST (Static Analysis)
Scans your SOURCE CODE for vulnerabilities — SQL injection, XSS, hardcoded secrets. Runs WITHOUT executing the app. Tools: SonarQube, Fortify, Checkmarx.
📦
SCA (Software Composition)
Scans your DEPENDENCIES (libraries) for known vulnerabilities. "You're using log4j 2.14 which has a critical CVE." Tools: Black Duck, Snyk, Trivy.
🌐
DAST (Dynamic Analysis)
Scans the RUNNING APPLICATION by sending malicious requests. Finds runtime vulnerabilities. Tools: OWASP ZAP, Burp Suite.
🐳
Container Scanning
Scans your Docker IMAGE for OS-level vulnerabilities. "Alpine 3.14 has CVE-2023-xxxx." Tools: Trivy, Grype, Prisma Cloud.
\"Shift Left\" means moving security scanning EARLIER in the pipeline — catch issues during development, not in production. The earlier you find a vulnerability, the cheaper it is to fix. Security in CI is 100x cheaper than a breach in production.
08🚀
Deploy to Kubernetes
EKS, AKS, GKE Deployment
After building the Docker image and passing security scans, deploy it to Kubernetes. The pattern is the same for AWS EKS, Azure AKS, and Google GKE — only the authentication differs.
Deploy to AWS EKS
YAMLdeploy-eks:
stage: deploy
image: bitnami/kubectl:latest
before_script:
- aws eks update-kubeconfig --name my-cluster --region ap-south-1
script:
- kubectl set image deployment/order-service
app=$ECR_REGISTRY/order-service:$CI_COMMIT_SHORT_SHA
-n production
- kubectl rollout status deployment/order-service -n production --timeout=120s
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
Runners are the machines that actually execute your CI/CD jobs. GitLab provides shared runners (free, limited minutes) or you install your own (self-hosted, unlimited).
Runner Type
Where It Runs
Best For
Shared (SaaS)
GitLab.com cloud
Small projects, getting started (400 min/month free)
Group Runner
Your server, shared across group
Team-level, shared by all projects in a group
Project Runner
Your server, specific project
Specialized builds (GPU, large disk, private network)
TERMINAL# Install GitLab Runner on your server
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt install gitlab-runner
# Register runner with your GitLab instance
sudo gitlab-runner register
# URL: https://gitlab.com/ (or your self-hosted URL)
# Token: from Settings → CI/CD → Runners
# Executor: docker (recommended)
# Default image: alpine:latest
# Use Docker executor — every job runs in a fresh container
# Clean, reproducible, isolated builds
11⚡
Advanced Features
Includes, Child Pipelines & Templates
Enterprise GitLab uses includes to share pipeline code, child pipelines for complex workflows, and templates for standardization.
include — Reuse Pipeline Code
YAML# .gitlab-ci.yml — simple, calls shared templates
include:
# From another project
- project: 'devops/pipeline-templates'
file: '/templates/docker-build.yml'
# From a URL
- remote: 'https://company.com/templates/security.yml'
# From same repo
- local: '/ci/deploy.yml'
stages: [build, test, security, docker, deploy]
# All jobs from included files are merged into this pipeline
# Change the template once → all 50 projects get the update
12💼
Interview Questions
GitLab CI/CD Q&A
❓
What is .gitlab-ci.yml?
Pipeline definition file at repo root. Defines stages, jobs, scripts, rules, artifacts, and variables. GitLab reads it on every push and executes the pipeline automatically.
❓
Stages vs Jobs?
Stages define ORDER (build → test → deploy). Jobs define WORK (build-java, test-unit). Jobs in same stage run in parallel. Next stage waits for all jobs to pass.
❓
artifacts vs cache?
Artifacts pass files between jobs (build JAR → deploy JAR). Cache speeds up builds by saving dependencies between pipeline runs (node_modules, .m2/repository).
❓
What are GitLab Runners?
Machines that execute pipeline jobs. Shared (GitLab cloud), Group (shared in org), Project (dedicated). Docker executor = clean container per job.
❓
SAST vs SCA vs DAST?
SAST: scans source code (SonarQube, Fortify). SCA: scans dependencies (Black Duck, Snyk). DAST: scans running app (ZAP). All three are needed for complete security.
❓
rules vs only/except?
rules is modern, more powerful (if/when/exists conditions). only/except is legacy. Always use rules for new pipelines.
❓
How to deploy to K8s?
Build → Docker push to registry → kubectl set image or kubectl apply. Use environment: for tracking. Add when: manual for production approval gate.
❓
GitLab vs Jenkins?
GitLab: all-in-one (repos + CI/CD + registry + security), YAML pipelines. Jenkins: CI/CD only, 1800+ plugins, Groovy pipelines. GitLab is simpler, Jenkins is more customizable.