Introduction

What is GitHub Pages

GitHub Pages hosts static websites. It could be about yourself, a project, or a business. GitHub Pages prohibits use for running an online business, e-commerce site or anything primarily directed as commercial transactions or Software as a Service. For more information on GitHub Pages, see GitHub Pages documentation.

This website is hosted using GitHub Pages.

What is Jekyll

Jekyll is a framework, written in Ruby, to create static websites and blogs from plain text documents. GitHub Pages can use Jekyll. Jekyll plugins provide a mechanism to extend Jekyll functionality. GitHub Pages makes a limited number of Jekyll plugins available. See the GitHub Pages depencency versions page for available Jekyll plugins. For more details on Jekyll, see the Jekyll documentation.

This website is built using Jekyll.

What is Docker

Docker allows developers to build and test applications. In Docker, an image of everything required to run an application is packaged and used to create a standard container that runs in a virtual machine. For more information on Docker, see the Docker documentation.

The jsware/github-pages Docker image contains the correct versions of Ruby, Jekyll and plugins allowed by GitHub Pages.

This website is tested using Docker and the jsware/github-pages image.

Local Development Environment

Every time you push your website modifications to GitHub, GitHub Pages will publish those changes. If you are not able to test your changes before publishing them, you could easily break the site. This becomes more important as your site grows.

GitHub Pages in Docker

This Docker image came about because I was not able to setup Ruby, Jekyll and plugins allowed by GitHub Pages. My MacBook Pro (Mid 2015) only runs macOS Monterey 12.7.6 (the latest). A common way of running Jekyll locally uses Homebrew package manager software. Unfortunately as of October 2024, Homebrew stopped supporting macOS Monterey 12.

So this Docker image was born.

Prerequisites

Before using this image, you will need the following installed:

Usage

Once the above are installed and working, use the folowing command to start your GitHub Pages website (Replace THINGS-LIKE-THIS with your own values):

cd YOUR-WEBSITE-DIRECTORY

docker run --rm --interactive --tty --volume .:/home --pubish 4000:4000 jsware/github-pages

The command options are explained:

docker run \            # Create and start a container.
  --rm \                # When the container stops, remove it to keep tidy.
  --interactive \       # Interactive mode shows the Jekyll build output.
  --tty \               # Connect the keyboard to the running container.
  --volume .:/home \    # Map the current directory . to /home in the container.
  --pubish 4000:4000 \  # Map port 4000 in the container to port 4000 on your local workstation.
  jsware/github-pages   # The name of the Docker image to use.

The above command uses verbose arguments. Shorter ones are available:

docker run --rm -it -v .:/home -p 4000:4000 jsware/github-pages

You might decide to create a short shell script such as follows so you can run that quickly and easily:

# Do this once...
echo "docker run --rm -it -v .:/home -p 4000:4000 jsware/github-pages" >serve.sh
chmod +x serve.sh

# Then run serve.sh whenever you want to start your website locally.
./serve.sh

If you store your Jekyll site in a docs subdirectory of your GitHub project, you can modify the docker run command:

docker run --rm -it -v ./docs:/home -p 4000:4000 jsware/github-pages

NB: You might get the following message because the container cannot find the .git repository information directory:

fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

This is because only the docs subdirectory has been mounted within the container. I will change how the volume is mounted in the future to avoid the message if it becomes a problem.

GitHub Repository Information

If your site includes GitHub information such as site.github then an environment variable called JEKYLL_GITHUB_TOKEN needs to be set to your GitHub access token:

Don’t store it in your repository for everyone to see!

I recommend setting an environment variable JEKYLL_GITHUB_TOKEN with your access token text and then refer to it in configuration or when running commands:

docker run --rm -it -v .:/home -p 4000:4000 -e JEKYLL_GITHUB_TOKEN=$JEKYLL_GITHUB_TOKEN jsware/github-pages

Docker Compose

If you wish, you could create a docker-compose.yaml file so the GitHub Pages application can be started using:

docker compose up

an example docker compose file is:

services:
  github-pages:
    image: jsware/github-pages
    container_name: GitHub-Pages
    environment:
      JEKYLL_GITHUB_TOKEN: $JEKYLL_GITHUB_TOKEN
    ports:
      - "4000:4000"
    volumes:
      - ./docs:/home
    tty: true

NB: In the above example, the docker-compose.yaml file lives in a GitHub parent directy with the website files stored in a docs subdirectory. Hence the volume is./docs:/home.