> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Staging Environment and Canary Deployment with AutoDevOps part 1

> Guide showing how to configure GitLab Auto DevOps for staging and manual canary production deployments, demonstrating incremental rollout, pipelines, security scans, and review apps

In this lesson we implement a canary (incremental) deployment using GitLab Auto DevOps. The pattern we demonstrate is common in CI/CD pipelines:

* Staging: continuous deployment — commits to the default branch are deployed automatically to staging.
* Production: continuous delivery — production deployments are gated by manual approval.

To enable this workflow you configure Auto DevOps (for example set `STAGING_ENABLED=1`) and choose an incremental rollout in manual mode. This allows you to step the production rollout percentage up or down during the deployment lifecycle.

What is an incremental rollout (canary)?
A canary deployment releases a new version to a small subset of running pods/instances first, verifies behavior, then increases the percentage of traffic (or replicas) routed to the new version. If issues appear you reduce or abort the rollout; if the release behaves correctly you continue until 100% of traffic or replicas run the new version.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/W9SEJcpInqKlutTv/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-canary-deployments-docs-page.jpg?fit=max&auto=format&n=W9SEJcpInqKlutTv&q=85&s=d19281c90fb7091c3d854d072363594a" alt="A screenshot of a GitLab Docs webpage titled &#x22;Canary deployments&#x22; showing explanatory text about continuous deployment and use cases. The page includes a left navigation menu, a top search/header bar, and an &#x22;On this page&#x22; sidebar." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-canary-deployments-docs-page.jpg" />
</Frame>

A simple incremental rollout plan might look like:

```text theme={null}
1. rollout 10%
2. rollout 25%
3. rollout 50%
4. rollout 100%
```

With 10 replicas:

* 10% → 1 pod runs the new version, 9 run the old version.
* You can advance to 25%, 50%, etc.
* If something goes wrong you can reduce the rollout percentage. After a 100% rollout the only way to return to the previous version is a rollback to a prior deployment revision.

For more detail, see GitLab’s Auto DevOps documentation and the "incremental rollout" option for UI-managed canary steps: [https://docs.gitlab.com/ee/topics/autodevops/](https://docs.gitlab.com/ee/topics/autodevops/)

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/W9SEJcpInqKlutTv/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-autodevops-deployment-strategy-setup.jpg?fit=max&auto=format&n=W9SEJcpInqKlutTv&q=85&s=e6396ed1f2ad3d8972778c8d47842999" alt="A screenshot of the GitLab Docs page titled &#x22;Auto DevOps deployment strategy,&#x22; showing a table of deployment strategies and setup/methodology details. The left sidebar navigation and page contents for configuring Auto DevOps are also visible." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-autodevops-deployment-strategy-setup.jpg" />
</Frame>

Demo: configure Auto DevOps for staging + manual production

1. In GitLab, open your project → Settings → CI/CD → Auto DevOps.
2. Select “Automatically deploy to staging, manually deploy to production” (the third strategy).
3. Save changes.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/W9SEJcpInqKlutTv/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-ci-cd-autodevops-settings.jpg?fit=max&auto=format&n=W9SEJcpInqKlutTv&q=85&s=e2ea7c9ae4805d5c0c5d7d0c1850dd73" alt="Screenshot of a GitLab project's CI/CD Settings page showing Auto DevOps configuration and deployment strategy radio buttons. The left navigation menu is visible and a blue &#x22;Save changes&#x22; button is shown." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-ci-cd-autodevops-settings.jpg" />
</Frame>

Note: changing the Auto DevOps strategy updates the configuration — it does not necessarily trigger an immediate pipeline run. In a typical workflow:

* Protected branches and protected environments enforce approvals for production.
* Production environments are usually protected, requiring manual approval before deployment.

Verify environment protections at Operate → Environments: [https://docs.gitlab.com/ee/ci/environments/](https://docs.gitlab.com/ee/ci/environments/)

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/W9SEJcpInqKlutTv/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-environments-production-deployment-badges.jpg?fit=max&auto=format&n=W9SEJcpInqKlutTv&q=85&s=c2f8b01010c1b4489f0f7c853e0183f8" alt="A GitLab web UI screenshot showing the &#x22;Environments&#x22; page for a project with entries for production, review/feature/adsa, and staging. The production row shows deployment badges (Success, Needs Approval, Latest Deployed) plus trigger, job, and branch details." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-environments-production-deployment-badges.jpg" />
</Frame>

Preparing a feature branch for the canary demo

For this demo repository (SolarSystemAutoDevOps) I created a feature branch containing small front-end and test changes so Auto DevOps runs the pipeline, deploys a review app, and exercises security scanning.

Files changed:

* `index.html` — replaced an animated GIF with a static PNG and commented out the rotation animation.
* `app.js` — cleaned up logging, ensured static assets are served, and added robust DB fallbacks.
* `tests/hyphen-test.js` — Mocha + Chai integration tests (use of `let` corrected).

Below are the cleaned, relevant snippets.

index.html (static background + commented animation)

```html theme={null}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Solar System - Sid</title>
<link rel="icon" type="image/x-icon" href="https://gitlab.com/sidd-harth/solar-system/-/raw/main/images/saturn.png">

<style>
#planetImage {
  background: url('https://gitlab.com/sidd-harth/solar-system/-/raw/main/images/solar-system.png') center;
  background-repeat: no-repeat;
  background-size: cover;
  position: static;
  /* animation: spin 25s linear infinite; */
  width: 50vw;
  height: 50vw;
}
@keyframes spin {
  100% { transform: rotate(360deg); }
}
body {
  display: flex;
  align-items: center;
  justify-content: center;
  background: url('images/static-background.png');
}
/*.shadow {
  animation: rainbow 2s linear infinite;
}*/
</style>
</head>
<body>
```

app.js (Node/Express + Mongoose — robust and simplified)

```javascript theme={null}
const path = require('path');
const express = require('express');
const OS = require('os');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');

const app = express();

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '/')));
app.use(cors());

mongoose.connect(process.env.MONGO_URI, {
  user: process.env.MONGO_USERNAME,
  pass: process.env.MONGO_PASSWORD,
  useNewUrlParser: true,
  useUnifiedTopology: true
}, function(err) {
  if (err) {
    console.error("MongoDB connection error:", err);
  } else {
    // Connection successful
  }
});

const Schema = mongoose.Schema;

const dataSchema = new Schema({
  name: String,
  id: Number,
  description: String,
  image: String,
  velocity: String,
  distance: String
});

const planetModel = mongoose.model('Planet', dataSchema);

// Example fallback data used if a DB record isn't found (useful for local testing)
const samplePlanets = {
  1: { id: 1, name: 'Mercury', description: 'Closest planet to the Sun' },
  2: { id: 2, name: 'Venus', description: 'Second planet from the Sun' }
};

planetModel.findOne({ id: 1 }, function(err, planetData) {
  if (err) {
    console.error("Error fetching planet data:", err);
  } else {
    // Example usage
  }
});

app.get('/', async (req, res) => {
  res.sendFile(path.join(__dirname, '/', 'index.html'));
});

app.post('/planet', async (req, res) => {
  const id = parseInt(req.body.id, 10);
  if (isNaN(id)) {
    return res.status(400).json({ error: 'Invalid id' });
  }
  try {
    const planet = await planetModel.findOne({ id: id }).lean().exec();
    if (planet) {
      return res.json(planet);
    }
    // Fallback to sample data if DB not available or record missing
    if (samplePlanets[id]) {
      return res.json(samplePlanets[id]);
    }
    return res.status(404).json({ error: 'Planet not found' });
  } catch (err) {
    console.error('Error fetching planet:', err);
    return res.status(500).json({ error: 'Internal server error' });
  }
});

module.exports = app;
```

tests/hyphen-test.js (Mocha + Chai)

```javascript theme={null}
let mongoose = require('mongoose');
let server = require('./app');
let chai = require('chai');
let chaiHttp = require('chai-http');

chai.should();
chai.use(chaiHttp);

describe('Planets API Suite', () => {
  describe('Fetching Planet Details', () => {
    it('should fetch a planet named Mercury', (done) => {
      let payload = { id: 1 };
      chai.request(server)
        .post('/planet')
        .send(payload)
        .end((err, res) => {
          res.should.have.status(200);
          res.body.should.have.property('id').eql(1);
          res.body.should.have.property('name').eql('Mercury');
          done();
        });
    });

    it('should fetch a planet named Venus', (done) => {
      let payload = { id: 2 };
      chai.request(server)
        .post('/planet')
        .send(payload)
        .end((err, res) => {
          res.should.have.status(200);
          res.body.should.have.property('id').eql(2);
          res.body.should.have.property('name').eql('Venus');
          done();
        });
    });
  });
});
```

Commit and workflow

* Commit with a descriptive message such as `testing autodevops canary release`.
* Push as a feature branch (e.g., `feature/canary-deployment`) and create a merge request in the GitLab UI.

Watching the pipeline

When the feature branch pipeline runs, Auto DevOps constructs many stages: build, test, review, security scans (SAST/DAST/container/dependency/secret detection), performance tests, and cleanup. The Pipelines view shows statuses and progress for each run.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-status-badges-list.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=99dacb513236474c9d2f0e7b3aab122e" alt="A screenshot of a GitLab project's Pipelines page showing a list of CI/CD pipelines with status badges (Running, Warning, Canceled, Failed), pipeline names, timestamps, and stage progress indicators. The left sidebar displays project navigation (Pipelines, Jobs, Code, etc.) and the top has filter and action buttons." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-status-badges-list.jpg" />
</Frame>

Common security and quality jobs you might see:

| Job / Feature | Purpose | Example artifact |
| - | - | - |
| dependency\_scanning | Creates a bill-of-materials and finds vulnerable packages | `gl-sbom-*.cdx.json` |
| container\_scanning | Scans Docker images for CVEs (Trivy, etc.) | vulnerability reports |
| code\_quality | Lints and identifies maintainability regressions | inline MR comments |
| dast | Dynamic application scanning of deployed review apps (ZAP) | `gl-dast-report.json` |
| performance/browser tests | Run synthetic performance tests | performance metrics artifacts |

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-autodevops-canary.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=2294780d4548635611b90b94db9e36b1" alt="Screenshot of a GitLab Pipelines page showing a running AutoDevOps canary release with pipeline stages (build, test, review, dast, performance) and a list of jobs like code_quality and container_scanning. The left sidebar shows project navigation (Pipelines, Jobs, Code, etc.)." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-autodevops-canary.jpg" />
</Frame>

<Callout icon="lightbulb" color="#1CB2FE">
  Dependency scanning generates a Software Bill of Materials (SBOM) in CycloneDX format (`gl-sbom-*.cdx.json`) and dependency reports listing package names and versions. DAST uses OWASP ZAP to spider and scan a deployed review environment URL for runtime vulnerabilities.
</Callout>

When the pipeline completes, you can inspect artifacts and generated reports. The dependency scanning job may produce a CycloneDX JSON, and other scanners will upload their corresponding artifacts.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/W9SEJcpInqKlutTv/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-docs-auto-dependency-scanning.jpg?fit=max&auto=format&n=W9SEJcpInqKlutTv&q=85&s=09cf399a997bb3fd60b0478b69fbb928" alt="A screenshot of the GitLab Docs webpage showing the &#x22;Auto Dependency Scanning&#x22; section. The page includes a left sidebar navigation and a right-hand table of contents." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-docs-auto-dependency-scanning.jpg" />
</Frame>

A successful pipeline run shows green checks and produced reports:

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-autodevops-canary-passed.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=941c9707730a0179697e9fe9039beacc" alt="Screenshot of a GitLab Pipelines page for &#x22;testing autodevops canary release&#x22; showing a passed pipeline with stages and green check marks. Visible jobs include code_quality, container_scanning, dast, and browser_performance." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-autodevops-canary-passed.jpg" />
</Frame>

Dynamic Application Security Testing (DAST)

The DAST job boots an OWASP ZAP proxy, retrieves the review environment URL saved by the review job, spiders the site, and runs passive/active scans. The job uploads a `gl-dast-report.json` artifact summarizing findings.

Example (truncated) DAST log excerpt:

```text theme={null}
2024-02-09 18:16:16 Running DAST v4.0.25 on Python 3.10.12
Starting the ZAP Server
Running ZAP with parameters ['/zap/zap.sh', '-daemon', '-host', '0.0.0.0', '-port', '41596', '-dir', '/app/zap', ...]
looking for ZAP at http://127.0.0.1:41596...
Spider starting with target: http://54762898-review-feature-ca-pqok5f.139.84.208.48.nip.io
Spider complete
The following URLs were scanned:
GET https://54762898-review-feature-ca-pqok5f.139.84.208.48.nip.io/
...
PASS: Vulnerable JS Library (Powered by Retire.js) [10003]
WARN: Content Security Policy (CSP) Header Not Set [10038] x 3
PASS: Content-Type Header Missing [10019]
SUMMARY - PASS: 42 | WARN: 6 | SKIP: 12
Uploading artifacts...
gl-dast-report.json: found 1 matching artifact
Job succeeded
```

Review environments and review apps
The review environment deploys the feature branch to a unique URL (often with `-review-feature-...`), enabling manual inspection and runtime scans. Confirm the front-end change (e.g., static background and no rotation) at the review app URL — the environment’s unique pod/identifier is often present in the URL.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/W9SEJcpInqKlutTv/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-environments-dashboard-cards-warnings.jpg?fit=max&auto=format&n=W9SEJcpInqKlutTv&q=85&s=5cd8f5e66ea521bc379cbaf71c909a84" alt="A screenshot of a GitLab &#x22;Environments Dashboard&#x22; showing environment cards for production, staging, and development with deployment details and warning badges. The left-hand GitLab navigation panel is also visible." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-environments-dashboard-cards-warnings.jpg" />
</Frame>

Merge request aggregation: reports and security findings

The merge request aggregates Auto DevOps reports so reviewers can triage issues before merging. From the MR you can:

* View the deployed review app.
* Inspect license compliance details for dependencies.
* Review consolidated security findings (SAST, DAST, container scanning, dependency scanning, secret detection) and create issues from findings.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-solar-system-mr-performance-security.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=025bf6f350fe3e3c01b52a273fbfbd44" alt="A GitLab merge request page for a &#x22;Solar System AutoDevOps&#x22; project showing browser performance test metrics, security scanning findings, and a &#x22;Ready to merge&#x22; section with a Merge button. The left sidebar shows project navigation while the right column displays assignee/reviewer avatars." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-solar-system-mr-performance-security.jpg" />
</Frame>

Example findings visible in the MR:

* SAST findings: e.g., potential Node NoSQL injection.
* DAST warnings: medium/high runtime issues.
* Secret detection: critical findings such as exposed SSH/RSA private keys.
* Container/dependency CVEs flagged by Trivy, Gemnasium, or comparable scanners.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-merge-request-security-scan-findings.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=ec3f72465fa42df43466ea24d5fb6568" alt="A GitLab merge request page displaying security scan findings (critical SSH/RSA private keys and multiple dependency/container vulnerabilities) and a &#x22;Ready to merge&#x22; section. The left sidebar shows project navigation and the right column lists assignee/reviewer and other merge details." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-merge-request-security-scan-findings.jpg" />
</Frame>

Clicking a finding opens a modal with contextual details (CVE, severity, scanner, file/image path) and remediation guidance when available.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-security-cve-2023-4244-trivy.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=be6e268aa4560c6e807361a0ddb7b64c" alt="A screenshot of a GitLab security report modal detailing CVE-2023-4244 (use-after-free) with a description, status &#x22;Needs triage&#x22;, severity marked High, scanner (Trivy) and project/container info. The left side shows the GitLab project navigation for &#x22;Solar System AutoDevOps.&#x22;" width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-security-cve-2023-4244-trivy.jpg" />
</Frame>

The pipeline Security tab collects and filters findings across tools and severities, giving a single pane of glass for vulnerability triage.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-security-scan-ssh-rsa-nosqli.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=41c748ac75e28df1f645cd459264c007" alt="A screenshot of a GitLab project's Security tab showing vulnerability scan results and counts for DAST, SAST, Container Scanning, Dependency Scanning, and Secret Detection. Below that is a list of findings including critical SSH and RSA private key leaks and a high-severity node_nosqli_injection." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-security-scan-ssh-rsa-nosqli.jpg" />
</Frame>

License compliance and code quality

Auto DevOps also surfaces license compliance and code quality results in the pipeline and MR, useful for legal and maintainability reviews before merging.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-licenses-compliance-11.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=36368a060755a7e0ba40a4e802626559" alt="A screenshot of a GitLab project’s Pipelines → Licenses tab showing License Compliance detected 11 licenses and listing entries like Apache License 2.0, BSD 2‑Clause/3‑Clause, MIT, ISC, and others. The left sidebar shows project navigation items (Issues, Merge requests, Pipelines, Jobs)." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-licenses-compliance-11.jpg" />
</Frame>

Final notes and next steps

* Merging to the protected default branch triggers a pipeline that requires manual approval for production deploys. The production job will be gated by environment protection.
* In Part 2 we will merge the feature branch into the protected branch and observe the protected job and the UI-driven incremental rollout (canary) behavior for production. We’ll demonstrate manually stepping rollout percentages in the GitLab UI and handling a rollback.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/fW4IJbgPafxNE8SJ/images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-autodevops-canary-release.jpg?fit=max&auto=format&n=fW4IJbgPafxNE8SJ&q=85&s=7d9b3333d500e9b8b3ea26dbe66268f6" alt="A screenshot of a GitLab Pipelines page for a &#x22;testing autodevops canary release&#x22; showing pipeline stages (build, test, review, dast, performance) with completed jobs indicated by green checkmarks. The left sidebar navigation and pipeline/job details (author, status, duration) are also visible." width="1920" height="1080" data-path="images/GitLab-CICD-Architecting-Deploying-and-Optimizing-Pipelines/Auto-DevOps/Staging-Environment-and-Canary-Deployment-with-AutoDevOps-part-1/gitlab-pipelines-autodevops-canary-release.jpg" />
</Frame>

<Callout icon="warning" color="#FF6B6B">
  Protect production environments and require approvals. Manual gates prevent unreviewed changes from reaching production and give you control over canary steps and rollbacks.
</Callout>

That's all for Part 1 — in the next session we’ll perform the protected merge and exercise the incremental rollout UI to complete the canary deployment to production.

Related links and references

* GitLab Auto DevOps: [https://docs.gitlab.com/ee/topics/autodevops/](https://docs.gitlab.com/ee/topics/autodevops/)
* GitLab CI/CD Environments: [https://docs.gitlab.com/ee/ci/environments/](https://docs.gitlab.com/ee/ci/environments/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/gitlab-ci-cd-architecting-deploying-and-optimizing-pipelines/module/a6a5540f-e7d1-4820-afc8-2be1d6e3061a/lesson/b09a09fc-08c3-4fce-9e44-b4b2f56b98b9" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.