I would like to write a small guide of recommendations for host your static website (blog, portfolio, landing page, etc.) in GitLab.com. Why not GitHub.com?, basically because of this open Feature Request, you can not (for the moment) use your own SSL Certificates and custom domain in GitHub Pages. You should also read my previous article where I describe why I decided to do this.
This guide is divided into 4 major topics that I will proceed to document.
Three important points to keep in mind about hosting your content in GitLab:
You should create in the root folder of your content a GitLab’s configuration file, the name of the file is important,
must be called
.gitlab-ci.yml and with this file you’ll tell GitLab what to do with your content.
For instance, to build a plain HTML site, this file configuration should be enough:
Important sections from previous configuration file are:
- script section: You will indicate a list of commands to build your content in GitLab.
- artifact section: This should point always to
If you want to read a real and complete GitLab configuration file you can use this one from my blog based on Hexo.io, a static site generator in Node.js. Also in here you can search default projects containing GitLab configuration files.
The rule of thumb is one public site per GitLab user or per GitLab group.
If you understand this convention, the moment you push your content to your repository in GitLab and your repo includes a proper GitLab configuration file, your publishded content will be automatically available in the url http://YOURUSERNAME.gitlab.io
As usual you can have multiple repositories in your GitLab account, but only one of the repositories is taken into account to publish your content. The GitLab convention says that the repository should be called
username.gitlab.io, this is why the repository that hosts my blog is called
In the case you have a group and several projects within, the same rule applies. You must create a repository called
yourgrup.gitLlab.io in order to publish the content in the url
To check if GitLab is serving your content through the default url convention, you could use the Administration panel of your repository, go to Settings > Pages and check if the url is available.
So far you can publish your content in a GitLab public url (it includes GitLab SSL Certificates), however, if you want also to link your content with a custom domain, keep the reading.
Once your content is available in a Gitab url you should create a new DNS A record in your DNS configuration and should point to GitLab server’s IP (IP: 188.8.131.52). I’m using 1and1 as my Domain dealer, so this is how it should looks the setup.
1.- Click on DNS Configuration
2.- In A/AAAA records section instead of 1and1 IP address select Another IP and introduce this one 184.108.40.206
3.- In CNAME records section you should add a new entry pointing to your Gitlab public url
To prove that the domain has been configured correctly, you can create a new domain on the Administration page of your Gitlab repository, go to Settings > Pages and click on New Domain.
Add your domain and just save it. If everything has correctly setup, you will be able to access your published content through your domain url.
We are almost done. In fact, if you’re not interested in Https, you can finish the guide here, but since you’re brave I recommend you to continue.
It’s time now to create and validate a TLS certificate for your domain. The fastest and most effective way is to rely on Docker, some time ago I wrote about this fabulous technology in my article Docker & Raspberry Pi, perfect combo!.
If you have Docker installed, using the official Let’s Encrypt Docker image called Cerbot you can generate and validate certificates in less than five minutes.
From previous command in Line 2, with
-d option you should add your domain with and without www and with
-m option you should add the email address to receive renewal reminders.
Below is how it looks the output after executes previous commands
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Cerbot script will challengue you to prove you are the owner of the domain using a server file validation.
From previous step 3.1 do not press ENTER until you do what the script says:
Create a file containing just this data:
Now, steps involved to publish this validation file in your GitLab public url will depend on how complex your build process is.
Assuming that your build process uses the entire repository as published content, you could have done something similar to the next commands to validate Let’s Encrypt challenge.
mkdir -p .well-known/acme-challenge
When you push this code to Gitlab you will see in the Pipelines view a new build job running.
Once GitLab completes the build you could check if everything has went well by accessing the Cerbot url from step 3.1, in my case is http://toub.es/.well-known/acme-challenge/ei63vo4bg79x9Z7P-1lyAPyvDCa3FodyPgUpRt8MA3M
If you see the content, it’s time to tell Cerbot to finish the process we started in step 3.1
This is what would happen if Certbot validates the authentication process.
Waiting for verification...
Since we use Docker with option
-v, new TLS certificates are available in the
cert folder (created in step 3.1) and will remain valid for 90 days. If you provide an email address to Let’s Encrypt when you create the certicates, they will automatically send you expire notices when your certificate is coming up for renewal.
Now we just need to upload the certificate and the key to GitLab. Go to Settings -> Pages inside your project, remove the old domain you have created in step 2 and add a new one with the same domain, but now you’ll also include content from your certificate.
Paste the content of
./cert/live/YOURDOMAIN.org/fullchain.pem (you’ll need sudo to read the file) to the “Certificate (PEM)” field and
./cert/live/YOURDOMAIN.org/privkey.pem (also needs sudo) to the “Key (PEM)” field.
Repeat this step to include www sub-domain in Gitlab (using same generated certificates).
Congratulations on completing the necessary steps. If you have any questions I will gladly answer them in the comments.