Install GitLab CE on Amazon Linux 2 with Let’s Encrypt SSL

Posted on 261 views

GitLab has evolved to be a complete DevOps platform delivered as a single application. With GitLab you can comfortably do source code management, project planning, CI/CD pipelines and monitoring of deployments triggered from GitLab. GitLab provides a Git-repository manager with built-in issue-tracking, wiki, and continuous integration and deployment pipeline features. The software is developed by GitLab Inc and released under open-source license.

In this short guide we will be installing GitLab CE on an Amazon Linux 2 EC2 instance server. For this installation you need to have an SSH access to the EC2 instance with sudo, a domain name or subdomain used to install GitLab CE on Amazon Linux 2 and an email address that will be used for notifications on expiry of Let’s Encrypt SSL Certificates.

My GitLab CE Setup on Amazon Linux 2 Server

I have an EC2 server with below specifications:

  • Public IP Address:
  • Server Hostname:
  • Login Username: ec2-user
  • Let’s Encrypt notifications email: [email protected]

Map an A record to DNS name of the server.


Step 1: Update Amazon Linux Server

Initiate an SSH session to your instance:

$ ssh [email protected]
Warning: Permanently added '' (ECDSA) to the list of known hosts.
Enter passphrase for key '/Users/jkmutai/.ssh/id_rsa':

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
2 package(s) needed for security, out of 13 available
Run "sudo yum update" to apply all updates.
[[email protected] ~]$

Update all the system packages to the latest versions available in repositories.

sudo yum -y update

It is always recommended to reboot the system once the upgrade is done.

sudo reboot

Step 2: Set Correct Server hostname

Once the server is rebooted login and set correct server hostname.

sudo hostnamectl set-hostname --static
sudo hostnamectl set-hostname --transient

Update cloud init configuration to persist hostname across server reboots.

$ sudo vim /etc/cloud/cloud.cfg

Add below line at the end.

preserve_hostname: true

Reboot the server to validate the change is persistent.

sudo systemctl reboot

Check current server hostname.

[[email protected] ~]$ hostnamectl
   Static hostname:
         Icon name: computer-vm
           Chassis: vm
        Machine ID: ec239da046efe33c7665d4508a7d0a61
           Boot ID: 1e38214807fb4591bff2d68438765f22
    Virtualization: xen
  Operating System: Amazon Linux 2
       CPE OS Name: cpe:2.3:o:amazon:amazon_linux:2
            Kernel: Linux 4.14.198-152.320.amzn2.x86_64
      Architecture: x86-64

It means we’re good to go to the next step.

Step 3: Install Postfix Local Mail Agent

Postfix can be installed and configured as local mail server for sending notifications:

sudo yum -y install postfix

Start and enable Postfix service after the installation.

sudo systemctl enable postfix
sudo systemctl start postfix

More information on mail configurations, e.g using external email relays can be found on configure an external SMTP server page.

Step 4: Add the GitLab CE Repository to Amazon Linux 2

The next step is addition of GitLab on to our Amazon Linux 2 server. Accomplish this by running below commands in your terminal as user with sudo privileges.

sudo tee /etc/yum.repos.d/gitlab_gitlab-ce.repo<

This command creates repository file /etc/yum.repos.d/gitlab_gitlab-ce.repo.

Step 5: Install GitLab CE on Amazon Linux 2

If the repository is added to the system you can start the installation of GitLab CE on Amazon Linux 2 server.

sudo yum install gitlab-ce

Review the dependency tree and accept installation of GitLab CE on Amazon Linux 2 machine.

Dependencies Resolved

 Package                                      Arch                         Version                                   Repository                              Size
 gitlab-ce                                    x86_64                       13.4.3-ce.0.el7                           gitlab_gitlab-ce                       761 M
Installing for dependencies:
 audit-libs-python                            x86_64                       2.8.1-3.amzn2.1                           amzn2-core                              79 k
 checkpolicy                                  x86_64                       2.5-6.amzn2                               amzn2-core                             294 k
 libcgroup                                    x86_64                       0.41-21.amzn2                             amzn2-core                              66 k
 libselinux-python                            x86_64                       2.5-12.amzn2.0.2                          amzn2-core                             237 k
 libsemanage-python                           x86_64                       2.5-11.amzn2                              amzn2-core                             115 k
 policycoreutils-python                       x86_64                       2.5-22.amzn2                              amzn2-core                             454 k
 python-IPy                                   noarch                       0.75-6.amzn2.0.1                          amzn2-core                              32 k
 setools-libs                                 x86_64                       3.3.8-2.amzn2.0.2                         amzn2-core                             618 k

Transaction Summary
Install  1 Package (+8 Dependent packages)

Total download size: 763 M
Installed size: 1.6 G
Is this ok [y/d/N]: y

Import GPG keys when prompted to do so.

Total                                                                                                                              87 MB/s | 763 MB  00:00:08
Retrieving key from
Importing GPG key 0x51312F3F:
 Userid     : "GitLab B.V. (package repository signing key) "
 Fingerprint: f640 3f65 44a3 8863 daa0 b6e0 3f01 618a 5131 2f3f
 From       :
Is this ok [y/N]: y
Retrieving key from
Importing GPG key 0xF27EAB47:
 Userid     : "GitLab, Inc. "
 Fingerprint: dbef 8977 4ddb 9eb3 7d9f c3a0 3cfc f9ba f27e ab47
 From       :
Is this ok [y/N]: y

If you have firewalld enable http and https:

sudo firewall-cmd --add-service=http,https --permanent
sudo firewall-cmd --reload

On the AWS Security group add the http and https protocol to list of allowed services in Inbound rules.


Save the rules once done.

Step 6: Secure GitLab CE Server with Let’s Encrypt SSL Certificate

Stop GitLab services.

$ sudo gitlab-ctl stop
ok: down: alertmanager: 0s, normally up
ok: down: gitaly: 0s, normally up
ok: down: gitlab-exporter: 0s, normally up
ok: down: gitlab-workhorse: 1s, normally up
ok: down: grafana: 0s, normally up
ok: down: logrotate: 0s, normally up
ok: down: nginx: 1s, normally up
ok: down: node-exporter: 0s, normally up
ok: down: postgres-exporter: 1s, normally up
ok: down: postgresql: 0s, normally up
ok: down: prometheus: 1s, normally up
ok: down: puma: 0s, normally up
ok: down: redis: 0s, normally up
ok: down: redis-exporter: 1s, normally up
ok: down: sidekiq: 0s, normally up

Edit the configuration and set Let’s Encrypt Settings.

$ sudo /etc/gitlab/gitlab.rb
# Let's Encrypt integration
letsencrypt['enable'] = true
letsencrypt['contact_emails'] = ['[email protected]'] # This should be an array of email addresses to add as contacts
letsencrypt['auto_renew'] = true

Enable HTTPS and set External URL like below:

external_url ''

Under the ## GitLab NGINX section, enable Nginx and redirect http traffic to https:

nginx['enable'] = true
nginx['redirect_http_to_https'] = true

Reconfigure GitLab services.

sudo gitlab-ctl reconfigure

Confirm it is successfully reconfigured.

Recipe: letsencrypt::enable
  * crond_job[letsencrypt-renew] action create
    * file[/var/opt/gitlab/crond/letsencrypt-renew] action create
      - create new file /var/opt/gitlab/crond/letsencrypt-renew
      - update content in file /var/opt/gitlab/crond/letsencrypt-renew from none to bf6734
      --- /var/opt/gitlab/crond/letsencrypt-renew	2020-10-10 07:47:54.466643024 +0000
      +++ /var/opt/gitlab/crond/.chef-letsencrypt-renew20201010-7771-qt1ffz	2020-10-10 07:47:54.466643024 +0000
      @@ -1 +1,2 @@
      +25 0 */4 * * root /opt/gitlab/bin/gitlab-ctl renew-le-certs
      - change owner from '' to 'root'
      - change group from '' to 'root'

  * ruby_block[display_le_message] action nothing (skipped due to action :nothing)
  * ruby_block[save_auto_enabled] action run
    - execute the ruby block save_auto_enabled
Recipe: gitlab::gitlab-rails
  * execute[clear the gitlab-rails cache] action run (skipped due to not_if)
Recipe: registry::enable
  * runit_service[registry] action restart (up to date)
Recipe: nginx::enable
  * execute[reload nginx] action run
    - execute gitlab-ctl hup nginx
Recipe: letsencrypt::enable
  * ruby_block[display_le_message] action run
    - execute the ruby block display_le_message
Recipe: crond::enable
  * runit_service[crond] action restart (up to date)

Running handlers:
Running handlers complete
Chef Infra Client finished, 80/955 resources updated in 37 seconds
gitlab Reconfigured!

Start all GitLab services.

sudo gitlab-ctl restart

Confirm status:

$ sudo gitlab-ctl status
run: alertmanager: (pid 3513) 20s; run: log: (pid 3509) 20s
run: crond: (pid 3524) 20s; run: log: (pid 3522) 20s
run: gitaly: (pid 3476) 20s; run: log: (pid 3475) 20s
run: gitlab-exporter: (pid 3517) 20s; run: log: (pid 3516) 20s
run: gitlab-workhorse: (pid 3503) 20s; run: log: (pid 3502) 20s
run: grafana: (pid 3514) 20s; run: log: (pid 3510) 20s
run: logrotate: (pid 3518) 20s; run: log: (pid 3515) 20s
run: nginx: (pid 3499) 20s; run: log: (pid 3498) 20s
run: node-exporter: (pid 3501) 20s; run: log: (pid 3500) 20s
run: postgres-exporter: (pid 3512) 20s; run: log: (pid 3508) 20s
run: postgresql: (pid 3488) 20s; run: log: (pid 3487) 20s
run: prometheus: (pid 3520) 20s; run: log: (pid 3519) 20s
run: puma: (pid 3490) 20s; run: log: (pid 3489) 20s
run: redis: (pid 3478) 20s; run: log: (pid 3477) 20s
run: redis-exporter: (pid 3511) 20s; run: log: (pid 3507) 20s
run: registry: (pid 3525) 20s; run: log: (pid 3523) 20s
run: sidekiq: (pid 3491) 20s; run: log: (pid 3483) 20s

Manual Let’s Encrypt Certificate generation (Not recommended)

If you prefer to request and manage Let’s Encrypt Certificates manually then perform the following actions.

Enable EPEL repository:

sudo amazon-linux-extras install epel

Install certbot tool that we’ll use to request for Let’s Encrypt SSL certificates.

sudo yum install -y python2-certbot-apache.noarch
$ certbot --version
certbot 1.7.0

Set Domain name and Email notifications address.

EMAIL="[email protected]"

Request for Certificates.

sudo certbot certonly --standalone -d $DOMAIN --preferred-challenges http --agree-tos -n -m $EMAIL --keep-until-expiring

Here is my request response:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for
Waiting for verification...
Cleaning up challenges

 - Congratulations! Your certificate and chain have been saved at:
   Your key file has been saved at:
   Your cert will expire on 2021-01-08. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:
   Donating to EFF:          

Provide SSL certificates Path.

nginx['ssl_certificate'] = "/etc/letsencrypt/live/"
nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/"

Step 7: Access GitLab CE Console

Next open the GitLab CE Web console, for me this is and set root password.


Check certificate information details.


Gravatar Image
A systems engineer with excellent skills in systems administration, cloud computing, systems deployment, virtualization, containers, and a certified ethical hacker.