Installing GitLab as a self-hosted git repository
Introduction
Having Git repository in your homelab is a good idea for storing code for various projects. For a lightweight option similar to GitHub, consider the Gitea project. GitLab is another option, offering a more feature rich experience, though it is more resource intensive. This post will concentrate on installing GitLab Community Edition.
UPDATE 2026-04-26: Added instruction how to automatically reload nginx configuration after obtaining new SSL certificate.
OS used: Debian 12
Software used: GitLab Community Edition 17.4.2
Source
- Official GitLab install documentation.
Initial requirements
In the beginning create new virtual machine, for example using this tutorial Debian VM fast initialization using Ansible.
GitLab installation
GitLab can be installed in different ways. Here we will use installation method from deb package.
GitLab requirements
I suggest resizing virtual machine disk to at least 20GB. Afterward, monitor used space and resize the disk when free space is running low. Also for homelab use, a virtual machine with 2 CPU and 4GB RAM should work fine.
Installation
- Install necessary packages:
$ sudo apt update && \
sudo apt install -y curl openssh-server ca-certificates perl
- Add GitLab repository:
$ curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
- Install GitLab:
$ sudo apt install gitlab-ce
Enable HTTPS
This tutorial will show how to enable HTTPS using Let's Encrypt certificate acquired using instruction from article Obtaining Let's Encrypt certificate using Cloudflare. Official documentation for HTTPS configuration can be found here: GitLab Docs - Configure HTTPS manually.
Perform following actions:
- Acquire Let's Encrypt certificate with
certbotusing instruction from article Obtaining Let's Encrypt certificate using Cloudflare. - Let's Encrypt certificate will be in folder
/etc/letsencrypt/live/<your_domain_name>/. - In GitLab configuration file, set the following options:
- URL to your GitLab
- disable Let's Encrypt integration
- enter path for certificate key and certificate
$ sudo vim /etc/gitlab/gitlab.rb
(...)
external_url "https://your_domain_name"
(...)
letsencrypt['enable'] = false
(...)
nginx['ssl_certificate'] = "/etc/letsencrypt/live/<your_domain_name>/fullchain.pem"
nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/<your_domain_name>/privkey.pem"
- Reconfigure GitLab (this command can take some time to run for the first time, so be patient and wait until it ends):
$ sudo gitlab-ctl reconfigure
Warning
If the content of SSL certificate changes (for example when certbot obtains new certificate) and Nginx used by GitLab don't use this new certificate, then Nginx configuration must be reloaded using following commands:
$ sudo gitlab-ctl hup nginx && \
sudo gitlab-ctl hup registry
To automatically reload Nginx configuration add the following certbot hook, which will run the commands above after a successful certificate renewal:
$ sudo vim /etc/letsencrypt/renewal-hooks/deploy/gitlab-nginx-reload
gitlab-ctl hup nginx
gitlab-ctl hup registry
Make file executable:
$ sudo chmod 744 /etc/letsencrypt/renewal-hooks/deploy/gitlab-nginx-reload
Mail notifications
Official documentation for mail configuration can be found here: GitLab Docs - SMTP settings. Below we will focus on using Gmail.
- Edit configuration file
/etc/gitlab/gitlab.rb:
$ sudo vim /etc/gitlab/gitlab.rb
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "my-gmail-password-for-app"
gitlab_rails['smtp_domain'] = "smtp.gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'peer' # Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert', see https://api.rubyonrails.org/classes/ActionMailer/Base.html
Warning
Your smtp_password should not contain any String delimiters used in Ruby or YAML (e.g. ') to avoid unexpected behavior during the processing of configuration settings.
- Reconfigure GitLab:
$ sudo gitlab-ctl reconfigure
- Test mail configuration by entering Ruby on Rails console:
$ sudo gitlab-rails console
- Execute following command in Ruby on Rails console:
Notify.test_email('[email protected]', 'Message Subject', 'Message Body').deliver_now
Firewall configuration
Open port 443 on firewall to access GitLab.
Using iptables
Use following command to add rule to iptables:
$ sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT && \
sudo iptables -L -v && \
sudo netfilter-persistent save
Using nftables
Add following line to your input chain in nftables config file:
$ sudo vim /etc/nftables.conf
table inet filter {
chain input {
(...)
tcp dport { 443 } ct state new accept
(...)
}
Reload rules after changing /etc/nftables.conf with command:
$ sudo systemctl restart nftables.service
In order to see firewall ruleset and counters statistics use command:
$ sudo nft list ruleset
Automatic upgrades
Note
GitLab upgrade can take some time and system resources (such as RAM), so consider whether it should be done automatically in your homelab and when.
If you are using unattended-upgrades for system upgrades you can enable GitLab automatic upgrades by editing file /etc/apt/apt.conf.d/50unattended-upgrades:
$ sudo vim /etc/apt/apt.conf.d/50unattended-upgrades
(...)
Unattended-Upgrade::Origins-Pattern {
"origin=Debian,codename=${distro_codename}-updates";
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
// --- Add these lines ---
// GitLab repository
"o=packages.gitlab.com/gitlab/gitlab-ce";
// -----------------------
(...)
};
(...)
Test if configuration is correct by running command:
$ sudo unattended-upgrades --dry-run --debug
If you see the following line in the command output than something is wrong with the configuration:
DEBUG Marking not allowed <apt_pkg.PackageFile object: filename:'/var/lib/apt/lists/packages.gitlab.com_gitlab_gitlab-ce_debian_dists_bookworm_main_binary-amd64_Packages' a=bookworm,c=main,v=1,o=packages.gitlab.com/gitlab/gitlab-ce,l=gitlab-ce arch='amd64' site='packages.gitlab.com' IndexType='Debian Package Index' Size=114917 ID:12>
Successful unattended-upgrades command output should not have Marking not allowed line.
First login to GitLab
To access GitLab open web browser and enter domain name which you configured for GitLab.
For initial login use:
- Username:
root - Password: is generated in
/etc/gitlab/initial_root_password - After login:
- Click
Admin(left down corner) >Overview>Users> perform following user actions:- Change
rootpassword to yours - Change username from
rootto something else - Change
rootemail to valid - Create new user for normal GitLab use (use Administrator user only for admin stuff)
- Change
GitLab configuration
Once GitLab is installed and running, I suggest looking at following options:
- Disable account creation for anyone:
- Click
Admin(left down corner) >Settings>General> disableSign-up enabled - Enable 2FA authentication for created users:
- Click your avatar >
Edit profile>Account> clickEnable two-factor authentication