Setting Up GitLab on Ubuntu with HAProxy and Using HTTPS for Development – Complete Guide

In modern software engineering, having a centralized, secure, and scalable code repository is critical. This guide walks through a real-world implementation of a self-hosted GitLab platform deployed on an Ubuntu VM, integrated with HAProxy for SSL termination, and configured for developer access via HTTPS.

This article also includes real troubleshooting scenarios and essential Git commands every developer should know.


🧱 Architecture Overview
Developers → HTTPS → HAProxy → GitLab (Ubuntu VM)

Key Components:

  • HAProxy → Handles SSL (HTTPS termination)
  • GitLab → Runs internally over HTTP
  • Developers → Access repositories securely via HTTPS

⚙️ Step 1: Install GitLab on Ubuntu

Prepare the server:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl openssh-server ca-certificates tzdata perl

Install GitLab:

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo EXTERNAL_URL="http://your-domain" apt install gitlab-ce -y

🔧 Step 2: Configure GitLab Behind HAProxy

Edit configuration:

sudo nano /etc/gitlab/gitlab.rb

Update:

external_url "http://your-domain"nginx['listen_port'] = 80
nginx['listen_https'] = falsenginx['proxy_set_headers'] = {
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}

Apply changes:

sudo gitlab-ctl reconfigure

🌐 Step 3: Configure HAProxy

Example configuration:

frontend https_front
bind *:443 ssl crt /path/to/certificate.pem
mode http
default_backend gitlab_backendbackend gitlab_backend
mode http
option forwardfor
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Ssl on
server gitlab1 <private-ip>:80 check

👥 Step 4: Setup Users and Projects

Inside GitLab Community Edition:

  • Create users
  • Create a project
  • Assign roles:
    • Developer
    • Maintainer

💡 Best Practice: Use Groups instead of assigning users per project.


🔐 Step 5: Use HTTPS Instead of SSH

Clone repository:

git clone https://your-domain/group/project.git

📤 Step 6: Push Code from Windows (or any developer machine)

Initialize repository:

git init
git add .
git commit -m "Initial commit"
git branch -M main

Add remote:

git remote add origin https://your-domain/group/project.git

Push:

git push -u origin main

⚠️ Troubleshooting (Real Issues & Fixes)

❌ Error: src refspec main does not match any

Cause:

No commits exist yet.

Fix:

git add .
git commit -m "Initial commit"

❌ Error: remote origin already exists

Fix:

git remote set-url origin https://your-domain/group/project.git

❌ Error: non-fast-forward / fetch first

Cause:

Remote repo already contains files.

Fix:

git pull origin main --allow-unrelated-histories

❌ Merge Conflict (e.g., README.md)

Example:

CONFLICT (add/add): Merge conflict in README.md

Fix:

  1. Open file
  2. Remove markers:
<<<<<<< HEAD
=======
>>>>>>> ...
  1. Save and run:
git add README.md
git commit -m "Resolve merge conflict"
git push

❌ Authentication Issues (HTTPS)

Solution:

Use Personal Access Token (PAT) instead of password:

  • Username → GitLab username
  • Password → PAT

❌ SSH Key Not Working

Cause:

  • Key not added to GitLab
  • SSH agent not running

Fix:

Use HTTPS instead OR properly configure SSH keys.


❌ Git Push Rejected

Cause:

Local branch behind remote

Fix:

git pull origin main
git push

🧰 Useful Git Commands (Cheat Sheet)

🔍 Check status

git status

🔗 View remote

git remote -v

➕ Add files

git add .

💾 Commit changes

git commit -m "message"

📤 Push code

git push

📥 Pull latest changes

git pull origin main

🔄 Change remote URL

git remote set-url origin <new-url>

🌿 Create new branch

git checkout -b feature-branch

🔀 Merge branch

git merge branch-name

⚠️ Force push (use carefully)

git push --force

🔎 View commit history

git log --oneline

🧠 Key Lessons Learned

✅ HTTPS simplifies onboarding

No SSH key setup required for developers

✅ Always expect initial merge conflicts

Especially when GitLab auto-generates README

✅ Git error messages are helpful

They guide you to the solution

✅ HAProxy provides clean SSL architecture

Decouples SSL from GitLab


🚀 Final Thoughts

Setting up a self-hosted GitLab with HAProxy and HTTPS access provides:

  • Secure developer access
  • Scalable architecture
  • Flexibility for enterprise environments

With proper setup, your team can:

  • Push code securely
  • Collaborate efficiently
  • Extend into CI/CD pipelines

📌 Next Steps

To take this further:

  • Setup GitLab CI/CD pipelines
  • Integrate with Azure DevOps / Kubernetes
  • Enable SSO (Entra ID)
  • Configure automated backups