Support Online
Skip to main content

Installing Continuous Deployment on Ubuntu with GitLab

What will you learn in this guide?

In this guide

oaicite:0

With CI/CD
**

oaicite:1

**on a working server
**

oaicite:2

You will establish a **based automatic distribution line.

After each commit, you will learn the process of producing a Docker image, sending it to the registry, and going live via SSH.
We will set up a production-ready CD structure used in real life, including rollback.

Stage 1 – Technical Analysis (Summary)

Main topic: Installing Continuous Deployment with GitLab CI/CD
Solved problem: Manual deployment, human error and waste of time

Steps followed:

  • Creating a GitLab repo
  • Installing GitLab Runner
  • Deploy securely via SSH
  • Producing and running a Docker image
  • Rollback

Prerequisites

  • Ubuntu 18.04 or above server
  • At least 1 GB RAM, 1 CPU
  • Docker must be installed on the server
  • Container Registry is an open GitLab account
  • sudo authorized, non-root user

Creating a GitLab Project

In GitLab, select New Project → Blank Project.
Set the project name and adjust visibility as needed.

Creating index.html

<html>
<body>
<h1>My Personal Website</h1>
</body>
</html>
  • This file is the sample web page that will be displayed in the browser after deployment.

Creating Dockerfile

  1. Dockerfile
COPY index.html /usr/share/nginx/html
  • This Dockerfile adds static site on Nginx image. Using a fixed version is good practice to avoid surprises in the future.

GitLab Runner Installation

  1. Connect to the server:

ssh deployer@SUNUCU_IP

  1. Install GitLab Runner:

curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt install gitlab-runner
  • This service runs CI/CD jobs.

  1. Save the Runner to the project:

sudo gitlab-runner register -n \
--url https://gitlab.com \
--registration-token PROJE_TOKEN \
--executor docker \
--docker-image docker:stable \
--tag-list deployment \
--docker-privileged
  • This runner only deploys for this project.

Creating Deployment User


sudo adduser deployer
sudo usermod -aG docker deployer
  • This user is used only for deployment operations.

(Yes, the Docker group is as authorized as root — we do it on purpose.)


Generating SSH Key


su deployer
ssh-keygen -b 4096
  • cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
  • CI/CD pipeline connects to the server with this key.

Password is left blank; pipeline is not interactive.


Saving SSH Key to GitLab

  1. GitLab → Settings → CI/CD → Variables
KeyTypeDescription
ID_RSANetSSH private key
SERVER_IPVariableServer IP
SERVER_USERVariabledeployer

ID_RSA variable must be marked as Protected.


.gitlab-ci.yml File


stages:
- publish
- deploy

variables:
TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA

publish:
image: docker:latest
stage: publish
services:
- docker:dind
script:
- docker build -t $TAG_COMMIT -t $TAG_LATEST .
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker push $TAG_COMMIT
- docker push $TAG_LATEST

deploy:
image: alpine:latest
stage: deploy
tags:
- deployment
script:
- chmod og= $ID_RSA
- apk add --no-cache openssh-client
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker rm -f my-app || true"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name my-app $TAG_COMMIT"
environment:
name: production
url: http://SUNUCU_IP
only:
- master
  • This structure produces the Docker image and automatically goes live.

Deploy Verification

  1. GitLab → CI/CD → Pipelines
  • Pipeline status must be Passed.
  1. Check from browser:

http://SUNUCU_IP

  • Verify container on server:

docker ps
  • my-app container must be running.

Rollback

  1. Click Run Again for old deployment

  2. GitLab redeploys the old image

  3. Live system returns to its previous state


Frequently Asked Questions (FAQ)

1. Is this structure suitable for production? Yes, it is very suitable for small and medium-sized projects.

2. Are there other methods instead of SSH? Yes, Kubernetes or GitOps may be preferred.

3. Can I use Shared Runner? Not recommended for security reasons.

4. How to add HTTPS? Nginx + Let's Encrypt or Traefik can be used.

5. Why does rollback fail? The old image may have been deleted from the registry.


Result

With this guide, you've set up a fully automated deployment chain using GitLab CI/CD. After each commit, your application is published automatically.

You can implement this structure in minutes on the GenixNode infrastructure.