Skip to content

TutorialsGit & DevOps

How to install GitLab CE on Ubuntu or Debian with built-in Let's Encrypt

Install GitLab Community Edition from GitLab's official package repository with Let's Encrypt HTTPS, then lock down sign-ups, back it up and upgrade safely.

  • Intermediate
  • 45 min read
  • Updated

Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 13

This guide is not available in your language yet, so it is shown in English.

On this page
  1. Prerequisites
  2. Step 1 — Open the firewall
  3. Step 2 — Add GitLab's package repository
  4. Step 3 — Install GitLab CE with HTTPS
  5. Step 4 — Sign in as root
  6. Step 5 — Restrict sign-ups and set the certificate contact
  7. Step 6 — Tune GitLab for a smaller server (optional)
  8. Back up and restore
  9. Upgrade GitLab
  10. Troubleshooting
  11. 502 error right after installation, a restart or an upgrade
  12. Let's Encrypt fails during reconfigure
  13. Errno::ENOMEM: Cannot allocate memory during backup or upgrade
  14. PostgreSQL reports that it could not create a shared memory segment
  15. reconfigure stops with undefined method for nil:NilClass
  16. The initial root password no longer works or the file is gone
  17. Next steps

GitLab Community Edition (CE) brings Git repositories, merge requests, issues, CI/CD pipelines and container and package registries together in one self-managed application. The official Linux package bundles GitLab together with PostgreSQL, Redis, Gitaly, Puma, Sidekiq and NGINX, and you configure all of it through a single file, /etc/gitlab/gitlab.rb.

This guide installs GitLab CE from GitLab's own package repository on Ubuntu or Debian, lets GitLab obtain a Let's Encrypt certificate by itself, secures the root account and sign-ups, and then covers backups, upgrades along GitLab's required upgrade stops, and the problems you are most likely to meet on a single server.

Prerequisites

You need a server running a release that GitLab supports. In October 2026, when GitLab 19.4 is current, GitLab's supported platforms table shows:

Operating systemStatus in GitLab's supported platforms table
Ubuntu 26.04 LTSSupported from GitLab 19.3.0
Ubuntu 24.04 LTSSupported
Debian 13Supported from GitLab 18.5.0
Debian 12Proposed last supported GitLab version 19.3.0, so not recommended for new installations

GitLab builds packages for amd64 and arm64 and notes known issues on ARM. The Ubuntu installation page itself still lists only 22.04 and 24.04; Ubuntu 26.04 support comes from the supported platforms table. You also need:

  • A non-root user with sudo rights and SSH key login, as in Secure a new Linux server and Set up SSH keys. GitLab uses the server's own OpenSSH for Git over SSH as the git user; if you restricted logins with AllowUsers or AllowGroups, include git.
  • A domain such as gitlab.example.com with an A (and AAAA) record pointing at the server. Let's Encrypt needs inbound HTTP and HTTPS access and a valid hostname.
  • Ports 80 and 443 free: GitLab's bundled NGINX listens on them, so do not run another web server on this host.
  • Outbound access to https://packages.gitlab.com/ and https://storage.googleapis.com/packages-ops/ if a firewall filters outgoing traffic.
ResourceMinimum (official)Suggested starting point
CPU8 vCPU baseline for a single node8 vCPU
Memory16 GB baseline; at least 8 GB with memory-constrained settings16 GB
Disk40 GB for the application, plus all repositories, plus 5–12 GB for PostgreSQL100 GB SSD, growing with your repositories and CI artifacts

The minimum column comes from GitLab's installation requirements. The suggested column is a conservative starting point, not an official or benchmarked figure. GitLab's requirements also ask you to disable swap where possible, or to provide enough memory that GitLab never uses it.

Step 1 — Open the firewall

GitLab's installation pages enable SSH and open SSH, HTTP and HTTPS in ufw. Port 22 also carries Git over SSH:

Bash
sudo systemctl enable --now ssh
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Unlike Docker-based apps, GitLab's NGINX runs directly on the host, so ufw rules apply to it normally. If your SSH daemon listens on another port, allow that port instead of 22 before you enable ufw.

Step 2 — Add GitLab's package repository

GitLab provides a script that configures its apt repository. Install curl, download the script, read it, then run it:

Bash
sudo apt update
sudo apt install -y curl
curl --location "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh" -o gitlab-ce-repo.sh
less gitlab-ce-repo.sh
sudo bash gitlab-ce-repo.sh

The script:

  • detects your distribution and codename from /etc/os-release;
  • installs apt-transport-https, gnupg if gpg is missing, and on Debian debian-archive-keyring;
  • downloads the repository definition for your release into /etc/apt/sources.list.d/gitlab_gitlab-ce.list;
  • downloads GitLab's signing key, converts it and stores it as /etc/apt/keyrings/gitlab_gitlab-ce-archive-keyring.gpg;
  • runs apt-get update and stops with an error if that fails.

Check that apt now offers GitLab CE from GitLab's repository:

Bash
apt-cache policy gitlab-ce

The Candidate line shows the newest version, and the source is packages.gitlab.com.

Step 3 — Install GitLab CE with HTTPS

Pass your public address in EXTERNAL_URL. Because it starts with https://, GitLab requests a Let's Encrypt certificate during the first configuration run:

Bash
sudo EXTERNAL_URL="https://gitlab.example.com" apt install gitlab-ce

The installation and the first gitlab-ctl reconfigure take several minutes. GitLab also accepts GITLAB_ROOT_EMAIL and GITLAB_ROOT_PASSWORD (at least 8 characters) on the same command line, but only on the first installation, and the password then ends up in your shell history; the generated password in Step 4 avoids that. If GitLab cannot detect a valid hostname, reconfigure does not run automatically; then pass the same variables to sudo gitlab-ctl reconfigure.

Check the services and the site:

Bash
sudo gitlab-ctl status
curl -I https://gitlab.example.com

Every service line starts with run:. curl returns a redirect to the sign-in page over a valid certificate. A 502 page in the first minute or two is normal while Puma starts.

Step 4 — Sign in as root

GitLab generates a random root password and stores it for 24 hours:

Bash
sudo cat /etc/gitlab/initial_root_password

Open https://gitlab.example.com, sign in as root with that password, then immediately:

  1. Set a new long password in your user settings, under Password.
  2. Change the root account's email address to one you read.
  3. Turn on two-factor authentication for the account.

After 24 hours GitLab deletes the file automatically. If you lose the password, the troubleshooting section shows how to reset it.

Step 5 — Restrict sign-ups and set the certificate contact

By default, anyone who can reach your GitLab can request an account; new instances require administrator approval for these sign-ups. If only invited people should have accounts, switch sign-up off:

  1. In the upper-right corner, select Admin.
  2. In the left sidebar, select Settings, then General.
  3. Expand New user account restrictions.
  4. Clear Allow new user accounts and select Save changes.

Create accounts yourself under Admin, Users from now on.

Next, tell Let's Encrypt where to send expiry warnings. Open the configuration file:

Bash
sudo nano /etc/gitlab/gitlab.rb

Add or edit this line:

Config
letsencrypt['contact_emails'] = ['[email protected]']

Apply the change:

Bash
sudo gitlab-ctl reconfigure

GitLab renews the certificate on its own schedule (by default after midnight on every fourth day of the month); you never need to run Certbot.

GitLab emails account confirmations, password resets, invitations and notifications; send them through your relay by setting gitlab_rails['smtp_enable'] = true, smtp_address (smtp.example.com), smtp_port (587), smtp_user_name, smtp_password and smtp_enable_starttls_auto = true in the same gitlab.rb, as shown in GitLab's SMTP settings, then run sudo gitlab-ctl reconfigure.

Step 6 — Tune GitLab for a smaller server (optional)

If your server has less than the 16 GB baseline, GitLab documents settings for memory-constrained environments. The most effective ones go into /etc/gitlab/gitlab.rb:

Config
puma['worker_processes'] = 0
sidekiq['concurrency'] = 10
prometheus_monitoring['enable'] = false

Run sudo gitlab-ctl reconfigure afterwards. The first run with these settings can take a while. GitLab's page for memory-constrained environments also covers Gitaly concurrency limits and memory allocator settings if you need to go further.

Back up and restore

A GitLab backup has two parts. The gitlab-backup tool archives the database, repositories and uploads into a .tar file in /var/opt/gitlab/backups. It does not include the configuration in /etc/gitlab, and especially not gitlab-secrets.json, which holds the keys that decrypt values stored in the database. Back up both:

Bash
sudo gitlab-backup create
sudo ls -lh /var/opt/gitlab/backups
sudo mkdir -p /opt/backups
sudo tar czf /opt/backups/gitlab-etc-$(date +%F).tar.gz /etc/gitlab

Keep the configuration archive somewhere other than the data backups, because together they give full access to your data. If the backup reports file changed as we read it on busy instances, use sudo gitlab-backup create STRATEGY=copy, which needs up to the same amount of disk space again.

To back up every night at 02:00, add this line to root's crontab with sudo crontab -e:

Text
0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1

Limit how long local archives are kept with gitlab_rails['backup_keep_time'] = 604800 (seven days) in gitlab.rb. GitLab can also upload each archive to S3-compatible storage through the backup_upload_connection settings. Either way, copy backups off the server.

Restore. You can only restore into exactly the same GitLab version, installed from the same gitlab-ce package. Install that version, put your saved /etc/gitlab/gitlab-secrets.json and gitlab.rb back in place and run sudo gitlab-ctl reconfigure. Then copy the archive into the backup folder and restore it with Puma and Sidekiq stopped. Use your own archive name; the BACKUP value is the name without _gitlab_backup.tar.

Bash
sudo cp 1791500000_2026_10_09_19.4.1-ce_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git:git /var/opt/gitlab/backups/1791500000_2026_10_09_19.4.1-ce_gitlab_backup.tar
sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
sudo gitlab-ctl status
sudo gitlab-backup restore BACKUP=1791500000_2026_10_09_19.4.1-ce
sudo gitlab-ctl reconfigure
sudo gitlab-ctl start
sudo gitlab-rake gitlab:check SANITIZE=true
sudo gitlab-rake gitlab:doctor:secrets

The last command confirms that the restored secrets can decrypt the values in the database.

Upgrade GitLab

GitLab releases a new minor version every month, and some versions are required upgrade stops that you must install before going further: 18.2, 18.5, 18.8 and 18.11 in GitLab 18, and 19.2, 19.5, 19.8 and 19.11 in GitLab 19 (later stops may not be released yet). GitLab's Upgrade Path tool lists the exact versions for your starting point. At each stop, wait until background migrations have finished before you move on.

The package takes an automatic database backup before it upgrades, but GitLab still asks you to keep a full, current backup of your own. A typical upgrade to a specific version looks like this:

Bash
sudo gitlab-backup create
sudo apt update
apt-cache madison gitlab-ce
sudo apt install gitlab-ce=19.4.1-ce.0
sudo gitlab-rake gitlab:background_migrations:list

apt-cache madison lists the versions in the repository; replace 19.4.1-ce.0 with your target. The last command (GitLab 18.9 and later) shows queued background migrations; you can also check them under Admin, Monitoring, Background migrations. While the upgrade runs, a single-node server shows a deploy message or a 502 page.

Troubleshooting

502 error right after installation, a restart or an upgrade

Puma is still starting; on a small server this can take a minute or more. Check sudo gitlab-ctl status and follow the logs with sudo gitlab-ctl tail puma. If the 502 persists, look at memory with free -h. GitLab Workhorse also returns 502 when a single request takes longer than one minute; for very slow pages you can raise gitlab_workhorse['proxy_headers_timeout'] in gitlab.rb.

Let's Encrypt fails during reconfigure

Let's Encrypt must reach the server on ports 80 and 443 under the name in EXTERNAL_URL. Check the DNS record, open both ports in ufw and in any provider firewall, then run sudo gitlab-ctl reconfigure again. You can force a renewal later with sudo gitlab-ctl renew-le-certs.

Errno::ENOMEM: Cannot allocate memory during backup or upgrade

GitLab needs about 2 GB of available memory for these tasks. If the server already uses swap during normal operation, add memory; otherwise adding swap may be enough to get through the backup or upgrade.

PostgreSQL reports that it could not create a shared memory segment

The bundled PostgreSQL tries to reserve 25% of the server's memory. Set postgresql['shared_buffers'] = "100MB" in gitlab.rb and run sudo gitlab-ctl reconfigure.

reconfigure stops with undefined method for nil:NilClass

gitlab.rb contains an invalid or obsolete setting, often after an upgrade. Compare your file with the current template using sudo gitlab-ctl diff-config, fix the setting and run reconfigure again.

The initial root password no longer works or the file is gone

The file is deleted after 24 hours. Reset the root password with GitLab's Rake task and enter a new password twice:

Bash
sudo gitlab-rake "gitlab:password:reset[root]"

Next steps

Frequently asked questions

Which Ubuntu and Debian versions does GitLab support?

In October 2026 GitLab’s supported platforms table lists Ubuntu 22.04, 24.04 and 26.04 (26.04 from GitLab 19.3) and Debian 11, 12 and 13. Debian 11 and 12 have a proposed last supported GitLab version of 19.3, so use Ubuntu 24.04, Ubuntu 26.04 or Debian 13 for a new server.

How much memory does GitLab CE need?

GitLab’s requirements give 8 vCPU and 16 GB of memory as the baseline for a single-node installation. With the settings for memory-constrained environments, a single node can run with at least 8 GB.

Where do I find the GitLab root password after installation?

Unless you set one during installation, GitLab writes a random password to /etc/gitlab/initial_root_password. The file is deleted automatically after 24 hours, so sign in as root and change the password right away.

Does gitlab-backup include the GitLab configuration?

No. The backup archive does not contain /etc/gitlab. Back up /etc/gitlab/gitlab-secrets.json and /etc/gitlab/gitlab.rb separately, because a restore needs the same secrets file to decrypt values stored in the database.

Can I upgrade GitLab straight to the newest version?

Only if no required upgrade stop lies between your version and the target. GitLab 19 has stops at 19.2, 19.5, 19.8 and 19.11; install each stop’s exact package version and let background migrations finish before you continue.

Sources

Gerar senha

Please confirm