Hosting GitLab on Your Private Server with CI/CD: A How-To Guide

👋 Hi, I’m Praduman Prajapati — a DevOps Engineer with hands-on experience in building production-grade CI/CD pipelines, containerized applications, and scalable, secure, and automated cloud infrastructure.
I’ve work on multiple real-world projects including: • Automated CI/CD pipelines using Jenkins, GitHub Actions, and ArgoCD • Kubernetes cluster provisioning and deployment on AWS (EKS and kubeadm) • Containerization and orchestration with Docker and Kubernetes • Infrastructure provisioning and automation using Terraform and Ansible • DevSecOps implementations with Trivy, SonarQube, OWASP, Prometheus, and Grafana • Production-grade deployments of applications on cloud infrastructure
Self-hosting GitLab on a private server gives you full control over your code, repositories, and CI/CD pipelines. It’s a great solution for teams needing privacy and customization. In this guide, I’ll walk you through setting up GitLab with CI/CD using Docker, based on a project I recently completed.
Why Self-Host GitLab?
Privacy: Keep your code and data on your own infrastructure.
Customization: Tailor GitLab to your team’s needs.
CI/CD: Automate builds, tests, and deployments with GitLab Runners.
Prerequisites
A server with 8 vCPU, 7.2GB RAM, and 50GB+ disk space (e.g., Ubuntu 22.04).
Root or sudo access.
A domain name (e.g.,
git.example.com) or static IP.
Creating an EC2 server
Go to
AWS console→EC2→Instances
Click on
Launch Instance
Fill the requirements
Name:
GitLab ServerAMI:
Ubuntu Server 24.04
Instance type:
t2.2xlarge
Create a new
key pairand save it
Configure the
Network settings
Configure storage (set
50+ GiBof storage)
Launch the Instance


Connect to the Gitlab Server using SSH
Copy the
public IPof the ServerOpen Your
local terminalConnect to the Instance via
sshcommand:ssh -i <path_of_key_pair_file> ubuntu@<public_ip>
Congrats! 🎉 Gitlab server is now connected to the local server via SSH
Step 1: Prepare the Server
Start by updating your server and installing dependencies:
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
Optionally, install Postfix for email notifications:
sudo apt-get install -y postfix
Select
Internet Siteand enter yourserver’s domain or IP.
Step 2: Install Docker
Install Docker to run GitLab in a container:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

Log out and back in, then verify Docker:
docker --version

Log out and back in for the group change to take effect.
Step 3: Deploy GitLab
Create directories for persistent storage:
mkdir -p /srv/gitlab/config /srv/gitlab/logs /srv/gitlab/data


Run the GitLab container:
sudo docker run --detach \
--hostname git.example.com \
--publish 443:443 --publish 80:80 --publish 22:22 \
--name gitlab \
--restart always \
--volume /srv/gitlab/config:/etc/gitlab \
--volume /srv/gitlab/logs:/var/log/gitlab \
--volume /srv/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

Replace
git.example.comwith yourdomain or server IP.Wait 5-10 minutes for GitLab to initialize.
Check container status:
docker ps

Step 4: Secure the Instance
Access GitLab: Navigate to http://<server-ip> or
https://git.example.com.
Set a password for the root user when prompted.
Log in: Use username
rootand the password you set.

Enable HTTPS by editing /srv/gitlab/config/gitlab.rb:
external_url 'https://git.example.com'
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['your-email@example.com']
Reconfigure GitLab:
sudo docker exec -it gitlab gitlab-ctl reconfigure

Restrict access (optional): In the GitLab UI, go to Admin Area > Settings > General > Sign-up restrictions and disable sign-ups for a private setup.

Step 5: Set Up CI/CD with GitLab Runner
Install GitLab Runner:
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install -y gitlab-runner

Register the Runner:
In GitLab UI, go to Settings > CI/CD > Runners to get the registration token and URL.

Register the runner:
sudo gitlab-runner register \
--url https://git.example.com \
--token <your-registration-token> \
--description my-runner \
--tag-list docker-runner \
--executor docker \
--docker-image alpine:latest
Verify Runner:
sudo gitlab-runner status

Test CI/CD with a Pipeline
Create a .gitlab-ci.yml file in your project to test the pipeline:
stages:
- build
- test
build:
stage: build
tags:
- docker-runner
script:
- echo "Building the project..."
- mkdir -p builds
- touch builds/app.txt
artifacts:
paths:
- builds/
test:
stage: test
tags:
- docker-runner
script:
- echo "Running tests..."
- test -f builds/app.txt
Push the file and check the pipeline in CI/CD > Pipelines
Conclusion
You now have a self-hosted GitLab instance with CI/CD, ready for private development and automation. Secure it with a firewall (ufw) and regular backups:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo docker exec -it gitlab gitlab-backup create



