How to install GitLab on a dedicated server
GitLab is a platform for Git repositories, code review, issue tracking and CI/CD that you can run on your own server. A self-hosted instance keeps your source code under your control, and its capacity depends only on the server resources and the GitLab features you use.
A dedicated server suits GitLab well. Repository storage is disk-intensive, and the database and background services need a steady amount of RAM. On dedicated hardware these resources are not shared with anyone else, so GitLab stays responsive during large pushes and CI runs.
Why run your own GitLab
GitLab.com is convenient for a start, but as a team grows, a self-hosted instance often becomes the better choice:
- Code stays on your server. Source code, issues and CI/CD secrets are stored on hardware you control, in the data center location you choose. This matters for projects with NDA or data residency requirements.
- No plan limits on users, storage and CI/CD minutes. The free tier of GitLab.com limits them, while on your own server only its resources set the limits.
- Your own CI/CD runners. Builds run on your servers without paying for compute minutes, and they can reach internal services that are closed to the internet.
- Full control over updates and settings. You decide when to upgrade, which integrations to enable and how to back up data.
If you already use GitLab.com, install your own instance first and then move groups and projects to it.
This guide shows how to install GitLab from the official package on Ubuntu or Debian, get a free Let's Encrypt certificate and prepare the instance for your team.
What you need before installation
A dedicated server with at least 8 vCPU (CPU threads) and 16 GB of RAM. A 4-core processor with Hyper-Threading or SMT already gives 8 threads. GitLab can start with 8 GB of RAM, but it uses almost all of it and will be slow under load. Use SSD or NVMe disks with at least 40 GB free for the system and GitLab, plus enough space for all repositories and backups.
Ubuntu 26.04 LTS, Ubuntu 24.04 LTS or Debian 13 installed on the server. The commands in this guide are the same for all three systems; where Debian differs, this is noted.
A domain or subdomain for GitLab, for example gitlab.example.com.
A DNS A record that points this domain to the public IPv4 address of the server.
If you also add an AAAA record, IPv6 must already work on the server. Let's Encrypt prefers IPv6 when an AAAA record exists, and if the server is not reachable over IPv6, the certificate is not issued. If you are not sure, add only the A record.
Root access or a user with sudo rights. The commands in this guide are run as root; if you use a sudo-enabled user, add sudo before them. In the command that adds the GitLab repository, put sudo before bash: curl ... | sudo bash.
Ports 22 (SSH), 80 (HTTP) and 443 (HTTPS) open to the internet. Port 80 is required even if you plan to use only HTTPS, because Let's Encrypt checks the domain over HTTP.
Throughout this guide, replace gitlab.example.com with your own domain and 203.0.113.10 with the IP address of your server.
Connect to the server
Connect to the server over SSH from your computer:
Check the operating system version:
cat /etc/os-release
Example output:
PRETTY_NAME="Ubuntu 26.04 LTS" NAME="Ubuntu" VERSION_ID="26.04" ...
The output must show Ubuntu 26.04, Ubuntu 24.04 or Debian 13. Then check the number of CPU cores, the amount of RAM and the free disk space:
nproc free -h df -h /
Make sure that the domain already points to the server. Run this command on your local computer (it works on Windows, macOS and Linux):
nslookup gitlab.example.com
The A record must return the public IPv4 address of the server. If you also use an AAAA record, make sure the server is reachable over IPv6. If the addresses do not match, fix the DNS records and wait until the change takes effect. Do not continue until the domain resolves correctly, because GitLab requests the Let's Encrypt certificate during the initial configuration.
Update the server and install dependencies
Update the package lists and installed packages:
apt update && apt upgrade -y
Set the server hostname to the GitLab domain. GitLab does not require this, but it keeps the system name consistent with the GitLab address in logs and outgoing email:
hostnamectl set-hostname gitlab.example.com
Install the packages GitLab needs:
apt install -y curl openssh-server ca-certificates perl tzdata locales
GitLab also needs a UTF-8 locale: without it, the bundled PostgreSQL database may fail to initialize during installation. Enable en_US.UTF-8 in the list of locales and generate it (on Ubuntu 26.04 it is already enabled, and the first command changes nothing):
sed -i 's/^# *en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen locale-gen
Configure the firewall
This guide uses the UFW firewall. It is included in Ubuntu but disabled by default; on Debian, install it first:
apt install -y ufw
If UFW is already enabled on your server, check its current rules with ufw status first. Allow SSH, HTTP and HTTPS, and only then turn the firewall on, so that your SSH session is not interrupted:
ufw allow ssh ufw allow http ufw allow https ufw enable
Answer y when asked to confirm. Check the rules:
ufw status
Example output:
Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) 80/tcp (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
If your SSH server uses a port other than 22, allow that port before ufw enable, for example ufw allow 2222/tcp. Otherwise the connection will be lost.
Add the GitLab repository
GitLab is distributed in two editions:
- GitLab Enterprise Edition (
gitlab-ee). It includes all free features and lets you activate paid features later without reinstalling. - GitLab Community Edition (
gitlab-ce). A fully open-source build with the free GitLab features.
This guide uses gitlab-ee. If you prefer the Community Edition, replace gitlab-ee with gitlab-ce in all commands.
Add the official GitLab repository:
curl -fsSL https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | bash
The script adds the repository and its signing key and refreshes the package list.
Install GitLab
Install the package and pass the address of your instance in EXTERNAL_URL. Use https:// in the address: in this case GitLab requests a Let's Encrypt certificate and sets up the redirect from HTTP to HTTPS automatically.
EXTERNAL_URL='https://gitlab.example.com' apt install -y gitlab-ee
During installation, GitLab unpacks its components (the web server, PostgreSQL database, Redis, Git storage and background services), writes the configuration to /etc/gitlab/gitlab.rb, requests the certificate and starts all services. This takes 5 to 10 minutes. When it finishes, the output ends with a "Thank you for installing GitLab!" message.
Example output:
Thank you for installing GitLab! GitLab should be available at https://gitlab.example.com
GitLab generates a random password for the root account and saves it to a file. Display it:
cat /etc/gitlab/initial_root_password
Copy the password. The file is deleted automatically 24 hours after installation, so sign in and set your own password before then.
You can set the root password yourself during installation by adding GITLAB_ROOT_PASSWORD='your-password' before EXTERNAL_URL in the install command. Use single quotes, so that the shell does not change characters such as $ or !. If the password is shorter than 8 characters, GitLab does not use it and generates a random password instead.
Open GitLab and check HTTPS
Open https://gitlab.example.com in your browser. The page must open without a security warning, and the browser must show a valid certificate issued by Let's Encrypt.
If the page shows error 502, GitLab is still starting its services. Wait a minute or two and reload the page.
Sign in with the username root and the password from initial_root_password.
Change the password right away. Select your avatar, then Edit profile. In the left menu, expand Access, select Password and authentication, then select Change password. Enter the current password and a new one, and select Save password. GitLab rejects weak passwords, including ones that contain the word "gitlab" or your username.
If the page does not open over HTTPS, the certificate was most likely not issued. In that case, the installation output contains a Let's Encrypt error. Check that the domain resolves to the server IP address, that port 80 is open and that there is no AAAA record without working IPv6. After fixing the cause, request the certificate again:
gitlab-ctl reconfigure
Let's Encrypt limits the number of failed attempts per hour, so fix the cause before retrying.
Basic GitLab configuration
Disable public registration. If the instance is only for your team, turn off account creation from the sign-up page. By default, anyone who opens your GitLab page can register, and the new account then waits for administrator approval. The quickest way is the Deactivate button in the banner on the GitLab home page. You can also select Admin in the top right corner, go to Settings > General and expand New user account restrictions. Clear the Allow new user accounts checkbox and select Save changes. New accounts will then be created only by administrators.

Create user accounts. Go to Admin > Instance overview > Users and select New user, fill in the name, username and email address, and select Create user. Use a personal account with administrator rights for daily work and the root account only when necessary.
Create a group. Groups combine projects and team members. Select Create new (the plus icon) in the top bar, then New group > Create group, enter a name and select Create group. Add your colleagues to the group under Manage > Members.



Add an SSH key. To work with repositories over SSH, each user adds their public key under Edit profile > Access > SSH keys: select Add new key, paste the key and select Add key.
GitLab sends emails to reset passwords, confirm accounts and unlock them after failed sign-in attempts. Until outgoing email is configured (see "What to configure next"), these functions do not work, and administrators have to reset passwords manually.
Verify the installation
Check that all GitLab services are running:
gitlab-ctl status
Example output:
run: gitaly: (pid 2981) 512s; run: log: (pid 2975) 512s run: gitlab-workhorse: (pid 3412) 498s; run: log: (pid 3401) 498s run: nginx: (pid 3530) 495s; run: log: (pid 3522) 495s run: postgresql: (pid 3105) 507s; run: log: (pid 3098) 507s run: puma: (pid 3288) 501s; run: log: (pid 3280) 501s run: redis: (pid 2950) 514s; run: log: (pid 2944) 514s run: sidekiq: (pid 3350) 499s; run: log: (pid 3342) 499s ...
Every line must start with run:.
Run the built-in check of the configuration and services:
gitlab-rake gitlab:check SANITIZE=true
Create a test repository. In the web interface, select Create new > New project/repository > Create blank project, enter the name test, select your group and keep Initialize repository with a README selected. Select Create project.


Check access over SSH from your computer:
ssh -T [email protected]
Example output:
Welcome to GitLab, @username!
A working setup replies with a welcome message containing your username. Then clone the test repository:
git clone [email protected]:group/test.git
Replace group with the path of your group. If the repository is cloned and contains README.md, GitLab is installed and working.
What to configure next
Backups. The gitlab-backup create command creates an application backup with the GitLab database, repositories and other application data in /var/opt/gitlab/backups. The configuration files /etc/gitlab/gitlab.rb and /etc/gitlab/gitlab-secrets.json are not included and must be backed up separately, for example with gitlab-ctl backup-etc. Without gitlab-secrets.json, a restored instance cannot decrypt 2FA settings and CI/CD variables. Run application and configuration backups regularly and copy them to storage outside the GitLab server, for example to INTROSERV Cloud Storage: see Connecting INTROSERV Cloud Storage to the server.
Outgoing email. Configure an SMTP server in /etc/gitlab/gitlab.rb so that GitLab can send notifications, password resets and account confirmations. See SMTP settings in the GitLab documentation.
GitLab Runner. Runner executes CI/CD pipelines. Builds use a lot of CPU and RAM, so it is better to install Runner on a separate VPS or dedicated server rather than on the GitLab server itself.
Updates. GitLab releases a new version every month and security fixes more often. Before upgrading across several versions, check the official upgrade path: GitLab must pass through certain intermediate versions. Create a backup, then update with apt update && apt install -y gitlab-ee.
Monitoring. GitLab includes Prometheus and exports its own metrics. The health of the instance can be checked in Admin > Monitoring > Health check, and the endpoints listed there can be connected to your external monitoring system.

To choose a server for your GitLab instance, see the Dedicated Servers page.