I work on projects that I'd rather not store on public SaaS platforms — either because of client confidentiality requirements or because I want complete control over the code, the pipelines, and who has access. GitLab Community Edition gives you a full self-hosted Git platform: repositories, merge requests, CI/CD pipelines, container registry, and a wiki, all running on your own server.
The trade-off is resource requirements. GitLab is not lightweight. But on the right server size, it runs well and the maintenance overhead is surprisingly low once it's set up.
I run GitLab CE on Tencent Cloud Lighthouse. Use the 4 GB RAM / 2 vCPU plan at minimum — 8 GB RAM is more comfortable when you're also running CI/CD runners. GitLab's self-hosted advantage on Lighthouse: complete data sovereignty over your code and pipelines, with no per-seat licensing. Lighthouse's snapshot feature is particularly important for GitLab because the instance contains repositories, CI/CD artifacts, container registry images, and user data — a single snapshot captures everything. The spec upgrade path also means you can start at a smaller plan and grow as your team and repository count increases.
- Key Takeaways
GitLab CE on your own server gives you:
The cost per user at scale drops to near zero compared to per-seat SaaS pricing.
| Requirement | Minimum | Recommended |
|---|---|---|
| RAM | 4 GB | 8 GB |
| CPU | 2 vCPU | 4 vCPU |
| Storage | 20 GB | 50 GB+ |
| OS | Ubuntu 22.04 | Ubuntu 22.04 |
| Domain | Required for SSL | — |
GitLab's omnibus package includes PostgreSQL, Redis, Nginx, and Sidekiq — it's a complete stack in one package. That's why the memory requirement is higher than a single-service app.
sudo apt update
sudo apt install -y curl openssh-server ca-certificates tzdata perl
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
Replace gitlab.yourdomain.com with your actual subdomain:
sudo EXTERNAL_URL="https://gitlab.yourdomain.com" apt install gitlab-ce
This single command installs GitLab and automatically configures Let's Encrypt SSL for your domain. The installation takes 3–5 minutes.
Check that GitLab services are running:
sudo gitlab-ctl status
All services (puma, sidekiq, postgresql, redis, nginx) should show run.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp # SSH for Git over SSH
sudo ufw reload
Also open ports 80, 443, and 22 in your Lighthouse console firewall rules.
If you didn't set the EXTERNAL_URL with HTTPS during installation, configure it now:
sudo nano /etc/gitlab/gitlab.rb
Find and update:
external_url 'https://gitlab.yourdomain.com'
# Auto SSL via Let's Encrypt
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['you@example.com']
letsencrypt['auto_renew'] = true
letsencrypt['auto_renew_hour'] = 12
letsencrypt['auto_renew_minute'] = 30
letsencrypt['auto_renew_day_of_month'] = "*/7"
Apply the configuration:
sudo gitlab-ctl reconfigure
This applies all settings and restarts services. Takes 2–3 minutes.
sudo cat /etc/gitlab/initial_root_password
This file contains the auto-generated password for the root account. It's only valid for 24 hours.
Navigate to https://gitlab.yourdomain.com in your browser.
Log in with:
rootImmediately go to User Settings → Password and set a strong permanent password.
Go to Admin Area → Settings → General:
Groups organize related projects:
my-team)On your local machine:
cat ~/.ssh/id_ed25519.pub
In GitLab: User Settings → SSH Keys → Add new key
Paste your public key and save.
git clone git@gitlab.yourdomain.com:my-team/my-project.git
cd my-project
# make changes
git add .
git commit -m "Initial commit"
git push origin main
On the same server (or a separate runner machine):
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt install -y gitlab-runner
In GitLab: Admin Area → CI/CD → Runners → Register an instance runner
Copy the registration token, then run:
sudo gitlab-runner register
Follow the prompts:
GitLab instance URL: https://gitlab.yourdomain.com
Registration token: (paste from UI)
Description: my-server-runner
Tags: ubuntu, docker
Executor: docker
Default Docker image: alpine:latest
.gitlab-ci.ymlAdd this to your project root to test CI/CD:
stages:
- test
- deploy
test:
stage: test
image: node:20-alpine
script:
- npm ci
- npm test
deploy:
stage: deploy
image: alpine:latest
script:
- echo "Deploy step here"
only:
- main
Push to main and watch the pipeline run under CI/CD → Pipelines.
Configure SMTP so GitLab can send pipeline notifications, invite emails, etc.
Edit /etc/gitlab/gitlab.rb:
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.sendgrid.net"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "apikey"
gitlab_rails['smtp_password'] = "YOUR_SENDGRID_API_KEY"
gitlab_rails['smtp_domain'] = "yourdomain.com"
gitlab_rails['smtp_authentication'] = "plain"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['gitlab_email_from'] = 'gitlab@yourdomain.com'
Apply:
sudo gitlab-ctl reconfigure
Test:
sudo gitlab-rails console
Notify.test_email('you@example.com', 'Test', 'GitLab email works').deliver_now
After installation, GitLab was accessible via the web UI but I couldn't push via SSH — git push timed out.
The problem: GitLab uses port 22 for SSH Git operations, but my system SSH daemon was also on port 22. They were conflicting.
The fix: Two options:
Option A — Move system SSH to a different port:
sudo nano /etc/ssh/sshd_config
# Change: Port 22 → Port 2222
sudo systemctl restart ssh
sudo ufw allow 2222/tcp
Then update your ~/.ssh/config to connect to port 2222 for your server.
Option B — Configure GitLab SSH to use port 2222:
In /etc/gitlab/gitlab.rb:
gitlab_rails['gitlab_shell_ssh_port'] = 2222
After sudo gitlab-ctl reconfigure, clone URLs will show the non-standard port automatically.
I went with Option A — kept GitLab on standard port 22 for Git and moved my system SSH management to 2222.
| Issue | Likely Cause | Fix |
|---|---|---|
| 502 Bad Gateway | Services still starting | Wait 3–5 min after install; check gitlab-ctl status |
| SSL certificate error | DNS not propagated | Wait, then gitlab-ctl renew-le-certs |
| High memory usage | Normal for GitLab | Monitor with gitlab-ctl status; upgrade to 8 GB RAM if needed |
| CI pipeline stuck | Runner not connected | Check gitlab-runner status; re-register if needed |
| Git push via SSH fails | Port conflict (see above) | Move system SSH or GitLab SSH to different port |
| Email not sending | SMTP config error | Check logs: sudo gitlab-ctl tail gitlab-rails |
| reconfigure takes too long | Normal first time | Wait 5–10 minutes; subsequent reconfigurations are faster |
GitLab CE running on a cloud server is a complete DevOps environment:
✅ What you built:
Maintenance: Updates are straightforward — sudo apt update && sudo apt install gitlab-ce upgrades to the latest version. GitLab releases monthly. Run updates during low-traffic hours.
Cost: A 4 GB RAM Lighthouse instance runs GitLab CE well for small teams. The hardware cost replaces per-seat fees at scale.
Is self-hosted GitLab CE suitable for production use?
Yes — GitLab CE is used in production environments ranging from individual developers to small teams. Pair it with regular Lighthouse snapshots and stay current with updates.
How do I migrate from a cloud-hosted GitLab CE to self-hosted?
Export your data from the cloud service, import it to the self-hosted instance, update DNS or internal service configurations, and verify everything works before switching fully.
How much disk space does GitLab CE need?
Initial installation is minimal. Disk usage grows with usage — artifacts, repositories, and caches accumulate over time. Monitor with df -h and use CBS cloud disk expansion when needed.
How do I set up backups for GitLab CE?
Use Lighthouse snapshots for full-server recovery. Additionally, export GitLab CE's application data directly (usually a backup command or data directory export) for granular restore capability.
👉 Get started with Tencent Cloud Lighthouse
👉 View current pricing and launch promotions
👉 Explore all active deals and offers