XF

[Tutorial] Create a Static Website Using Jekyll + GitHub Pages - [for Beginners, Windows 10 and WSL 2]

Static Website & Dynamic Website

A static website contains web pages with fixed, unchanging content. The information displayed is the same for all users, and can only be modified by the site’s owner or maintainer, not visitors. In contrast, a dynamic website serves web pages generated in real-time when a user makes a request. The server may retrieve data from a backend database to populate the page on-the-fly. Popular examples like Facebook and Taobao are dynamic sites. Their content is tailored for each user based on factors like login status. In this tutorial, we will build a static website using Jekyll and host it on GitHub Pages.

Prerequisites

First, this tutorial assumes you have internet access. If you are in mainland China, your ISP may be blocking certain sites like raw.githubusercontent.com, which you’ll need to access. You may have to work around these restrictions yourself to avoid errors like TLS handshake failures when installing software mentioned here.

It’s also assumed you are running Windows 10 version 1903 (build 18362) or later with WSL 2 installed already. If not, refer to this Microsoft documentation on getting WSL set up. We’ll be using the default Ubuntu 20.04 LTS Linux distribution in WSL for the steps here.

For your terminal, Windows Terminal is highly recommended over the default Command Prompt or PowerShell. It offers useful features for WSL and CLI work. Read more about it in the Windows Terminal documentation.

Additionally, having Visual Studio Code installed on Windows is optional but suggested. Specifically, you’ll want the Remote Development extension pack to connect VS Code from Windows Host to WSL.

To verify your setup allows developing in WSL with VS Code, first open a WSL Ubuntu shell. Then type the following:

code .

This will launch a VS Code window connected directly to your Linux filesystem. You can create and edit files here (note the bottom left corner):

VS Code

Should there be any problems, refer to the VS Code remote development documentation.

Before we proceed, make sure you have some basic tools and dependencies installed in your WSL environment, including git and gcc.

sudo apt install git 
sudo apt install build-essential

In the upcoming steps, we will build a Jekyll website in WSL and publish it to GitHub Pages.

To deploy to GitHub Pages, you’ll need a GitHub account with SSH key authentication set up. If you haven’t configured SSH keys yet, refer to GitHub’s documentation on connecting with SSH.

To verify your SSH connection is working, go back to your WSL terminal and enter:

This will attempt to ssh to GitHub using your key and print a welcome message if successful.

Auth GitHub

Install Dependencies

Ruby

Jekyll requires a Ruby environment, which we can set up in WSL. While Ubuntu has a system Ruby, it’s recommended to install a more recent Ruby version with rbenv instead. rbenv allows installing Ruby into your ${HOME} directory without needing root permissions. This gives more control over Ruby versions and installing gems via gem install.

To install rbenv, I recommend rbenv-installer. Try ONE of the following commands:

# with curl 
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash 
# alternatively, with wget 
wget -q https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer -O- | bash

After installing rbenv, you may need to add its executable path to your shell’s PATH variable. First, check your current shell by running:

echo $SHELL

On WSL Ubuntu 20.04, the default shell is typically bash. If using bash, run these commands to add the PATH lines to your .bashrc file. For zsh or other shells, add those lines to the appropriate dotfile like .zshrc instead. This will ensure rbenv is initialized and accessible from your shell whenever you start a new session. The eval command sets up auto-completion as well.

# If you are using bash:
echo 'export PATH=${HOME}/.rbenv/bin:${PATH}' >> .bashrc 
echo 'eval "$(rbenv init - --no-rehash)"' >> .bashrc

# If you are using zsh:
echo 'export PATH=${HOME}/.rbenv/bin:${PATH}' >> .zshrc 
echo 'eval "$(rbenv init - --no-rehash)"' >> .zshrc

Reload your shell’s configuration (source ~/.bashrc or source ~/.zshrc). Then run the following command to list which Ruby versions are available to install:

rbenv install --list

The output should look like:

ruby-install-list

Before installing Ruby with rbenv, we need to ensure the required dependencies are available in WSL. Run these commands to install the necessary packages:

sudo apt-get install -y libssl-dev zlib1g-dev

Now we’re going to install Ruby. We can install Ruby 3.0.0 by

rbenv install 3.0.0

Note: in case of failure, you may follow the instructions prompted to install additional dependencies and retry installing Ruby.

ruby-install

Finally type

rbenv versions

You should get list of ruby versions installed and managed by rbenv in this machine (i.e., WSL Ubuntu).

rbenv-version-list

Now type

cd ~
rbenv local 3.0.0

This command will create a .ruby-version file in current directory, setting the ruby version that will be used in this directory (and its subdirectories) to 3.0.0. For more details, see the rbenv documentation rbenv - How It Works.

Jekyll Quickstart

In this section, we will be following the Jekyll Quickstart Tutorial to create our first website locally.

Install Jekyll and bundler

gem install jekyll bundler

Create a new Jekyll site in ~/myblog

Of course, you have the flexibility to choose both the name and location of the directory yourself. For the purpose of this tutorial, we’ll simply create the directory in your WSL ${HOME} directory, which is represented by ~.

cd ~
jekyll new myblog

cd myblog

Build the site and make it available on a local server

Note: Since we are using the latest versions of Ruby (as of Mid-Jan-2021, Ruby 3.0.0) and Jekyll (4.2.0), it’s possible that the building process may encounter an issue with Jekyll complaining about cannot load such file -- webrick (LoadError)(ref: issue #8523). You can address this problem by manually installing the webrick gem:

echo 'gem "webrick"' >> Gemfile 
bundle install 

Proceed to build and serve the site on localhost:

bundle exec jekyll serve

The default port is 4000. Open a web browser, enter localhost:4000 in the address bar, and check if the site is live:

preview-site-1

Try some editing

To edit the site’s content, open a new WSL tab, navigate to the site’s directory, and open VS Code there:

cd ~/myblog
code .

You may see a file structure that looks like

jekyll-file-structure

Now, edit the _config.yml file. This file serves as the global configuration for the site, including variables like site name, author, and description. Update the site title and save the file:

edit-config-yml

As of Mid-Jan-2021, the current version of WSL has limitations on filesystem watchers. Consequently, Jekyll may not recognize changes to files, and won’t automatically rebuild the site when files like posts are modified. In addition, Jekyll won’t auto-rebuild in response to changes in the global config file _config.yml, even without the WSL filesystem watcher issue.

To stop Jekyll and restart, press Ctrl + C and then re-run the command.

bundle exec jekyll serve

jekyll-serve

Refresh the browser or revisit localhost:4000. If everything works as expected, you’ll see the updated site title:

preview-site-2

Posts are located in the _posts directory. You can edit the default Welcome to Jekyll! post or create your own post following the naming convention: yyyy-mm-dd-your-post-title.md (For details about post format, see Jekyll official doc). After making changes, repeat the process to stop and re-run Jekyll. Your new post should then appear in the browser:

preview-site-3

Congratulations! You’ve successfully built a static website on your computer. In the following sections, we’ll cover how to publish this site online.

Publish the Jekyll Site to GitHub Pages

Create a GitHub Repository to Host Your Site

A common practice, especially for personal homepages, is to create a GitHub repository named <your_github_username>.github.io. GitHub will automatically publish the site within this repository for you. However, if you prefer a different name or already have a repository with that name, using a repository with an arbitrary name is also acceptable. For example, if you’re running a department homepage, the URL could be <your_dept_github_username>.github.io, and research projects or groups can have their own child pages in their respective repositories, like group1. Group 1’s page could be published at <your_dept_github_username>.github.io/group1.

In this tutorial, we’ll use a different repository name, such as jekyll-tut (indicating Jekyll tutorial).

Note: if you (1) are using a repository name other than the default <your_github_username>.github.io, and (2) created the Jekyll site following the steps in this tutorial by executing jekyll new <my_site_name>, before you continue, you must edit _config.yml and change the baseurl to /<the_repo_name>, for example,

edit-base-url

Create a new GitHub repository with the name <the_repo_name>:

gh-create-repo-1

gh-create-repo-2

Copy the repository address in the format [email protected]:<your_github_username>/<the_repo_name>.git.

gh-create-repo-3

Initialize Your Local Git Repository

If you haven’t set your Git username and email, you can do so by:

git config --global user.name <your_github_username>
git config --global user.email <your_github_email>

Note that setting your real username and email address is not compulsory for git operations, but it’s recommended for easier recognition by GitHub :P.

In the WSL shell, navigate to your site directory and initiate it as a git repository:

cd ~/myblog
git init

git-init

Add the GitHub repository address as a remote target:

git remote add origin [email protected]:<your_github_username>/<the_repo_name>.git

Note: origin is a common convention for the shorthand name that points to the remote repository, but you can replace it with any name you prefer.

Now, add and commit your files to Git:

git add -A
git commit -m 'init my jekyll site'

-m stands for commit message; you can write any message describing your achievement or changes made to the code.

Finally, push the files to GitHub:

git push origin master

Return to the GitHub repository page and refresh it. You will now see the files in the repo.

gh-repo

Now, navigate to the repository settings.

gh-repo-setting

In the ‘GitHub Pages’ section, set the source to master (or main) branch and the path to /(root) as shown below:

gh-pages-setting

You’re all set (you may need to wait a few seconds). Open a web browser and visit https://<your_github_username>.github.io/<the_repo_name>. Your site should now be live and accessible to the world!

preview-site-publish

Next Steps

You have just published a static site online. The next steps can be

  1. Enhancing the content by adding more posts (like a personal blog);
  2. Connect a custom domain to the site. Currently, the site address is https://xxx.github.io/xxx, you may purchase your own domain and make your site accessible via e.g., https://<yourname>.com;
  3. Personalize the Design by editing the site source codes, especially the css files.

For 1 and 3, you can carry out your editing work locally. Afterward, use command git add -A, then git commit -m 'some message' and finally push the changes to GitHub using git push origin master (or git push origin main, depending on the branch name you use). GitHub will automatically re-build the site and publish it for you.

Conclusion

In this tutorial, we’ve covered how to create a Jekyll site locally from scratch. However, many users may not need to start from scratch, especially if they’re not experienced web developers or designers. A much more common approach for typical users is to fork an existing Jekyll site template, make modifications, and then publish it. There’s a wealth of Jekyll site themes (templates) available for forking on the internet; you can simply choose one that suits your preferences.

Let’s use minimal theme as an example:

To fork the repository, clicking the “Fork” button:

gh-repo-fork

This operation “saves a copy” of the minimal Jekyll theme under your GitHub account, enabling you to make edits and modifications to it:

gh-repo-fork-2

From here, you can: