What Is GitLab CI/CD?
GitLab CI/CD is a software development tool that allows organizations to implement “continuous” methodologies, including continuous integration (CI), continuous delivery (CD), and continuous deployment (also abbreviated to CD).
Using GitLab CI/CD, you can identify code errors and bugs early in the software development life cycle (SDLC). It helps you ensure that any code you deploy to production adheres to the compliance regulation and coding standards relevant to your applications.
This is part of an extensive series of guides about software development.
GitLab offers three pricing tiers. The free tier offers basic features, useful for individuals. These include 5GB of storage, 10GB of data transfers per month, 400 CI/CD minutes per month, and five users per namespace.
The premium tier costs $19 per month and gives users more control over the DevOps platform and transition to production. It allows you to achieve faster releases with higher visibility and less downtime.
In addition to all free tier features, GitLab Premium offers faster code reviews, advanced CI/CD, agile enterprise planning, reliable self-management functions, and control over releases. It includes 50 GB of storage, 100GB of transfers per month, 10,000 CI/CD minutes per month, and support.
The third tier, Gitlab Ultimate, costs $99 per month and provides better security, planning, and compliance across the enterprise. In addition to everything from the premium tier, it offers advanced security testing, compliance pipelines, and management capabilities (vulnerability, portfolio, and value stream management).
The ultimate tier includes 250 GB of storage, 500GB of transfers per month, 50,000 CI/CD minutes per month, and a free guest user option.
GitLab CI/CD Overview
GitLab Runner is an open source application written in Go that lets you run jobs in a CI/CD pipeline. You can install this application on a self-managed infrastructure and run it as a single binary—there are no language-specific requirements. You can install it on multiple supported operating systems, run it inside a Docker container, or deploy it on a Kubernetes cluster. Learn more in our detailed guide to GitLab ci runner (coming soon)
In GitLab CI/CD, pipelines are top-level components that facilitate continuous integration, deployment, and delivery. Pipelines consist of jobs that define what the pipeline does (compiling or testing code, for example), and stages that define when the pipeline should run a job (running tests after compiling the code).
Runners execute jobs. When there are enough concurrent runners, they execute multiple jobs from the same stage in parallel. If all the stage’s jobs succeed, the pipeline can move on to the following stage. However, If any job within a stage fails, the pipeline usually does not execute the next stage and ends early.
Pipelines are typically executed automatically, requiring no intervention once created, but you can manually interact with a pipeline if needed.
A pipeline often consists of four stages, executed as follows:
- A build stage, including a compile job.
- A test stage, including two testing jobs called test1 and test2.
- A staging stage, including a deploy-to-stage job.
- A production stage, including a deploy-to-prod job.
Learn more in our detailed guide to GitLab CI/CD pipeline
Pipeline configuration requires using jobs, which are the fundamental component of a .gitlab-ci.yml file. You define jobs using constraints that state the conditions required to execute the job.
Each job is a top-level element including an arbitrary name and containing at least a script clause. There is no limit as to how many jobs you can define. You can access the pipeline to see all jobs related to that pipeline.
A CI/CD variable is an environment variable you can use to control the behavior of pipelines and jobs, store values for reuse, and avoid hard-coding values in a .gitlab-ci.yml file. GitLab lets you use predefined CI/CD variables or define your own custom variables.
GitLab Caches and Artifacts
A cache consists of one or several files that a job downloads and saves. Any subsequent job using the same cache does not have to download these files again, enabling them to execute more quickly.
You can use cache in GitLab for dependencies, like packages downloaded from the Internet. When distributed cache is enabled, GitLab stores your cache in the same location your GitLab Runner is installed and uploaded to S3.
GitLab lets you use artifacts to shift intermediate build results between different stages. A job can generate artifacts, and the pipeline stores them in GitLab, where you can download them. Artifacts and caches can define their paths relative to the project directory and cannot link to files outside the directory.
The .gitlab-ci.yml File
You can use GitLab CI/CD only if you host application code in a Git repository and include a .gitlab-ci.yml file in the repository’s root. The .gitlab-ci.yml file contains your CI/CD configuration.
The .gitlab-ci.yml file lets you define scripts to run, additional configuration files and templates, and dependencies and caches. You can also define specific commands to run in sequence, commands to run in parallel, the desired deployment location for your application, and specify whether you want to trigger scripts manually or run them automatically.
Once you add a .gitlab-ci.yml file to a Git repository, GitLab detects it and employs a GitLab Runner to run any script defined in the job.
Learn more in our detailed guide to GitLab CI YAML
When configuring CI/CD, you need to specify an image to create a container where jobs run. You can specify this image using the image keyword and define an additional image using the services keyword.
The pipeline uses this additional image to create another container, making it available to the first container. These two containers get access to each another and can communicate when they run the job.
You can use the service image to run any application. However, it is typically used to run a database container, such as MySQL, Redis, PostgreSQL, and GitLab. A service inherits the same search domains, DNS servers, and other hosts as the CI container uses.
GitLab ChatOps lets you interact with CI/CD jobs using chat services like Slack. Chat services often facilitate discussions, collaboration, and troubleshooting. The ability to run CI/CD jobs and post the output to a chat channel can help significantly augment a team’s workflow.
GitLab Testing and Security
GitLab CI/CD can help test all changes in a feature branch. It can check an application for various security vulnerabilities, such as unauthorized access, Denial of Service (DoS), and data leaks.
GitLab can analyze the application on a schedule or as part of a CI/CD pipeline, checking the source code, vulnerabilities in a running web application, dependencies in projects or container images, and infrastructure as code (IaC) configuration. It also lets you display reports and link to important information directly from your merge requests.
GitLab for GitOps
GitLab provides a single application for CI/CD, version control, and code review. It offers tight integration with Vault and HashiCorp Terraform and multi-cloud capabilities for infrastructure automation.
You can store your environment as code in GitLab version control, using it as a single source of truth (SSoT). GitLab CI/CD for infrastructure automation can reconcile your environments with your SSoT in version control.
Teams can use GitLab planning and code review to collaborate. The same tool can help plan, version, and deploy an application code to ensure it also works for operations code.
You can combine GitLab, GitOps, and Kubernetes to create a more efficient workflow. It enables you to set up GitLab as the GitOps operator, Kubernetes as the convergence and automation system, and GitLab CI/CD for CI and the agent for CD.
You can also leverage built-in automatic drift remediation and set up resource management using server-side applies to achieve transparent multi-actor field management.
GitLab CI/CD Quick Start Tutorial
GitLab can be installed on most GNU/Linux distributions, multiple cloud providers, and within Kubernetes clusters. There are several installation methods including a Linux package, a Helm chart and a Docker container.
Ensure you have runners available
In GitLab, runners are agents that run CI/CD tasks.
There may already be runners available for your project, including shared runners that can be used by all projects in your GitLab instance.
To see available runners, click Settings > CI/CD > Runners.
If there is at least one active runner with a green circle next to it, this means there are runners available to handle the task. However, if there are no active runners, the user or administrator must install GitLab Runner and register at least one runner.
Create a .gitlab-ci.yml file
The .gitlab-ci.yml file is a YAML file that organizes specific instructions for GitLab CI/CD.
In this file, you define the structure and sequence of tasks executed by the runner, and how the runner makes decisions when faced with specific situations.
For example, when committing to a branch which is not the default branch, you can run a series of tests, but when you commit to the main branch, you can automatically deploy the app and run a different set of tests suitable for a staging environment.
To create a .gitlab-ci.yml file:
- From the left sidebar, select Project information > Details.
- Above the list of files, select the branch you want to commit to, choose the plus icon, and click New File.
.gitlab-ci.ymlas the file name and paste the following sample code into the text window. This code is taken from the GitLab documentation.
build-job: stage: build script: - echo "Hello, $GITLAB_USER_LOGIN!" test-job1: stage: test script: - echo "This job tests something" test-job2: stage: test script: - echo "This job tests something, but takes more time than test-job1." - echo "After the echo commands complete, it runs the sleep command for 20 seconds" - echo "which simulates a test that runs 20 seconds longer than test-job1" - sleep 20 deploy-prod: stage: deploy script: - echo "This job deploys something from the $CI_COMMIT_BRANCH branch." environment: production
$CI_COMMIT_BRANCH are predefined variables that populate when the job runs.
When done, click Commit changes and wait for the commit to complete. The pipeline then starts automatically.
Learn more in our detailed guide to GitLab CI CD tutorial
GitLab CI/CD Best Practices
Use Caches and Artifacts Effectively
In GitLab, a cache provides the ability to save one or more files a job downloads. Subsequent jobs can use the same cache – this means they don’t have to download the files again, allowing them to execute more quickly.
To ensure maximum availability of the cache, tag runners and use the tag on jobs that share the same cache. Ensure you only use runners that are available for a particular project. Finally, use a key for each workflow (for example, you could have a different cache for each branch in your project).Read the Documentation
GitLab provides extensive documentation that is frequently updated to reflect its latest features. Refer to the README or other accessible documentation format. Team members should review the documentation and create bookmarks and frequently asked questions to share with new team members.
Optimize Pipeline Stages
To get the most out of your GitLab CI pipeline, optimize stages to make failures easy to identify and fix. In many cases it is not optimal to organize similar jobs into stages. You may have jobs in the pipeline that you can safely run in earlier stages, without negatively impacting your project in case of failure. Try moving jobs as early in the pipeline as possible to speed up pipeline execution.
Use Failures to Improve Processes
Create a culture of continuous improvement, by helping teams handle failure more easily. Instead of asking who caused a failure, ask why something failed. This can help your team transition from a culture of blame to a culture of learning.
If your team commits frequently, it’s much easier to identify and fix issues. If there is a pattern in the failed build, investigate the root cause. Check if there are bugs outside of your code that are causing unnecessary builds—if so, you can include an allow_failure parameter.
Test Environments Should Mirror Production
In continuous integration, every commit triggers a build. These builds then run tests to see if anything is breaking, because of the code changes they introduce.
The “test pyramid” is a good way for developers to think about how to balance their tests. End-to-end testing is primarily used as a safeguard (with relatively few tests), whereas unit testing is most often used to identify bugs (with many tests).
An important thing to keep in mind when testing is the environment. Matching test and production environments gives developers confidence to deploy their results. GitLab provides the Review Apps feature, which puts new code into a production-like live environment to visualize code changes. This helps developers evaluate the impact of changes
Combine GitLab with Codefresh to Support GitOps and Kubernetes Deployments
GitLab is a very powerful platform but it is focused mostly on CI and does not support GitOps and native Kubernetes deployments. Codefresh is created specifically for GitOps and Cloud native applications and includes native support for using GitLab as a Git provider.
This means that you can get the best of both worlds by keeping all your CI workflows in GitLab, while using Codefresh for advanced features such as:
- Application dashboards
- Git source managements
- Configuration drift management
- Kubernetes environment dashboards
- Topology views
In case you are new to Codefresh – we have made it our mission since 2014 to help teams accelerate their pace of innovation. Codefresh recently released a completely rebuilt GitOps CI/CD toolset. Powered by Argo, Codefresh now combines the best of open source with an enterprise-grade runtime allowing you to fully tap the power of Argo Workflows, Events, CD, and Rollouts. It provides teams with a unified GitOps experience to build, test, deploy, and scale their applications.
The World’s Most Modern CI/CD Platform
A next generation CI/CD platform designed for cloud-native applications, offering dynamic builds, progressive delivery, and much more.Check It Out