Github has worked great for me over the past many years, and I've been a paying customer for about 8 years. That's not likely to change but I took the recent acquisition by Microsoft as a prompt to explore other options as I saw many comments praising gitlab, and specifically their continuous integration options.
I found that really interesting as I had found the plugin restrictions in Github very limiting - I want to be able to run preprocesses on my files so I don't have to type or copy and paste so much.
This post explores how I migrated one of my sites there.
Outline of the process
Optionally: run your own runner to do the build (future post).
Option 1: Import using Gitlab's wizard. Very easy but you give access to all projects you have access to. Some client companies may not be fine with it. At the very least remember to disable access on Github settings when you're done with the import.
Option 2: If you just need the git history.
We will be creating a file called .gitlab-ci.yml
on the root folder.
pages
that generates an artifact that contains a
folder called public
, everything under that folder will be served as static
contentsimage: ruby:2.4.4
variables:
JEKYLL_ENV: production
before_script:
- bundle install
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
and here's the Gemfile
I was used for jekyll already:
source "https://rubygems.org"
ruby "2.4.4"
gem 'jekyll','3.6.2'
gem 'jekyll-paginate'
You should never lose the ability to build locally, so keep the pipeline script ultra simple.
It's important to match the ruby versions between Gemfile and pipeline, otherwise the runner would be launched with a different version.
Just by pushing the CI file it will create the pipeline and it will build every time there is a push to master.
After a first build passes you will be able to access the site. If you don't, check where you went wrong as all the rest is meaningless until you get to this stage.
Now you can rest, keep playing with your site and check that everything looks ok. Depending on how you implemented it, it may not be able to find CSS and images, but don't panic - just use view source to check the URLs will be ok when it's in its own domain (or fix your jekyll config so that it is)
A nice github feature is that you, simply by checking a box, get a valid SSL certificate (they do internally all the let's encrypt domain validation). On Gitlab pages this is a manual process. You'll find lots of guides for this, but here's what I did (word of advice: the best approach is probably to do first adding a domain without SSL and then adding SSL support, but I did all at the same time)
Install certbot:
apt install certbot
You can use yum, brew or whatever your poison is.
Decide of a home to store your certificates. I decided this certificate is pretty much irrelevant so put it inside the container itself:
export CERTDIR=~/onlydognews.com/certs
Generate a certificate request and send it to letsencrypt:
certbot certonly -d onlydognews.com --work-dir ${CERTDIR}/work/ --logs-dir ${CERTDIR}/logs/ --config-dir ${CERTDIR}/config/ --manual
Output:
...
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for onlydognews.com
...
Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: y
-------------------------------------------------------------------------------
Create a file containing just this data:
dasjlkdjasiojXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.dasdjskljxp-21rwefQQEWr8
And make it available on your web server at this URL:
http://onlydognews.com/.well-known/acme-challenge/jdaslkdjsaXXXXXXXXXXXXXXXXXXjklxjklxj
-------------------------------------------------------------------------------
Press Enter to Continue
This turned out to be a bit tricky since my domain was still pointing to the old Github project. So I cloned that repo and added a commit to publish that file, in order to verify my domain.
I added this to _config.yml
, the Jekyll configuration file:
include: [.well-known]
I created a new file under the path instructed by cerbot and pushed both changes upstream, which made the file available online. Then continued the certbot process.
Waiting for verification...
Cleaning up challenges
Non-standard path(s), might not work with crontab installed by your operating system package manager
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
.../_certs/config/live/onlydognews.com/fullchain.pem
Your key file has been saved at:
.../_certs/config/live/onlydognews.com/privkey.pem
Your cert will expire on 2018-09-02. 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"
There's an important bit there, we will have to remember to renew the certificate in three months. Certbot can automatically update some servers but not Gitlab as far as I'm aware.
'Live' folder
DOMAIN/privkey.pem
: the private key for your certificateDOMAIN/fullchain.pem
: the certificate file used in most server software.DOMAIN/chain.pem
: we don't need itDOMAIN/cert.pem
: we don't need it'Renewal' folder:
DOMAIN.conf
: File that certbot will use for renewal'Archive' folder: History of all the certificates generated. This will contain just the one just created.
'Renewal-hooks' folder: Empty folders for deploy, pre and post hooks.
'Keys' folder: Certificate private keys used. I have a few because I tried this process a few times.
'CSR' folder: Certificate requests used. Again, one for every try.
'Accounts' folder: Output of the registration process
meta.json
: creation date, host name that issued the requestprivate_key.json
: private key used during registrationregr.json
: data used during registration, contact details, terms and conditionsGo to your project/pages/domains/new
Check the enforce SSL option and add your domain name
In Certificate(PEM) add the fullchain.pem
text contents
In Key(PEM) add the privkey.pem
text contents
It will show:
This domain is not verified. You will need to verify ownership before access is enabled.
To do so, from your DNS provider create a new DNS record:
Important: the gitlab page displays the full Name (including the domain, as in
_gitlab-pages-verification-code.YOURDOMAIN.com
), but on the DNS settings you just add the host part
Now we can finally move our domain to the new one. In the settings page Gitlab will show a CNAME
entry that you should use. This is fine if your site is on a subdomain (for example www
), but if it's the root (as in gatillos.com
), you can't create a CNAME of it. This is a DNS restriction that some people are not aware of: the root domain is called APEX domain and is used by a number of things. If you create a CNAME of it you can lose control of MX and similar registers.
To find out the IP address you need, simply lookup the domain showed on the settings page:
dig +short YOURCNAME.gitlab.io
52.167.214.135
Which means we need to add an A record on your DNS, something like:
a @ 52.167.214.135 1 hour
Final result: