GitLab isn’t just a place to store your code; it’s a full-blown DevOps platform where code goes from your machine to production with minimal human intervention.
Let’s see it in action. Imagine you’ve got a simple Python web app. You push a change to your GitLab repository.
git add .
git commit -m "Add new feature"
git push origin main
This push triggers a GitLab CI/CD pipeline. You can see this pipeline running in the "CI/CD" -> "Pipelines" section of your GitLab project. It’s a series of stages, often including "build," "test," and "deploy." Each stage runs on a GitLab Runner, a separate agent that picks up jobs from GitLab.
Here’s a .gitlab-ci.yml file, the heart of any GitLab CI/CD setup:
stages:
- build
- test
- deploy
build_app:
stage: build
script:
- echo "Building the application..."
- docker build -t my-python-app:latest .
tags:
- docker
run_tests:
stage: test
script:
- echo "Running unit tests..."
- pip install -r requirements.txt
- pytest tests/
tags:
- python
deploy_staging:
stage: deploy
script:
- echo "Deploying to staging environment..."
- scp -r ./app staging_user@staging.example.com:/home/staging_user/apps/
- ssh staging_user@staging.example.com "sudo systemctl restart my-python-app"
environment:
name: staging
url: http://staging.example.com
only:
- main
tags:
- ssh
This file defines three stages: build, test, and deploy. The build_app job uses Docker to build an image. The run_tests job installs dependencies and runs pytest. The deploy_staging job uses SSH to copy files to a staging server and restart a service. Notice the environment block, which links the deployment to a specific GitLab environment, making it easy to track deployments. The only: - main ensures this job only runs when changes are pushed to the main branch.
The core problem GitLab CI/CD solves is the manual, error-prone process of getting code from a developer’s machine into a running, tested, and deployed state. It automates this entire workflow, providing visibility and control. You control the pipeline through the .gitlab-ci.yml file, defining stages, jobs, scripts, and when they should run. You control the execution environment through GitLab Runners, which can be configured to run on your own infrastructure or on cloud providers, supporting various execution environments like Docker, Kubernetes, or shell.
The real power comes from the integration. A commit to a branch can trigger a test pipeline. If tests pass, a merge request can be created. Approving the merge request and merging into main then triggers the production deployment pipeline. This entire flow is managed within GitLab, giving you a single pane of glass for your entire software delivery lifecycle.
What most people don’t realize is that environments within GitLab are not just labels; they are active entities that track deployments. When you deploy to a staging environment, GitLab records which commit was deployed there. If you later deploy the same commit to production, GitLab knows that production is now at the same version as staging, and can visually highlight this. This traceability is crucial for rollbacks and understanding what’s running where.
The next step is exploring GitLab’s security scanning features, which can be integrated directly into your pipelines.