Jekyll Hosting with KeyCDN

jekyll hosting

Jekyll is a popular open source static site generator that is also blog-aware. It allows you to render a completely static version of a site without any databases of server-side code. This, in turn, provides much faster response times and lower overall page sizes.

However, even though a site is completely static that doesn’t mean it can’t be further optimized. As we’ve already shown with Hugo, in this article, we’ll walk through similar steps for how to host a Jekyll static site using KeyCDN.

Apart from using Jekyll, this tutorial also uses a GitLab repository with the built-in CI for options 1 and 3 while a Bitbucket integration is outlined for options 2 and 4.

To install Jekyll refer to their documentation. The following commands show how to setup and build a basic Jekyll site.

jekyll new example-site
cd example-site
git init
echo "_site/\npublic/" > .gitignore
echo "exclude: [ bitbucket-pipelines.yml ]" >> _config.yml

git add .
git commit -am init

jekyll build

Once complete, you can test your page locally with:

bundle exec jekyll serve

Option 1: Host Your Static Site as a Gitlab Page Behind a KeyCDN Pull Zone

If you would rather pull your files from an existing origin server and have your files update immediately upon purging, running a pull zone in front of a GitLab page might be the solution for you.

Your Jekyll site will be running on GitLab with a URL of https://youruser.gitlab.io/reponame/. Set up a pull zone to point to this location.

Use the template below for your .gitlab-ci.yml file.

image: alpine:latest

variables:
    KEYCDN_ZONE_ID: "99531"

before_script:
    - apk update

pages:
    stage: deploy
    script:
    - apk add ruby ruby-dev ruby-rdoc ruby-irb make gcc g++ libc-dev curl
    - gem install bundler jekyll
    - jekyll build -d public
    - curl "https://api.keycdn.com/zones/purge/${KEYCDN_ZONE_ID}.json" -u "${KEYCDN_API_KEY}:"
    artifacts:
        paths:
            - public
    only:
    - master

Instead of your KeyCDN user name and SSH key pair (as you’ll need in option 3), you will need to define the Zone ID and your KeyCDN API key as a secret variable. You’ll require the Zone ID and API key to purge your zone – it’s not strictly needed but otherwise, the CDN might deliver older versions of your assets for some time.

Push your changes to GitLab:

git remote add origin git@gitlab.com:youruser/ciexample.git
git push -u origin master

After verifying your CI job ran without issues, check that your GitLab page shows up via https://youruser.gitlab.io/reponame/ (it might look broken if Jenkins uses any absolute links as GitHub uses a subdirectory to serve these files – don’t worry about that) and then by heading to whatever Zonealias / Zone URL you defined.

Option 2: Using a Pull Zone with Bitbucket

Bitbucket works slightly different from Gitlab in that you need to create a repository with a certain name and then commit your HTML files to that repository. In this example, we use one repository to hold the Jekyll code, configuration, and CI pipeline as shown in the previous example and one to hold the result of that CI pipeline as HTML.

The first step is to setup the repository holding the code as described in the example for the push zone in Option 4. We divert from that with setting different environment variables just like we used in the GitLab with pull zone example as shown above.

bitbucket keycdn api

The name of the new repository that will hold your actual page needs to follow a certain schema. It is named either after your user or after your team in the format <name>.bitbucket.io. In the case of this example, it will be keycdn-demo.bitbucket.io:

bitbucket new repo

To allow the CI pipeline of our code repository to push to this, we have to add the public SSH key of our code repository to the account access list of an account having access to the repository. This is necessary because the per-repository SSH keys are read-only and would not allow us to push the generated HTML. Keep in mind that this gives the CI pipeline access to all this account’s repositories – if more people have access to this repository, you might want to use a separate account for holding it.

Put the following in your bitbucket-pipelines.yml – modify the URL to your pages repository accordingly.

image: alpine:latest

pipelines:
    branches:
    master:
        - step:
        script:
            - apk update
            - apk add ruby ruby-dev ruby-rdoc ruby-irb make gcc g++ libc-dev curl git rsync openssh
            - gem install bundler jekyll
            - jekyll build
            - git clone git@bitbucket.org:keycdn-demo/keycdn-demo.bitbucket.io.git /tmp/page
            - rsync -rvt --cvs-exclude --delete _site/ /tmp/page/
            - git config --global user.name "Jekyll CI" && git config --global user.email "jekyll@example.com"
            - cd /tmp/page && git add . && git status && git commit -am "CI Jekyll run" && git push -u origin master
            - curl "https://api.keycdn.com/zones/purge/${KEYCDN_ZONE_ID}.json" -u "${KEYCDN_API_KEY}:"

You can then head to Pipelines and check on your CI job:

bitbucket ci jobs

After verifying your CI job ran without issues, check that your Bitbucket page shows up via https://<name>.bitbucket.io and then by accessing whatever Zonealias / Zone URL you defined.

Option 3: Using a Push Zone with GitLab

If you want to host your Jekyll site entirely on KeyCDN’s storage cluster through Gitlab, your first step will be to create a push zone. Make sure to enable Directory Index in the advanced settings of your zone.

directory index enabled

You’ll likely want to use your own Zonealias for your website instead of the generic Zone URL (e.g. cipush-7bb7.kxcdn.com) we use in this example. Define this alias now and substitute it below for the Zone URL.

Create a .gitlab-ci.yml file describing the automated build jobs that will happen every time changes are committed to the repository. Make sure to set your username accordingly.

image: alpine:latest

variables:
    KEYCDN_USER: "youruser"
    KEYCDN_ZONE_NAME: "cipush"

before_script:
    - apk update

jekyll:
    stage: build
    script:
    - apk add ruby ruby-dev ruby-rdoc ruby-irb make gcc g++ libc-dev
    - gem install bundler jekyll
    - jekyll build
    artifacts:
    paths:
        - _site

push_keycdn:
    stage: deploy
    script:
    - apk add openssh rsync
    - mkdir -p ~/.ssh
    - echo 'rsync.keycdn.com,185.172.149.122 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFM7Jqs3BqC+MSEoVsZ+YMKTjVIMTSKlZX2+0t88o4LZvd+BWt71SkXv4mQr7xKD59m7jeJcWiO43u7YQzi+Tgg=' >> ~/.ssh/known_hosts
    - echo "${SSH_DEPLOY_KEY}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
    - rsync -rtvz --chmod=D2755,F644 --delete _site/ ${KEYCDN_USER}@rsync.keycdn.com:${KEYCDN_ZONE_NAME}/
    only:
    - master

Create a GitLab repository for your website as well as an SSH key pair that will be used to push the generated data to a KeyCDN push zone.

For sensitive information like the SSH key, we use a secret variable to store the Private key with our GitLab project. Secret variables can be defined under Settings -> Pipelines -> Secret variables.

gitlab secret variables

The public key will be stored in the KeyCDN dashboard under Account Settings -> Authentication -> Rsync over SSH Authentication.

public key rsync

Finally, it’s time to push the newly created repository to GitLab:

git remote add origin git@gitlab.com:youruser/ciexample.git
git push -u origin master

You can watch the progress and CI job output in your Gitlab project under “Pipelines”:

gitlab pipelines jekyll

You can now head over to your Zonealias URL (e.g. www.yourwebsite.com) for your brand new Jekyll website that’s fully hosted on KeyCDN.

Option 4: Using a Push Zone with Bitbucket

Bitbucket Pipelines are included in all Bitbucket plans (to some extent). To configuring your Jekyll site to be delivered via a KeyCDN push zone with Bitbucket you’ll first need to configure your SSH key (public and private) under projects settings -> ssh keys -> add private & public keys

public and private keys

Also, add rsync.keycdn.com as a known host:

known host

In Bitbucket, variables are set under projects settings -> environment variables. We use the following in our CI pipeline:

bitbucket environment variables

With all of the prerequisites now in place, we can create our bitbucket-pipelines.yml file to define our CI job. With Bitbucket, this can be done through the Web UI when enabling Pipelines for your repository. Replace the example template with the following:

image: alpine:latest

pipelines:
    branches:
    master:
        - step:
        script:
            - apk update
            - apk add openssh rsync ruby ruby-dev ruby-rdoc ruby-irb make gcc g++ libc-dev
            - gem install bundler jekyll
            - jekyll build
            - rsync -rtvz --chmod=D2755,F644 --delete _site/ ${KEYCDN_USER}@rsync.keycdn.com:${KEYCDN_ZONE_NAME}/

Your CI job will run after you saved this and you can watch its progress.

Summary

The popularity of static websites is growing. Therefore, knowing where and how to host these static websites for the best results is an interesting topic. The Jekyll hosting methods outlined in this guide are straightforward and will not only provide you with a place to host your static files but will give you access to our growing network of global POPs. This means your assets will be cached closer to your visitors, you’ll have better redundancy in place, you’ll be able to handle traffic spikes with ease, and more. To learn about all the benefits a CDN can provide your website, check out our 10 data-driven reasons article for why you need a CDN.