How to Install GitLab with Docker on Ubuntu 22.04

Gitlab Server is an open-source version of the cloud-hosted Gitlab version control. The advantage of self-hosting your repositories over cloud hosting is the total control over your code.

This guide will teach you how to install Gitlab Server using Docker on a Ubuntu 22.04 server. Gitlab server offers two editions - the free Community edition and the paid Enterprise edition. We will be installing the Community edition. If you want more features, you can upgrade it to the Enterprise edition easily.

Prerequisites

  • A server running Ubuntu 22.04.

  • A non-root user with sudo privileges.

  • Uncomplicated Firewall(UFW) is enabled and running.

  • A Fully Qualified domain name (FQDN) pointing to the server like, gitlab.example.com.

  • Everything is updated.

    $ sudo apt update && sudo apt upgrade
    

Step 1 - Configure Firewall

The first step before installing any packages is to configure the firewall to allow HTTP and HTTPS connections.

Check the status of the firewall.

$ sudo ufw status

You should see something like the following.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Allow HTTP and HTTPs ports.

$ sudo ufw allow http
$ sudo ufw allow https

Open port 587 for receiving mails via SMTP. You may be using a different port with your SMTP mailer.

$ sudo ufw allow http
$ sudo ufw allow 587

Check the status again to confirm.

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
587                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)
587 (v6)                   ALLOW       Anywhere (v6)

Step 2 - Install Dependencies

Before installing Gitlab, we need to install certain packages that will be required during the course of our tutorial.

$ sudo apt install ca-certificates curl openssh-server apt-transport-https gnupg lsb-release -y

Some of these packages may be pre-installed on your system.

Step 3 - Change System's SSH port

Gitlab uses the default SSH port which will conflict with the system's SSH port. For best results, it's better to change the system's default port.

To do this, open the /etc/ssh/sshd_config file for editing.

$ sudo nano /etc/ssh/sshd_config

Find the following line, remove the hash(#) in front of it and change the value from 22 to anything else of your choice. For our tutorial, we have picked 2425 by changing

#Port 22

to

 Port 2425

Save the file by pressing Ctrl + X and entering Y when prompted.

Restart the SSH service.

$ sudo systemctl restart sshd

Open port 2425 in the firewall.

$ sudo ufw allow 2425

Close your current SSH session and re-login using the new port.

$ ssh username@<serverIP> -p 2425

Step 4 - Install Docker and Docker Compose

Add Docker's official GPG key.

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg

Run the following command to add the Docker repository.

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update the system to include Docker's repository.

$ sudo apt update

Install Docker.

$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

This tutorial will be using the Docker Compose v2 plugin instead of the older legacy binary. Therefore, the command for running it has changed from docker-compose to docker compose and this is reflected here.

Docker runs with elevated privileges so you will need to use sudo frequently to run commands. The better option is to add your Linux user account to the docker user group.

$ sudo usermod -aG docker ${USER}

The ${USER} variable picks up the currently logged-in system account. If you are not logged in with the user you want to give privileges to, replace ${USER} with the username.

To apply for the new group membership, log out of the server and back in, or use the following command. You will be prompted for the user's password.

$ su - $(USER)

Step 5 - Set up Docker Volumes

Before proceeding with the installation, we need to set the location for Gitlab data and configuration to be accessed via Docker volumes.

Create the Docker volume directory.

$ sudo mkdir /srv/gitlab -p

Create a directory for the Docker compose file.

$ mkdir ~/gitlab-docker

Switch to the directory.

$ cd ~/gitlab-docker

Create an environment variable file and open it for editing.

$ nano .env

Paste the following code to define the $GITLAB_HOME variable.

GITLAB_HOME=/srv/gitlab

The Gitlab container uses host-mounted volumes to store persistent data. The following table shows the mapping of the local location of the Gitlab directories to the location of containers and their respective usage.

Local Location Container Location Usage
$GITLAB_HOME/data /var/opt/gitlab For storing application data.
$GITLAB_HOME/logs /var/log/gitlab For storing logs.
$GITLAB_HOME/config /etc/gitlab For storing Gitlab configuration.

Step 6 - Install Gitlab using Docker Compose

Make sure you are inside the Docker compose directory of Gitlab.

Create and open the Docker compose configuration file for editing.

$ nano docker-compose.yml

Paste the following code in it.

version: '3.6'
services:
  web:
    image: 'gitlab/gitlab-ee:latest'
    container_name: 'gitlab-howtoforge'
    restart: always
    hostname: 'gitlab.example.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.example.com'
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "email-smtp.us-west-2.amazonaws.com"
        gitlab_rails['smtp_user_name'] = "SESUsername"
        gitlab_rails['smtp_password'] = "SESKey"
        gitlab_rails['smtp_domain'] = "example.com"
        gitlab_rails['smtp_enable_starttls_auto'] = true
        gitlab_rails['smtp_port'] = 587
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['gitlab_email_from'] = '[email protected]'
        gitlab_rails['gitlab_email_reply_to'] = '[email protected]'
        # Add any other gitlab.rb configuration here, each on its own line
    ports:
      - '80:80'
      - '443:443'
      - '22:22'
      - '587:587'
    volumes:
      - '$GITLAB_HOME/config:/etc/gitlab'
      - '$GITLAB_HOME/logs:/var/log/gitlab'
      - '$GITLAB_HOME/data:/var/opt/gitlab'
    shm_size: '256m'

Let us take a look at all the options defined in the file.

  • image refers to the location of the Docker image of Gitlab on Dockerhub.
  • container_name allows you to apply a label to your docker container, for use when referencing the container within a Docker network.
  • restart specifies a restart policy for the container. Setting it to always means that a container if exited, will automatically get restarted.
  • hostname defines the container's internal hostname or in this case, the URL where your Gitlab will be installed.
  • environment supplies the variable GITLAB_OMNIBUS_CONFIG which allows you to enter any Gitlab configuration setting.
  • external_url refers to the domain where your Gitlab will be installed. Using https protocol ensures automatic installation of the Let's Encrypt SSL certificate.
  • SMTP details - we have included SMTP details so that the Gitlab instance can send important emails and notifications. For our tutorial, we are using Amazon's SES service. You can however use any service of your choice. Check the Gitlab documentation for SMTP mailers to learn how to configure them.
  • ports tell the container to publish ports or a range of ports to the host. Since Gitlab needs ports 22(SSH), 80(HTTP), 443(HTTPS), and 587(SMTP), they have been exposed to the system. If you want Gitlab to use a non-standard port on your server (probably because it's not available), you would provide the host port first and then the container port. For eg, since your server is already using SSH(22) port, you can tell Gitlab to use SSH via a different port, say 3333. Then you would change 22:22 in the above file to 3333:22. You will also need to add the line gitlab_rails['gitlab_shell_ssh_port'] = 3333 under GITLAB_OMNIBUS_CONFIG above.
  • volume defines the directories present on the server to store persistent data. As defined in step 5, $GITLAB_HOME can now be used in the compose file to mount relevant directories on the container.
  • shm_size refers to the shared memory used by the container. By default, Docker allocates 64MB to the shared memory directory (mounted at /dev/shm). This can prove insufficient for the Prometheus metrics that the Gitlab container generates. Therefore, a minimum of 256MB of shared memory ensures the smooth running of the docker. You can increase its value depending upon the RAM your system has. Alternatively, you can disable Prometheus metrics from the admin area after installation. We will explore this in the next step.

Start the Gitlab Docker container.

$ docker compose up -d

It will take a few minutes for the process to finish. You can follow the progress using the Docker logs.

$ docker logs gitlab-howtoforge -f

Press Ctrl + C to exit the monitoring of the log.

You can check the status of the Gitlab container using the following command.

$ docker ps

Starting with Gitlab 14.0, it automatically generates a root password and stores it in the initiall_root_password file. This file can be found in the /srv/gitlab/config directory. Run the following command to view the root password.

$ sudo cat /srv/gitlab/config/initial_root_password

You will receive a similar output.

# WARNING: This value is valid only in the following conditions
#          1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it was provided before database was seeded for the first time (usually, the first reconfigure run).
#          2. Password hasn't been changed manually, either via UI or via command line.
#
#          If the password shown here doesn't work, you must reset the admin password following https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password.

Password: Hz3t7Etn18wB6VAfBWyDlYbN2VQdMCO0xIIENfDHcFo=

# NOTE: This file will be automatically deleted in the first reconfigure run after 24 hours.

Copy the password and save it for later use. Now that everything is set up, we can proceed with the configuration.

Step 7 - Configure Gitlab

Accessing Gitlab

Open the URL https://gitlab.example.com in your browser and you will get the following login screen.

Gitlab EE Login Screen

Enter root as the username and the password, you got in the previous step to sign in to your Gitlab dashboard. On signing in, you will be taken to the following dashboard screen.

Gitlab Dashboard

As you can see, Gitlab has already created a project to monitor the instance.

Restrict Public Sign-ups

By default, anyone can create an account and gain access. If you don't want it, you can turn it off. Fortunately, the setting for it is shown in the form of a pop-up screen on the dashboard. Click the Turn off button to restrict public sign-ups on your Gitlab instance. Doing so will redirect you to the following settings page.

Gitlab Sign-up restrictions

Uncheck the option Sign-up enabled to restrict them. Press the button Save changes to apply the setting.

In case, you don't see the pop-up in your dashboard, you can access the settings page by clicking the Menu button and accessing the Admin panel from there.

Gitlab Admin Menu

Once inside the admin panel, hover your mouse over the Settings option in the left sidebar and click on the General sub-menu. From there you can reach the Sign-up restrictions panel.

Gitlab General Admin Settings

Configure Gitlab Profile

Your default profile is pretty much bland and doesn't have anything to show for it. To change that, click on the user icon in the upper left-hand corner to bring up the drop-down menu and select the Edit profile option.

Gitlab Edit Profile button

You will be taken to the Profile settings page where you can add your name, e-mail, and other information about yourself. Click Update profile settings when you are done. Don't go back to the homepage as we have some more things to configure here.

Gitlab Edit Profile Page

Change Root Password

This is one of the most important steps. You should change your default root password immediately. With earlier versions, Gitlab required you to change it as part of the installation but now it has made it optional. To change your password, click on the Password menu from the left sidebar.

Gitlab Password Change Screen

Enter your password details and click Save password to make the change. You will be logged out of your instance and will have to log in again.

Change User name

You can change your default Gitlab username from root to anything of your choice. To do that, click the Account menu from the left sidebar.

Gitlab Account Username change page

Once on the page, enter your new username and click the Update username button to make the change. You will be prompted again for confirmation. Press the Update username button again to confirm the change.

You should also enable two-factor authentication here to improve your account security.

Disable Prometheus Metrics and improve Privacy

In the previous step, we discussed increasing the shared memory size for the droplet and to keep it at a minimum of 256 MB. It is required mainly to store the Prometheus metrics-related data on the disk. If you are not using the feature, you should disable the feature. You can do it only post-installation. To disable it, open the Admin Panel from the menu bar.

Once inside the Admin panel, open the Settings >> Metrics and profiling menu option.

Gitlab Metrics and profiling menu

On the Metrics page, expand the Metrics - Prometheus section and uncheck the Enable health and performance metrics endpoint option. Click the Save changes button to implement the change.

Gitlab Prometheus Setting

Gitlab also collects usage information from every installation. If you value privacy and don't want it to happen, expand the Usage statistics option on the same page and Uncheck the Enable Service Ping option. Click the Save changes button to implement the change.

Gitlab Usage Statistics

Step 8 - Creating your first Project

Let us try to create our first project and push a commit.

Adding your SSH Key

Before proceeding any further, we should add our SSH key. This allows us to interact with our installation without using any passwords. If you have an SSH key, you can skip the following command. If you don't have one, you can create one using the following command.

$ ssh-keygen -t ed25519 -C "gitlab.example.com"

This command is common to macOS, Linux, and Git Bash/WSL on Windows. Accept the defaults and enter a strong passphrase. We are creating the SSH keys on Windows Powershell Terminal.

Generating public/private rsa key pair.
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\<username>/.ssh/id_ed25519):
Enter same passphrase again:
Your identification has been saved in C:\Users\<username>/.ssh/id_ed25519.
Your public key has been saved in C:\Users\<username>/.ssh/id_ed25519.pub.
SHA256:CI3Ja1LSTN+j4LQnDYkAoP+DvZB8SWrD26zDyUBRbUY gitlab.example.com
+--[ED25519 256]--+
|* ..+E           |
|. + / o o        |
| o = B o .       |
|. o B = S        |
|.o X +           |
| +X.*            |
| .=B o           |
+----[SHA256]-----+

Add the private key identity to the SSH authentication agent. Make sure the OpenSSH Authentication Agent service is running if you are on Windows. If you are on Linux or macOS, run the following command.

$ eval $(ssh-agent -s)

Add the key.

$ ssh-add C:\Users\<username>/.ssh/id_ed25519

On Linux and macOS, the command will change to

$ ssh-add ~/.ssh/id_ed25519

You will be prompted for the passphrase. Enter it and the key will be added.

Next, we need to save these settings to the ~/.ssh/config file. On Windows, this will be the C:\Users\<username>\.ssh directory. Paste the following code at the end of the file.

Host gitlab.example.com
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_ed25519

In this file, the path name will remain the same across all operating systems. Save the file.

Next, we need to copy the public key to our Gitlab account. You can display your public key via the following command. The path name will again work across all operating systems here.

$ cat ~/.ssh/id_ed25519.pub

You will get a similar output.

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAml2KPhmGkdMWv7jksLKO13u3g1zI9CumKDQSpv7lYh gitlab.example.com

Open your profile settings in Gitlab and select the SSH Keys menu from the left sidebar.

Gitlab SSH Keys Menu

Paste the SSH key in the box provided and click on Add Key to proceed.

Gitlab SSH Keys Page

Next, we need to test whether our SSH connection is working successfully. Run the following command on your PC terminal.

$ ssh -T [email protected]

You will get a similar output. First, you will be asked to add the SSH key to your system's Known hosts list. Type yes to proceed. You will also get a warning that the SSH key for the Gitlab instance and your server IP is not the same and will again be asked if you want to continue. Type yes again. Finally, you will get a success message confirming your connection to your Gitlab instance.

The authenticity of host 'gitlab.example.com (192.0.2.0)' can't be established.
ECDSA key fingerprint is SHA256:g5mOqAY2A3lhXW0flnLGdSU7RrDnbRFKVJCquAhLXqk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'gitlab.example.com' (ECDSA) to the list of known hosts.
Warning: the ECDSA host key for 'gitlab.example.com' differs from the key for the IP address '192.0.2.0'
Are you sure you want to continue connecting (yes/no)? yes
Offending key for IP in C:\Users\navjo/.ssh/known_hosts:7
Welcome to GitLab, @navjot!

Now, we can move on to creating our first repository and make some commits.

Creating a Project

Each repository in Gitlab belongs to a project. A project includes a repository, issue tracker, merge requests, wiki, continuous integration and continuous delivery (CI/CD) pipelines, and lots of other features.

To create your first repository, click the New project button on your homepage.

Gitlab New Project Button

You will be taken to the New Project page where you will be given multiple options on how to create a new project.

Gitlab Create Project page

Select the Create blank project option to proceed. On the next page, enter the project name. Select your username from the dropdown menu in the Project URL option. Set your project slug. Enter a description of the project if you like and change the visibility of the project as per your need. You can Initialize your repository with a README file.

Gitlab New Project Page

Once you are done, click Create project. You will be taken to your repository page with just a single blank README.md file.

Gitlab Project Page

Now that our repository is live, let us try adding a changelog from the command line. Enter the following commands on your computer to create a CHANGELOG file and push it back to your repository. Make sure you have Git installed on your computer.

The first step is to clone the repository. You can clone either using SSH or HTTPS. Clone using SSH. You will be asked for the passphrase.

$ git clone [email protected]:user/howtoforge-test.git

Enter the remainder of the commands to create and push the CHANGELOG file.

$ cd howtoforge-test
$ touch CHANGELOG  # Or create the file in your editor and enter a project description
$ git add CHANGELOG
$ git commit -m "add Changelog"
$ git push -u origin main

You will be prompted for the passphrase again during the push command.

Go back to your Gitlab project page and you will see the CHANGELOG file in it. Congratulations! You have successfully created your first project and committed a file to it.

Gitlab Project after commit

Step 9 - Manage Gitlab Container

Let us see how you can manage the Gitlab container using simple commands.

If at any point you want to stop the container, issue the following command from inside the Docker compose directory.

$ docker compose down

To start them again, issue the following command.

$ docker compose up -d

If you want to change any setting or add a setting to your Gitlab instance, you can do so by editing the docker-compose.yml file under the GITLAB_OMNIBUS_CONFIG variable. Once you have made your change, you will need to restart the container to implement the change. Issue the following commands to update the container with the new configuration.

$ docker compose down --remove-orphans
$ docker compose up -d

To restart the container, issue the following command. The following restart command doesn't pick up any changes made to the Docker compose file though.

$ docker compose restart

Access the container shell.

$ docker exec -it <container name> bash

Step 10 - Backup Gitlab

Backing up Gitlab can be done via a single command.

$ docker exec -t gitlab-howtoforge gitlab-backup create

The backup file is saved in the /srv/gitlab/data/backups directory. This backup doesn't contain your gitlab-secrets.json configuration file. This file is in the /srv/gitlab/config directory. Therefore, you need to backup this file separately. There is another configuration file, gitlab.rb, which contains all the settings for the Gitlab instance. But in our case, we used the GITLAB_OMNIBUS_CONFIG variable in our compose file, therefore this file is not used by Gitlab. To make any changes to Gitlab, you will need to define them via the variable. Hence, you will need to backup the compose file as well.

You can create a cron entry to backup your Gitlab installation regularly.

Step 11 - Restore Gitlab

To restore Gitlab, you should have a working Gitlab installation on another system. You will also need to copy your configuration directory and overwrite the existing installation's configuration.

Restoring Gitlab requires running several commands. First, you need to stop the processes connected to the database.

$ docker exec -it <name of container> gitlab-ctl stop puma
$ docker exec -it <name of container> gitlab-ctl stop sidekiq

Replace <name of container> with the name of the container on your new server.

Verify that the processes are down before continuing.

$ docker exec -it <name of container> gitlab-ctl status

Copy the backup file to the /srv/gitlab/data/backups directory. Create the directory if it doesn't exist.

Run the restore command. You need to remove the _gitlab_backup.tar portion of the file name from the command.

$ docker exec -it <name of container> gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

Copy the gitlab-secrets.json file and overwrite the existing copy in the /srv/gitlab/config directory of the new server. Also, copy all the Gitlab settings from the backed-up compose file to the file on the newer container.

Restart the Gitlab container. We can't use the docker compose restart command directly as it won't pick any changes made to the compose file which we need.

$ docker compose down --remove-orphans
$ docker compose up -d

Check Gitlab.

$ docker exec -it <name of container> gitlab-rake gitlab:check SANITIZE=true

Step 12 - Upgrade Gitlab

To upgrade Gitlab, the first step is to take a backup as shown in the previous stop.

Next, switch to Gitlab's Docker compose directory.

$ cd ~/gitlab-docker

Next, stop and remove the existing container. Your data will be retained though.

$ docker compose down --remove-orphans

Pull the latest version of the Gitlab docker image.

$ docker compose pull

Start the containers again.

$ docker compose up -d

This process is fine for upgrading between minor versions of Gitlab but when you upgrade to a major version, you will need to follow extra steps and take precautions. You should refer to Gitlab's documentation before performing the upgrade.

Conclusion

This concludes our tutorial where you learned how to install Gitlab using Docker on a Ubuntu 22.04 server. You also created your first project and committed a file to it from your PC. If you have any questions, post them in the comments below.

Share this page:

2 Comment(s)