Uptimezen Blog

Tutorial: How to deploy SSL enabled (Let's Encrypt) Jekyll site with custom domain on Gitlab Pages

February 18, 2019 | 7 Minute Read

Gitlab pages is the best way to quickly publish websites for your projects. Every gitlab project will be available under HTTPS for default pages domain (*.gitlab.io). If you want to secure your Jekyll Website with SSL certificate, you need to issue a certificate for (sub)domain then import the keys into Gitlab UI. This process looks pretty easy but sometimes it gets tricky during validation process.

Before starting configuration steps , it is assumed that ;

  • You have already domain (Godaddy or another hosting provider)
  • You have already create project and run Jekyll successfuly on Gitlab
  • Your website is running without any issue and accessible from https://username.gitlab.io or https://groupname.gitlab.io (if not please make your project public from project settings)
  • You have already domain and validation is completed (https://blog.uptimezen.com/Gitlab-domain-validation/)

A. Getting SSL Certificate (Let’s Encrypt)

Due to not having access to shared runner over on Gitlab over SSH , you need to generate SSL certificate on your linux computer. I used my Ubuntu 16.04 LTS but you can use other linux distribution as well.

If you are already using Ubuntu please move forward with following steps, otherwise please install Ubuntu instance. (You can build quickly on VM or create new one from Google Cloud for Free if you have gmail account - https://cloud.google.com/compute/docs/quickstart-linux).

Step 1: Open a new terminal window on your Ubuntu instance (you can connect over SSH )

Step 2: Install the “Git” on your Ubuntu instance

apt-get install git-core 

Step 3: Download the letsencrypt-auto utility. (this tool won’t work for Windows users)

  git clone https://github.com/letsencrypt/letsencrypt

Step 4: Navigate to letsencrypt directory by typing the following command

  cd letsencrypt 

Step 5: Since we are running on your own Ubuntu server instead of Gitlab servers , we have to do a bit of manual work. Please execute the command.

  ./letsencrypt-auto certonly -a manual -d subdomain.domain.com 

Step 6: After you accept that your IP will be publicly logged a message like the following will be appear

 Make sure your web server displays the following content at
 http://Subdomain.YOURDOMAIN.org/.well-known/acme-challenge/5TBu788fW0tQ5EOwZMdu1Gv3e9C33gxjV58hVtWTbDM
 before continuing:

 5TBu788fW0tQ5EOwZMdu1Gv3e9C33gxjV58hVtWTbDM.ewlbSYgvIxVOqiP1lD2zeDKWBGEZMRfO_4kJyLRP_4U

#
 # output omitted
#
Press ENTER to continue

Step 7: At this point , you need to create page including code (generated by Let’s Encrypt) and serve it on given URL.

B. Creating Public Page on Jekyll for Let’s Encrypt Validation

The problem comes with setting up public page including your Let’s encrypt code during validation process. Majority of guide tell us how to get SSL certificate over Let’s encrypt but not have information about how to make public page including Let’s encrypt code on Jekyll without extension. If you cannot serve this code on your page , you probably get “Invalid Response” message from Let’s encrypt server.

    Waiting for verification...
    Cleaning up challenges
    Failed authorization procedure. blog.uptimezen.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: 
    Invalid response from http://blog.uptimezen.com/.well-known/acme-challenge/N4Mf7BY0jwWPdnSryalqupzHVSWnvLtOPdF5ALuPpbE: "\n<!DOCTYPE html>\n<html>\n<head>\n  
    <meta content=\"width=device-width, initial-scale=1, maximum-scale=1\" name=\"viewport\">\n  <title>"
    
    IMPORTANT NOTES:
     - The following errors were reported by the server:
    
       Domain: blog.uptimezen.com
       Type:   unauthorized
       Detail: Invalid response from
       http://blog.uptimezen.com/.well-known/acme-challenge/N4Mf7BY0jwWPdnSryalqupzHVSWnvLtOPdF5ALuPpbE:
       "\n<!DOCTYPE html>\n<html>\n<head>\n  <meta
       content=\"width=device-width, initial-scale=1, maximum-scale=1\"
       name=\"viewport\">\n  <title>"
    
       To fix these errors, please make sure that your domain name was
       entered correctly and the DNS A/AAAA record(s) for that domain
       contain(s) the right IP address.

This error occurs because Let’s encrypt server cannot access or read the code published on your public page.

Step 8: Open your Gitlab account then Go to Files under Repository (Projects –> You Project –> Repository –> Files)

Step 9: Before create public file for Let’s Encrypt , you have to create directory(/.well-known/acme-challenge) in the root directory of repository.

i . Click on “New Directory” then write directory name as .well-know , hit Create Directory button ii. Double click on .well-known folder then click on new directory then enter name as “acme-challenge”

Step 10: Go to /.well-known/acme-challenge/ directory then create new folder inside acme-challenge directory.

i. Enter the “file name” as displayed into Let’s encrypt response path

Exm: http://Subdomain.YOURDOMAIN.org/.well-known/acme-challenge/N4Mf7BY0jwWPdnSryalqupzHVSWnvLtOPdF5ALuPpbE is our url that should contain public file and file name is

N4Mf7BY0jwWPdnSryalqupzHVSWnvLtOPdF5ALuPpbE.

ii. Enter code that is provided by Let’s encrypt response (“Create a file containing just this data” section) in step 6,

Exm: 5TBu788fW0tQ5EOwZMdu1Gv3e0C33gxjV58hVtWTbDM.ewlbSYgvIxVOqiP1ld2zennWBGEZMRfO_4kJyLRP_4U

Then “save file” on Gitlab.

Step 11: When you complete the steps above directory will not be public. To make it public , please add following entry into .gitlab-ci.yml file.

script: 
- cp -a .well-known public/

Step 12: Now that everything is working as expected if your page including code is accessible over http://Subdomain.YOURDOMAIN.org/.well-known/acme-challenge/N4Mf7BY0jwWPdnSryalqupzHVSWnvLtOPdF5ALuPpbE , go back to terminal then hit “Enter”

Step 13: You will get following response from server

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/blog.uptimezen.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/blog.uptimezen.com/privkey.pem
   Your cert will expire on 2019-01-19. To obtain a new or tweaked
   version of this certificate in the future, simply run
   letsencrypt-auto again. To non-interactively renew *all* of your
   certificates, run "letsencrypt-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

C. Inserting SSL Keys into Gitlab pages

Step 14: Your keys saved at /etc/letsencrypt/live/subdomain.domain.com on Ubuntu instance. To access them please execute following command,

cd /etc/letsencrypt/live/subdomain.domain.com/

There 4 files are available (cert.pem , chain.pem , fullchain.pem and privkey.pem) into directory but we will use fullchain.pem and privkey.pem for Gitlab.

Step 15: You can display the file content with “cat” option. Please execute following command to read key file’s content

cat cert.pem 
cat fullchain.pem

Step 16: Please copy the content of each file in step 14 and insert into your project page on Gitlab. Then click on “Save”