GitHub Codespaces offers a completely browser-based IDE experience. Based on Visual Studio Code, the IDE provides you with a full-fledged editor, a virtual machine to run your code on, and even tunneled network connections so you can test directly in your browser. Firing up a Codespaces session is as simple as clicking on the “New codespace” button from the “Code” dropdown in your repo.
Out of the box, launching a Codespaces environment will give you a little 4 core machine with 8GB of RAM and 32GB of storage. More than enough for doing basic web development. However, the image that its running won’t have all of the software we need in order to develop for our Jekyll site. Rather than installing the software each time we fire up a new Codespace, wouldn’t it be great if we could define it all in a Docerkfile and have GitHub use THAT when launching a site? That’s exactly what we’re going to do in this tutorial.
Let’s get this party started. 🥳
Step 0
Fire up a Codespace in your repo.
Setup Dev Container
A great feature of Codespaces is the “dev containers” functionality.
When launching a Codespace, GitHub checks the root of your repo for a .devcontainer
directory. If present, it will use information stored there for the initial build out of our virtual machine image.
Microsoft has an entire repo dedicated to pre-build .devcontainer
configurations, based on your project type. Lucky for us, there is one
that already exists for Jekyll.
Inside of your Codespace terminal, clone the dev-container repo:
@zimventures ➜ /workspaces/TIL (main ✗) $ git clone https://github.com/microsoft/vscode-dev-containers
Move the .devcontainer
directory for the Jekyll project type into the root of your repo.
In this example, I’m already in the repo root so I’ll just move it to ./
@zimventures ➜ /workspaces/TIL (main ✗) $ mv vscode-dev-containers/containers/jekyll/.devcontainer/ ./
Taking a peek at the contents of the .devcontainer/base.Dockerfile
there is one entry of particular interest to us:
# Install bundler, latest jekyll, and github-pages for older jekyll
RUN gem install bundler jekyll github-pages
Fantastic! When the Codespace is fired up, we’ll already have some basics up and running.
Additionally, in the .devcontainer/post-create.sh
script, there is this little bit of logic:
# If there's a Gemfile, then run `bundle install`
# It's assumed that the Gemfile will install Jekyll too
if [ -f Gemfile ]; then
bundle install
fi
It sure would be nice if our gems were automatically installed for us. Let’s get to setting up our Gemfile
.
Gemfile setup
Create a new file called Gemfile
in the base of your repository.
@zimventures ➜ /workspaces/TIL (main ✗) $ touch Gemfile
Now let’s go ahead and add our required gems to the file, pinning versions that match what are currently supported on GitHub Pages. See the official dependency versions page for the most up to date pins. What gems do we need for development within our Codespace?
jekyll
jekyll-theme-midnight
(replace this with whatever theme you’re going to work with)kramdown-parser-gfm
(not installed by default, and needed by jekyll)
We’ll surely add more gems later, but that’s enough to get us started.
Here’s what the final version of our Gemfile
will look like:
source "https://rubygems.org"
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
gem "jekyll", "~> 3.9.0"
gem "jekyll-theme-hacker", "~> 0.2.0"
gem "kramdown-parser-gfm", "~> 1.1.0"
Placeholder Page
Before we check in all our files, let’s drop a placeholder landing page at the root of the repo. In Jekyll, pages can be written in Markdown and/or HTML.
We’ll create a new file, index.md
(in the root of the repo) and populate it with the following:
---
title: Home
layout: default
---
# Welcome to Today, I Learned
TODO: Write this! 😅
.gitignore
Before checking in our new files, let’s take a moment to create a .gitignore
file in the root of the repo. This file tells git to ignore any files or directories that match the specified entries. Jekyll automatically
creates directories and files during the process of building our site. We do not want those files to show up as potential candidates for a commit.
Here, we’ll ignore a couple of Jekyll generated directories as well as the gem lockfile (we’ll undo the lockfile later…).
_site/
.sass-cache
Gemfile.lock
Commit, clean, and restart
With all of our base files in place, we’ll go ahead and commit our changes, pushing them to main
.
Since our current Codespace was created prior to our code being merged to main
, we’ll need to destroy it and create a new one.
Simply close the Codespaces window, navigate back to your repo, and click the “manage” button in the list of code spaces.
In the list of Codespaces that’s shown, we’ll click on the menu button “…” and click “Delete”.
Disposable development environments…what a time to be alive. 😅
Restart
After the previous Codespace has been deleted, it’s time to fire up a new one. Follow the instructions as before to start one. You’ll note that this time will take a few minutes longer. GitHub is
building the Dockerfile
that was specified by your .devcontainer
and running the post build steps (installing our gems). Don’t worry though - this build process only happens on the initial spin up of the Codespace.
Going “live” (on our dev server)
Now it’s the moment of truth. Let’s see if we can serve the page from the newly spun up Codespace.
@zimventures ➜ /workspaces/TIL (main ✗) $ bundle exec jekyll serve
Configuration file: /workspaces/TIL/_config.yml
Source: /workspaces/TIL
Destination: /workspaces/TIL/_site
Incremental build: disabled. Enable with --incremental
Generating...
done in 0.506 seconds.
/usr/local/bundle/gems/pathutil-0.16.2/lib/pathutil.rb:502: warning: Using the last argument as keyword parameters is deprecated
Auto-regeneration: enabled for '/workspaces/TIL'
Server address: http://127.0.0.1:4000
Server running... press ctrl-c to stop.
Cracking open our browser and pointing it to http://127.0.0.1:4000
we are presented with:
GREAT SUCCESS!
The page looks the same as it does when browsing the the URL that GitHub Pages gave us for the TIL site. We didn’t cover enabling GitHub pages in this tutorial but if you’ve already done so, your page should be live at the auto-generated URL for your site.
Happy Coding 💻
Next up: Theme Customization