Skip to main content
GitLab CI
CHAPTER 07

Deployment Automation

Updated: May 15, 2026
25 min read

# CHAPTER 7

Deployment Automation

1. Introduction

We have reached the pinnacle of the DevOps pipeline: Continuous Deployment. The tests have passed in the test stage, and the artifact has been built in the build stage. Now, the deploy stage must take that artifact and securely push it to a live production server, making it accessible to the world. In this chapter, we will learn how to configure deployment pipelines. We will explore deploying via SSH to traditional web servers, utilizing multi-environment workflows (Staging vs. Production), and implementing manual approval gates to control when deployments occur.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the operational goals of the deploy stage.
  • Configure a GitLab CI job to execute an SSH deployment.
  • Utilize the environment keyword to track deployments.
  • Implement rules to restrict deployments to the main branch.
  • Implement manual approval triggers (when: manual).

3. Beginner Explanation

Imagine a newspaper printing press.
  • The Build Stage: The journalists finish typing the articles. The layout team finalizes the digital PDF of the newspaper page.
  • The Test Stage: The Editor-in-Chief proofreads the PDF to ensure there are no typos.
  • The Deploy Stage: The Editor hits a large red button. The digital PDF is instantly sent over a secure wire to the massive physical printing presses in the basement. The machines turn on, ink hits paper, and the newspaper is printed and thrown onto delivery trucks.

Deployment Automation is the wire connecting the Editor's desk to the printing press. Nobody has to walk downstairs with a USB drive.

4. Anatomy of a Deployment Job

Deploying code is essentially just having the GitLab Runner log into your remote web server and run a command (like git pull or docker run). The most common way to do this is via SSH (Secure Shell).
yaml
123456789101112131415161718192021222324
deploy_to_production:
  stage: deploy
  image: alpine:latest
  
  # 1. Ensure the Runner has an SSH key to log into the server securely
  before_script:
    - apk add --no-cache openssh-client
    - mkdir -p ~/.ssh
    - echo "$PRIVATE_SSH_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan $SERVER_IP >> ~/.ssh/known_hosts
  
  # 2. Log into the remote server and deploy the code
  script:
    - ssh user@$SERVER_IP "cd /var/www/html && git pull origin main && restart-server"
    
  # 3. Tell GitLab this is a deployment job
  environment:
    name: production
    url: https://my-website.com
    
  # 4. CRITICAL: Only run this job if code is pushed to the main branch
  only:
    - main

5. Multi-Environment Workflows

Professional teams do not test new features directly on the production server. They use a Staging environment.
  • Staging: An exact clone of the live website, but hosted on a secret URL (e.g., staging.my-website.com).
  • Production: The live website.

You can configure GitLab to deploy to Staging automatically on every commit, but deploy to Production *only* when code is merged into main.

6. Mini Project: Manual Approval Gates

Sometimes you want the pipeline to build everything automatically, but you want a human to click a button before it actually goes live (perhaps to wait for a marketing announcement).

We can add a simple rule to our deployment job:

yaml
123456789
deploy_to_production:
  stage: deploy
  script:
    - echo "Deploying to production..."
  environment: production
  only:
    - main
  # This pauses the pipeline until a human clicks the "Play" button in the UI!
  when: manual 

Step-by-Step Walkthrough:

  1. 1. Add the code above to your .gitlab-ci.yml.
  1. 2. Commit and push.
  1. 3. Go to the GitLab Pipelines dashboard.
  1. 4. You will see the pipeline run, but the deploy stage will have a "Paused" symbol ||.
  1. 5. The deployment will not execute. It waits indefinitely until you click the literal Play ▶ button next to it. You have instituted a manual Continuous Delivery gate!

7. Tracking Environments in GitLab

When you use the environment: name: production keyword, GitLab does something magical. On the left sidebar of your project, click Deployments -> Environments. GitLab creates a dashboard showing a history of exactly which commit is currently live on the Production server, who deployed it, and when. If a deployment breaks the site, there is a giant "Rollback" button on this dashboard that instantly redeploys the previous, working version of the code.

8. Best Practices

  • Immutable Artifacts: The golden rule of CI/CD is "Build Once, Deploy Many." Never recompile your code or rebuild your Docker image in the deployment stage. The exact artifact that was built in Stage 1 and tested in Stage 2 is the exact artifact that must be deployed in Stage 3. This guarantees that what you tested is exactly what is running in production.

9. Common Mistakes

  • Deploying Feature Branches: Forgetting to add the only: - main rule to your deployment job is a massive security risk. If a junior developer pushes an experimental feature branch named feature/broken-ui, the pipeline will trigger and instantly deploy their broken, unreviewed code over the live production website.

10. Exercises

  1. 1. Why is it a critical security requirement to restrict production deployment jobs to the main branch?
  1. 2. What is the operational difference between configuring a job with when: always versus when: manual?

11. FAQs

Q: Can GitLab CI deploy to AWS, Azure, and Google Cloud? A: Yes! GitLab CI is completely platform-agnostic. Because it relies on standard Docker containers and terminal commands, you can deploy to any cloud provider on earth simply by executing their respective CLI commands (like aws s3 sync) in your script block.

12. Summary

In Chapter 7, we achieved the ultimate goal of DevOps: Continuous Deployment. We transitioned from testing theoretical code to executing tangible network operations, utilizing SSH to securely connect our pipeline runners to live remote servers. We established the necessity of multi-environment workflows, separating volatile Staging areas from pristine Production environments. By implementing branch restrictions and manual approval gates, we engineered a deployment pipeline that is both aggressively fast and architecturally safe.

13. Next Chapter Recommendation

Our pipeline logs into a live server using a highly sensitive SSH key. Where exactly did we hide that key? If we put it in the YAML file, hackers will steal it. Proceed to Chapter 8: GitLab CI Security Best Practices.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·