GitLab Platform
GitLab is a single-application DevSecOps platform that covers the entire software development lifecycle — from planning and source control to CI/CD, security scanning, package registries, and monitoring. Unlike GitHub, which assembles its lifecycle from many separate products, GitLab's pitch is that everything lives in one integrated tool. It comes in two flavors: GitLab.com (the SaaS offering hosted by GitLab) and self-managed GitLab, which you install on your own infrastructure (popular with enterprises that need full control over their data).
SaaS vs self-hosted
GitLab.com (SaaS): fully managed, no maintenance, automatic upgrades. Best for teams that want zero ops overhead.
Self-managed: install on your own servers, VMs, or Kubernetes. You control upgrades, backups, and data residency — required by many regulated industries.
GitLab Dedicated: single-tenant SaaS where GitLab manages a dedicated instance for you (compliance without self-hosting ops).
Editions: the Community Edition (CE) is open source and free; the Enterprise Edition (EE) adds paid features and can run on the free tier with reduced functionality.
Core features
Repositories: Git hosting with unlimited private repos on all tiers, file locking, and large file storage (LFS).
Merge Requests (MRs): GitLab's term for what GitHub calls Pull Requests — code review with inline comments, approval rules, and merge trains.
Issues: track bugs and tasks with labels, milestones, weights, time tracking, and linked MRs.
Epics: group related issues across projects into a larger initiative (Premium and above).
Boards: Kanban-style issue boards for visualizing and managing workflow.
GitLab CI/CD: a first-class, built-in pipeline engine configured via
.gitlab-ci.yml.Container Registry: a built-in Docker/OCI image registry tied to each project.
Package Registry: host npm, Maven, NuGet, PyPI, Composer, and more.
Security scanning: SAST, DAST, dependency scanning, container scanning, and secret detection.
GitLab Pages: free static site hosting from any project.
Wiki and Snippets: per-project documentation and shareable code fragments.
GitLab CI/CD
GitLab CI/CD is one of the platform's strongest features. Pipelines are defined in a .gitlab-ci.yml file at the root of your repository. Pipelines are made of stages that run sequentially, and jobs within a stage that run in parallel. Jobs execute on runners — either GitLab's shared runners (included minutes) or your own self-hosted runners.
.gitlab-ci.yml
stages:
- build
- test
- deploy
variables:
NODE_VERSION: "20"
# Cache node_modules between jobs and pipelines
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
build:
stage: build
image: node:${NODE_VERSION}
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
test:
stage: test
image: node:${NODE_VERSION}
script:
- npm ci
- npm run test -- --coverage
coverage: '/Statements\s*:\s*([0-9.]+)%/'
deploy_production:
stage: deploy
image: alpine:latest
script:
- echo "Deploying to production..."
- ./scripts/deploy.sh
environment:
name: production
url: https://example.com
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manualStages run in order (build, then test, then deploy); a stage starts only when the previous one succeeds.
Jobs in the same stage run in parallel across available runners.
Artifacts pass build outputs (like
dist/) from one job to the next.Rules control when jobs run — by branch, by changed files, manually, or on schedules.
Environments track deployments and give you one-click rollback to a previous deploy.
GitLab CI/CD predefined variables like
$CI_COMMIT_BRANCHand$CI_PIPELINE_IDare injected automatically.
The GitLab Flow
GitLab Flow is a branching strategy that sits between the simplicity of GitHub Flow and the complexity of Git Flow. It pairs a single long-running main branch with environment branches or release branches, so code flows in one direction toward production.
Feature branches are created off
mainand merged back via Merge Requests.Environment branches (e.g.
staging,production) represent deployed states — you mergemainintostaging, thenstagingintoproduction.Code only ever flows downstream (main to staging to production), never the reverse, which keeps environments predictable.
For versioned software, use release branches (e.g.
2-3-stable) and cherry-pick fixes frommaininto them.Every change goes through an MR, so review and CI happen before anything reaches an environment branch.
Plan comparison
Feature | Free | Premium ($29/user/mo) | Ultimate ($99/user/mo) |
|---|---|---|---|
Private repos | Unlimited | Unlimited | Unlimited |
CI/CD minutes (shared) | 400/mo | 10,000/mo | 50,000/mo |
Merge Requests | Yes | Yes | Yes |
Code review approval rules | No | Yes | Yes |
Merge trains | No | Yes | Yes |
Epics & roadmaps | No | Yes | Yes |
Multiple approvers | No | Yes | Yes |
SAST / Secret detection | Yes (basic) | Yes | Yes |
DAST / Dependency scanning | No | No | Yes |
Container scanning | No | No | Yes |
Security dashboards | No | No | Yes |
Compliance & audit | No | Limited | Full |
Support | Community | Next business day | Priority |
The glab CLI
glab is GitLab's official command-line tool (the equivalent of GitHub's gh). It lets you create Merge Requests, manage issues, view pipelines, and more without leaving the terminal.
Common glab CLI commands
# Install brew install glab # macOS sudo apt install glab # Ubuntu (via GitLab repo) winget install glab.glab # Windows # Authenticate glab auth login # Create a merge request from the current branch glab mr create --title "Add checkout flow" --description "Implements cart checkout" # List open merge requests glab mr list # Check out an MR locally glab mr checkout 42 # Approve and merge glab mr approve 42 glab mr merge 42 --squash # Create an issue glab issue create --title "Login fails on Safari" --label bug # View the latest pipeline status glab ci status # Watch a running pipeline in real time glab ci view # Trigger a new pipeline on the current branch glab ci run
Container Registry and Package Registry
Every GitLab project ships with a built-in Container Registry, so you can build and push Docker images straight from a pipeline without a third-party registry. Authentication uses the $CI_REGISTRY variables that GitLab injects automatically.
Building and pushing an image in .gitlab-ci.yml
build_image:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"The Package Registry hosts npm, Maven, NuGet, PyPI, Composer, Conan, and Helm packages.
Cleanup policies can automatically prune old image tags to save storage.
Images are namespaced under the project, e.g.
registry.gitlab.com/group/project.
Built-in security scanning
GitLab embeds security scanning directly into the pipeline. You enable most scanners by including GitLab's pre-built CI templates. Results appear right inside the Merge Request, so vulnerabilities are caught before code is merged.
Scanner | What it does | Tier |
|---|---|---|
SAST | Static analysis of source code for security flaws | Free (basic) |
Secret detection | Finds committed API keys, tokens, and passwords | Free |
Dependency scanning | Flags known CVEs in your dependencies | Ultimate |
DAST | Dynamic testing of a running app for runtime vulnerabilities | Ultimate |
Container scanning | Scans Docker images for vulnerable OS packages | Ultimate |
License compliance | Detects dependency licenses that violate policy | Ultimate |
Enabling security scanners via templates
include: - template: Jobs/SAST.gitlab-ci.yml - template: Jobs/Secret-Detection.gitlab-ci.yml - template: Jobs/Dependency-Scanning.gitlab-ci.yml - template: Jobs/Container-Scanning.gitlab-ci.yml stages: - test
GitLab Pages
GitLab Pages serves static websites directly from a project. You build your site in a CI job and place the output in a public/ directory; a special job named pages publishes it. It works with any static site generator and supports custom domains and free HTTPS.
Deploying a static site with GitLab Pages
pages:
stage: deploy
image: node:20
script:
- npm ci
- npm run build
- mv build public
artifacts:
paths:
- public
rules:
- if: '$CI_COMMIT_BRANCH == "main"'GitLab vs GitHub
Aspect | GitLab | GitHub |
|---|---|---|
Code review unit | Merge Request (MR) | Pull Request (PR) |
Built-in CI/CD | GitLab CI/CD (.gitlab-ci.yml) | GitHub Actions |
Self-hosting | First-class, open-source CE | GitHub Enterprise Server |
Container registry | Built in, per project | GitHub Packages |
Security scanning | Built in (SAST/DAST/etc.) | Advanced Security add-on |
Issue hierarchy | Epics > Issues > Tasks | Issues + Projects |
Philosophy | One integrated DevSecOps app | Marketplace + ecosystem |
AI assistant | GitLab Duo | GitHub Copilot |