Setting up encrypted custom domain (apex and www) on GitHub pages
GitHub Pages is a simple, free way to host a static website, either plain HTML, or generated by a static site generator such as Jekyll.
GitHub Pages allows you to use a custom domain, such as example.com
or www.example.com
, or both.
In this post we will see how to set up a custom domain with HTTPS, so that:
http://example.com/a/b/c
redirects tohttps://www.example.com/a/b/c
https://example.com/a/b/c
redirects tohttps://www.example.com/a/b/c
http://www.example.com/a/b/c
redirects tohttps://www.example.com/a/b/c
Prerequisites
This post assumes you have a GitHub account and know how to create repos in GitHub.
Terminology
In this post we’ll use the term “apex” domain to refer to the domain in the format example.com
without the www.
. This is also sometimes referred to as the base or bare or root domain.
Subdomains are in the format something.example.com
, and www.example.com
is technically just another subdomain; although by convention it is special: generally we’ll expect websites to be be available on the the apex and www domains, and one of them to redirect to the other.
tldr;
The trick to get a certificate that covers both the www and the apex domain with GitHub Pages is to make sure the certificate is generated after both the apex and www domains correctly point to your GitHub Pages site. (If, for example, you start by getting the www domain to work with https, then you set up your A record on the apex domain, then the certificate will have been generated before the apex domain was set up, so the apex domain will not be covered by the certificate.)
If you set up the apex or www domain to point to your site after a certificate has already been generated by GitHub Pages, go to “Troubleshooting: forcing the certificate to be regenerated”, below.
Every GitHub Pages site contains a CNAME file at the same level as the root of the website (which can be the root of your GitHub repo, or the ./docs subfolder). You can either edit this CNAME file directly, or in the “Custom domain” field of the Pages section of your repo’s Settings. Both ways of editing the CNAME file will have the same effect.
The contents of your CNAME file (which is also the value of the “Custom domain” field of the Pages section of your repo’s Settings) will determine your website’s canonical domain.
- If the ./CNAME, or ./docs/CNAME file, contains www.example.com, then GitHub will attempt to redirect example.com to www.example.com.
- If the ./CNAME, or ./docs/CNAME file, contains example.com, then GitHub will attempt to redirect www.example.com to example.com.
In this post, we will assume that we want our canonical domain to be “www.example.com”, and “example.com” to redirect to it.
Step one: create a GitHub repo
I like to host my website pages in a subdirectory called ./docs
in a GitHub repo, so that anything outside the ./docs
repo (such as meta-data for the site, or development scripts) is not published; and anything inside the ./docs
is published to the web.
I also like using the “master” branch, although GitHub Pages also allows you to publish your website on other branches such as gh-pages
.
The simplest possible GitHub repo for a website is therefore a single index.html
file in a ./docs
directory, in the master
branch.
We will assume that your GitHub username (or, if you are using an orgninization, your GitHub organization name) is MY_USERNAME_OR_ORGANIZATION
and that your repo name is MY_REPO_NAME
.
Step two: activate GitHub Pages
Go to the Pages section of your repo Settings at https://github.com/MY_USERNAME_OR_ORGANIZATION/MY_REPO_NAME/settings/pages.
- Activate GitHub Pages
- Select “Deploy from a branch”
- Choose the “master” branch (or whatever branch you want to use)
- Choose the “/docs” directory (or “/ (root)” is case you prefer to use the root directory of your repo to host your website).
I like to set the custom domain in a future step by editing the CNAME file directly, but you can also enter your canonical domain in the “Custom domain” field here.
Step three: create a CNAME file
Let’s assume you want to use the domain www.example.com
as a canonical domain for your website, with example.com
directing to it.
Create a file called ./docs/CNAME
with the following content:
www.example.com
Step four: create a CNAME record
The way to do this depends on your registrar or DNS provider.
One of the pitfalls of CNAME records is that they must end with a dot, but certain DNS providers automatically add a dot without telling you, and others do not.
The CNAME record you’ll want for www.example.com
is
MY_USERNAME_OR_ORGANIZATION.github.io.
If that does not validate, it is possible that your DNS provider automatically adds a dot, in which case you’ll want to use
MY_USERNAME_OR_ORGANIZATION.github.io
Step five: create an A record for the apex domain
Apex domains cannot have CNAME records, so we need to use one or more A records.
Most DNS providers allow you to set up a “redirect” from the apex domain to the www
domain; however this will generally not set up HTTPS encryption, so that if someone visits “https://example.com”, they will see a warning in their browser, which is not what we want.
Here we will show how to create an A record; if you want to use an ALIAS, ANAME, or AAAA record please refer to the page “Configuring an apex domain” section of the page “Managing a custom domain for your GitHub Pages site”, on GitHub, on Nov. 15, 2023.
Go to your DNS provider and create an A record or IPv4 redirect for the apex domain, in our case example.com
, with the following values, which correspond to the IP addresses of GitHub’s servers:
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
This sometimes requires adding four separate A records, or sometimes you can add a single A record with multiple values.
Step six: make sure the certificate generated by GitHub covers both your apex and www domains
Wait between one and fifteen minutes for everything to settle in, then make sure the certificates are valid:
curl -I https://terredesjeunes.org
curl -I https://www.terredesjeunes.org
In both cases, you should not be seeing a “curl failed to verify the legitimacy of the server” error.
Step seven: force HTTPS
Go to the Pages section of your repo Settings at https://github.com/MY_USERNAME_OR_ORGANIZATION/MY_REPO_NAME/settings/pages.
- Select “Enforce HTTPS”
Step eight: test your setup
After waiting a minute or two, you should be able to test the following:
http://example.com/a/b/c
redirects tohttps://www.example.com/a/b/c
https://example.com/a/b/c
redirects tohttps://www.example.com/a/b/c
http://www.example.com/a/b/c
redirects tohttps://www.example.com/a/b/c
Troubleshooting: forcing the certificate to be regenerated
In https://github.com/MY_USERNAME_OR_ORGANIZATION/MY_REPO_NAME/settings/pages, if you had a domain such as www.example.com before you set up the apex domain A records, or if you had a domain such as example.com before you set up the www domain CNAME record, you might have to force the certificate to be regenerated.
Here is a quick way to to do this:
- If your “Custom domain” field contains “www.example.com”, then change it to “example.com”, wait a few minutes, and change it back to “www.example.com”, then wait 15 minutes.
- If your “Custom domain” field contains “example.com”, then change it to “www.example.com”, wait a few minutes, and change it back to “example.com”, then wait 15 minutes.
In the former case your canonical domain will be “www.example.com”, with “example.com” redirecting to it.
In the latter case your canonical domain will be “example.com”, with “www.example.com” redirecting to it.