Published on: September 2, 2025
16 min read
Learn how GitLab supports Rust development through its CI/CD capabilities, security scanning, dedicated Rust integrations, AI features, and more.
Rust has emerged as one of the most beloved programming languages due to its performance, memory safety, and concurrency features. As Rust adoption continues to grow, many developers are looking for robust CI/CD platforms to support their Rust projects.
GitLab's appeal to Rust developers extends beyond simple code hosting. The platform offers robust CI/CD capabilities that align perfectly with Rust's emphasis on safety, performance, and reliability. GitLab makes it easy to create repositories and use off-the-shelf Docker containers to put together custom CI jobs. Developers can easily set up automated testing, cross-platform builds, and documentation generation. The platform's integrated approach to DevSecOps resonates with Rust's philosophy of providing comprehensive tooling out of the box.
Being interested in how mortgage rates affect monthly payments and how hard it is to to afford a house in the current times, I decided to write a mortgage calculator in Rust, which I will use as an example throughout this tutorial. Feel free to import this project and follow along.
The mortgage calculator will help users calculate monthly mortgage payments, including principal, interest, property taxes, insurance, PMI, and HOA fees. It provides a modern, intuitive GUI using the egui framework, as well as a CLI for running it in the terminal.
This application contains a .gitlab-ci.yml
that generates a pipeline, which will build, test,
package, scan, and deploy the software. We will go over this pipeline definition in detail in the
sections below.
GitLab's Docker-based CI/CD system excels at Rust development workflows, providing a robust foundation for compilation, testing, and code quality checks. The platform's caching mechanisms are particularly valuable for Rust projects, which can have lengthy compilation times due to the language's thorough optimization and safety checking processes.
Rust's excellent cross-compilation capabilities combined with GitLab's flexible CI/CD system create a powerful solution for building applications across multiple platforms. This is particularly valuable for Rust applications that need to run on various operating systems and architectures without sacrificing performance or requiring platform-specific code.
Note: You can learn more about the .gitlab-ci.yml
by reading the CI/CD YAML syntax reference.
# Cache configuration to speed up builds by reusing dependencies
cache:
key: $CI_COMMIT_REF_SLUG # Use branch name as cache key
paths:
- .cargo/ # Cache Cargo registry and git dependencies
- target/ # Cache compiled artifacts
# Base template for Rust jobs - shared configuration
.rust-template:
image: rust:$RUST_VERSION-slim # Use slim Rust image for faster downloads
before_script:
# Install system dependencies required for building the Rust application
- apt-get update && apt-get install -y pkg-config libssl-dev libgtk-3-dev libxcb-shape0-dev libxcb-xfixes0-dev
# Template for cross-compilation build jobs
.build-template:
extends: .rust-template # Inherit from rust-template
stage: build # Execute during build stage
script:
- rustup target add $TARGET # Add the target platform for cross-compilation
- cargo build --release --target $TARGET # Build optimized release binary for target platform
# Build for Linux x86_64 (primary target platform)
build-linux:
extends: .build-template # Use build template configuration
variables:
TARGET: x86_64-unknown-linux-gnu # Linux 64-bit target
artifacts:
paths:
- target/$TARGET/release/mortgage-calculator # Save the compiled binary
expire_in: 1 week # Keep artifacts for 1 week
allow_failure: false # This build must succeed
# Build for Windows x86_64 (cross-compilation)
build-windows:
extends: .build-template # Use build template configuration
variables:
TARGET: x86_64-pc-windows-gnu # Windows 64-bit target
artifacts:
paths:
- target/$TARGET/release/mortgage-calculator # Save the compiled binary
expire_in: 1 week # Keep artifacts for 1 week
allow_failure: true # Allow this build to fail (cross-compilation can be tricky)
# Build for macOS x86_64 (cross-compilation)
build-macos:
extends: .build-template # Use build template configuration
variables:
TARGET: x86_64-apple-darwin # macOS 64-bit target
artifacts:
paths:
- target/$TARGET/release/mortgage-calculator # Save the compiled binary
expire_in: 1 week # Keep artifacts for 1 week
allow_failure: true # Allow this build to fail (cross-compilation can be tricky)
This GitLab CI configuration defines three build jobs that cross-compile a Rust mortgage calculator application for different platforms:
build-linux
creates a Linux x86_64 binary (required to pass)build-windows
creates Windows binaries (allowed to fail)build-macos
creates macOS x86_64 binaries (allowed to fail)All builds use shared templates for dependency caching and consistent build environments.
GitLab CI/CD streamlines code testing through its integrated pipeline system that automatically
triggers test suites whenever code is pushed to the repository. Developers can define multiple
types of tests — unit tests, integration tests, linting, and formatting checks — all within a single
.gitlab-ci.yml
configuration file, with each test running in isolated Docker containers to ensure
consistent environments.
# Run unit tests
test:unit:
extends: .rust-template # Use Rust template configuration
stage: test # Execute during test stage
script:
- cargo test --verbose # Run all unit tests with verbose output
# Run integration tests using the compiled binary
test:integration:
extends: .rust-template # Use Rust template configuration
stage: test # Execute during test stage
script:
# Test the compiled binary with sample inputs and verify expected output
- target/x86_64-unknown-linux-gnu/release/mortgage-calculator --cli calculate --property-value 350000 --down-payment 70000 --interest-rate 5.0 | grep -q "TOTAL MONTHLY PAYMENT"
needs:
- build-linux # Depends on Linux build job completing
# Run Clippy linter for code quality checks
test:clippy:
extends: .rust-template # Use Rust template configuration
stage: test # Execute during test stage
script:
- rustup component add clippy # Install Clippy linter
- cargo clippy -- -D warnings # Run Clippy and treat warnings as errors
allow_failure: true # Allow linting failures (can be improved over time)
# Check code formatting
test:format:
extends: .rust-template # Use Rust template configuration
stage: test # Execute during test stage
script:
- rustup component add rustfmt # Install Rust formatter
- cargo fmt -- --check # Check if code is properly formatted
allow_failure: true # Allow formatting failures (can be improved over time)
This GitLab CI configuration creates four test jobs that validate a Rust mortgage calculator application:
test:unit
runs unit teststest:integration
executes the compiled Linux binary with sample inputs to verify functionalitytest:clippy
performs code quality linting (allowed to fail)test:format
checks code formatting compliance (allowed to fail)GitLab's Package Registry provides a secure solution to the common challenge of sharing internal libraries and proprietary code within organizations. This capability is essential for enterprises and teams that need to maintain artifacts while leveraging the broader Rust ecosystem.
The registry supports generic artifacts with fine-grained access controls that align with GitLab's project permissions. This means teams can share libraries securely across projects while maintaining intellectual property protection and compliance requirements.
Additonally, we can containerize our application and store the container images in GitLab's built-in Container Registry.
This section of our .gitlab-ci.yml
demonstrates how to package and publish Rust applications
as tar archives to GitLab's generic package registry using CI/CD automation.
# Package application as tar archive
package:tar:
image: alpine/curl:8.12.1 # Lightweight image with curl for uploading
stage: package # Execute during package stage
variables:
PACKAGE_NAME: mortgage-calculator.tar.gz # Name of the archive file
script:
# Create tar archive of the Linux binary
- tar -czvf $PACKAGE_NAME target/x86_64-unknown-linux-gnu/release/mortgage-calculator
# Upload archive to GitLab Package Registry using API
- |
curl -v --location --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file $PACKAGE_NAME \
"$CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic/tar/$CI_COMMIT_BRANCH/$PACKAGE_NAME"
artifacts:
paths:
- target/x86_64-unknown-linux-gnu/release/mortgage-calculator # Save binary
- mortgage-calculator.tar.gz # Save archive
expire_in: 1 week # Keep artifacts for 1 week
needs:
- build-linux # Depends on Linux build completing
This GitLab CI configuration defines one packaging job package:tar
that creates a compressed tar archive
of the Linux mortgage calculator binary and uploads it to GitLab's Package Registry, while also saving
both the binary and archive as pipeline artifacts.
The below shows the process of building Dockerfiles and publishing Docker images to GitLab's Container Registry with proper tagging and authentication.
# Package application as Docker image
package:docker:
image: docker:24.0 # Use Docker image for building containers
stage: package # Execute during package stage
services:
- docker:24.0-dind # Docker-in-Docker service for building images
before_script:
# Login to GitLab Container Registry
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG . # Build Docker image with commit SHA tag
- docker tag $DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG $DOCKER_IMAGE_NAME:latest # Also tag as latest
- docker push $DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG # Push tagged image to registry
- docker push $DOCKER_IMAGE_NAME:latest # Push latest image to registry
This GitLab CI configuration defines one Docker packaging job package:docker
that builds a Docker
image of the mortgage calculator application, tags it with both the commit SHA and "latest," and
then pushes both tagged versions to GitLab's Container Registry.
GitLab security scanning provides comprehensive protection that goes beyond Rust's built-in memory safety guarantees. While Rust prevents many common security vulnerabilities at compile time, applications still need protection against dependency vulnerabilities, unsafe code blocks, and logical security issues.
The platform's Static Application Security Testing (SAST) integrates seamlessly with Rust's toolchain, providing automated security analysis as part of the CI/CD pipeline This proactive approach catches security issues before they reach production, supporting both compliance requirements and secure development practices.
GitLab's comprehensive security features including SAST, dependency scanning, secret detection and more can easily be implemented via templates, as seen below. Note: Additional configuration is required to enable SAST for Rust.
# Include GitLab's security scanning templates for DevSecOps
include:
- template: Jobs/SAST.gitlab-ci.yml # Static Application Security Testing
- template: Jobs/Dependency-Scanning.latest.gitlab-ci.yml # Scan dependencies for vulnerabilities
- template: Jobs/Container-Scanning.gitlab-ci.yml # Scan Docker containers for vulnerabilities
- template: Jobs/SAST-IaC.gitlab-ci.yml # Infrastructure as Code security scanning
- template: Jobs/Secret-Detection.gitlab-ci.yml # Detect secrets in source code
Security scanners can be configured similar to how you would configure any GitLab job:
# Configure Semgrep SAST scanning for Rust files
semgrep-sast:
rules:
- if: $CI_COMMIT_BRANCH # Run on any branch
exists:
- "**/*.rs" # Only if Rust files exist
variables:
SAST_EXCLUDED_PATHS: ".cargo/**" # Exclude Cargo cache from scanning
# Scan Docker container for security vulnerabilities
container_scanning:
stage: container-security # Execute during container-security stage
variables:
CS_IMAGE: $DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG # Image to scan
CS_DOCKERFILE_PATH: Dockerfile # Path to Dockerfile for context
needs:
- package:docker # Depends on Docker image being built
When vulnerabilites are detected in a merge request (MR), you can see all the vulnerabilites detected and use the provided information to either resolve or dismiss vulnerabilities.
You also can add Security Policies to require approval before vulnerable code can be merged, or to force scanners to run regardless of what is in the .gitlab-ci.yml
.
You can triage all the vulnerabilities found in your default branch by using the Vulnerability Report:
GitLab Pages provides an excellent platform for hosting Rust documentation, integrating seamlessly with Cargo's built-in documentation generation. This creates a powerful workflow where API documentation, project guides, and examples are automatically generated and deployed with every code change.
The combination of cargo doc
and GitLab Pages enables teams to maintain up-to-date documentation
without manual intervention, ensuring that documentation stays synchronized with code changes.
This is particularly valuable for Rust projects where comprehensive documentation is essential
to understand complex APIs and safety contracts.
The following code shows the CI/CD configuration for automatically generating and deploying Rust documentation using
cargo doc
and GitLab Pages.
# Generate and publish documentation using GitLab Pages
build-documentation:
extends: .rust-template # Use Rust template configuration
stage: build # Execute during build stage
variables:
GIT_SUBMODULE_STRATEGY: recursive # Clone submodules recursively if needed
pages: true # Enable GitLab Pages deployment
script:
- cargo doc --no-deps # Generate documentation without dependencies
- mv target/doc public # Move docs to public directory for Pages
artifacts:
paths:
- public # GitLab Pages serves from public directory
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH # Only run on default branch (main/master)
environment:
name: documentation # Environment name for tracking
url: $CI_PAGES_URL/mortgage_calculator/index.html # Documentation URL
allow_failure: true # Allow documentation build to fail
Once the job is complete, you can see the deployed documentation by visiting the GitLab Environment it has been deployed to.
This allows you to manage multiple versions of the documentation in different envrionments.
The documentation will be deployed consistent with the cargo doc
output:
One of GitLab's greatest strengths is its infrastructure-agnostic approach to deployment. Whether your organization runs on traditional on-premises servers, modern cloud platforms, hybrid environments, or edge computing infrastructure, GitLab's CI/CD system can deploy Rust applications seamlessly across any target environment.
GitLab's deployment flexibility stems from its container-first approach and extensive integration ecosystem. The platform supports deployment to virtually any infrastructure that can run containers, virtual machines, or bare-metal applications. This versatility is particularly valuable for Rust applications, which often need to run in diverse environments ranging from resource-constrained embedded systems to high-performance cloud clusters.
GitLab simplifies Kubernetes deployments by providing built-in cluster integration and pre-configured Docker images that include essential tools like Helm and kubectl, eliminating the need for developers to set up complex deployment environments.
# Deploy application to Kubernetes cluster
deploy:kubernetes:
stage: deploy # Execute during deploy stage
image: registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image:helm-3.10.0-kube-1.24.6-alpine-3.15 # Image with Helm and kubectl
variables:
HELM_HOST: "localhost:44134" # Helm host configuration
HELM_DEPLOY_NAME: mortgage-calc-$CI_COMMIT_REF_NAME # Deployment name based on branch
HELM_DEPLOY_NAMESPACE: calc-app # Kubernetes namespace for deployment
KUBE_CONTEXT: $CI_PROJECT_PATH:rust-mortgage-calculator # Kubernetes context to use
script:
- kubectl config use-context $KUBE_CONTEXT # Set the kubectl context
# Deploy using Helm with custom values and Docker image
- helm upgrade --install $HELM_DEPLOY_NAME chart -f chart/values.yaml
--namespace $HELM_DEPLOY_NAMESPACE
--create-namespace
--set image=$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG
--set calc.name=$HELM_DEPLOY_NAME
needs:
- package:docker # Depends on Docker image being available
This GitLab CI configuration defines one deployment job deploy:kubernetes
that uses Helm to deploy the
mortgage calculator application to a Kubernetes cluster, creating or upgrading the deployment in a
dedicated namespace while using the Docker image built in the previous packaging stage.
GitLab Duo AI features provide significant advantages for Rust development by offering intelligent code suggestions and explanations specifically tailored to the language's unique syntax and patterns.
The GitLab platform supports Rust as one of its directly-supported languages for every IDE, ensuring high-quality code completion and generation that understands Rust's ownership model, memory safety principles, and idiomatic patterns.
GitLab Duo's ability to provide contextual code suggestions while typing helps developers navigate Rust's sometimes complex syntax more efficiently, reducing the learning curve for newcomers and accelerating productivity for experienced developers.
GitLab Duo Chat complements the code suggestions by offering conversational assistance for explaining Rust code sections, debugging compiler errors, and providing guidance on best practices. This is particularly valuable in Rust development where compiler error messages, while helpful, can sometimes be overwhelming for developers transitioning from other languages. The AI can help interpret Rust's detailed error messages and suggest fixes, making the development process more efficient by reducing the time spent deciphering compilation issues.
GitLab Duo Chat can also be used directly from Vulnerability Report to explain a vulnerability. GitLab Duo Vulnerability Explanation represents a significant advancement in making application security more accessible and actionable for development teams. Rather than simply flagging potential issues with cryptic error codes. or technical jargon, AI breaks down each vulnerability's nature, potential impact, and remediation steps in terms that developers at all skill levels can quickly grasp. This democratization of security knowledge accelerates the remediation process, reduces the back-and-forth between security and development teams, and ultimately helps organizations ship more secure code faster:
GitLab Duo also provides Agentic Chat, which serves as an intelligent development companion for Rust
applications, offering context-aware assistance throughout the entire development lifecycle. Developers
can leverage its conversational interface to generate Rust code snippets, scaffold new Rust projects with
appropriate Cargo.toml
configurations, and much more.
GitLab Duo Vulnerability Resolution uses AI to automatically generate specific code fixes for detected security issues, dramatically reducing remediation time from hours to minutes. AI analyzes vulnerable code patterns and proposes precise patches tailored to the project's context, language, and dependencies while maintaining code functionality and style consistency. This automation is particularly effective for common vulnerabilities like SQL injection and cross-site scripting, enabling development teams to maintain velocity while significantly improving their security posture without disrupting the development workflow.
GitLab Duo's AI-powered code review enhances the development process by providing intelligent, automated feedback on MRs before human reviewers engage. AI analyzes code changes for potential bugs, security vulnerabilities, performance issues, and adherence to coding standards, offering contextual suggestions and explanations that help developers catch issues early. By augmenting traditional peer reviews with consistent, immediate AI insights, this feature reduces the burden on senior developers, accelerates the review cycle, and ensures that basic quality checks are consistently applied across all code contributions, ultimately improving code quality while allowing human reviewers to focus on higher-level architectural and business logic concerns.
These are just some of the AI feautures that can be used to allow you to ship more secure Rust software faster than ever. To learn about all the GitLab AI features provided, visit the GitLab Duo solution page.
GitLab provides a complete development platform that matches Rust's comprehensive approach:
Integrated Workflow:
Performance Benefits:
Developer Experience:
GitLab's platform capabilities perfectly complement Rust's strengths, creating an ecosystem where safety, performance, and developer productivity converge. Rust applications on GitLab represent the cutting edge of software development—powered by a platform that understands and enhances the Rust development experience.
To learn more about the benefits of GitLab, sign up for a free trial of GitLab Ultimate with Duo Enterprise.