This post describes a recipe for setting up a static website for free with these features:

Setup

  1. Install Jekyll
  2. Fork GitLab’s template Jekyll repository, or create your own locally
  3. Point DNS records to GitLab

Your site should be accessible through your custom domain using plain HTTP at this point.

HTTPS setup

To make this part easier, I’ve written a command-line tool named gitlab-le which handles obtaining and renewing HTTPS certificates from Let’s Encrypt.

Install gitlab-le with npm install --global gitlab-letsencrypt (requires Node.js 8 or greater).

Test everything works OK with the following command. See instructions for getting a GitLab access token.

gitlab-le \
  --email YOUR_EMAIL@example.com \
  --domains EXAMPLE.com www.EXAMPLE.com \
  --token YOUR_PERSONAL_GITLAB_ACCESS_TOKEN \
  --repository https://YOUR_REPOSITORY_URL \
  --jekyll \
  --path /

If everything worked, re-run the same command with an additional --production option.

At this point, your website should be accessible via HTTPS. Yay! However, the certificate we’ve obtained will only last for 90 days, so we need some way of renewing it.

Renewing HTTPS certificate

To renew your HTTPS certificate, run gitlab-le again with the same options, including the --production option. Automating this to run every 90 days is left as an exercise for the reader.

Tip: You can run gitlab-le run without the --production option as often as you want without fear of being rate-limited by Let’s Encrypt. This allows you to detect and fix issues with your repository before the certificate expiration date.

If you don’t want to or can’t set this up to run automatically, Let’s Encrypt will send notices when your certificate is about to expire to the --email used when first obtaining the certificate.

Forcing HTTPS

Currently it is not possible to automatically redirect all visitors to the HTTPS version of your website. There is an open issue on the GitLab CE repository to track this feature.

As a temporary workaround, you can redirect using JavaScript on your website:

if (location.protocol !== "https:") location.protocol = "https:";

Alternatives

GitHub Pages offer these same features but SSL on custom domains is provided with CloudFlare’s Universal SSL, which is not true end-to-end encryption.

Netlify’s free plan offers these same features with a friendly UI, but it is a closed-source service.