How to Start a Blog
There are many (maybe too many) options when it comes to technical solutions to build a website; if you want a free, simple way to put your blogs out for the world to see, GitHub Pages may be the way to go. I’m going to show you how to set up a blog in a few easy steps, with the express goal of getting your website up and running in an afternoon. To follow this guide, you should be somewhat familiar with Git, GitHub, and Docker.
When I decided I wanted to write this I was a bit overwhelmed with alternatives. I settled for GitHub Pages because at the time it appeared to require just a few steps to get it to work. By default, GitHub Pages uses Jekyll to generate a static site, but here I’ll show you how to build a site with Hugo. To make things easier (easy as in self-contained, organized, clean) we will be running Hugo inside a Docker container.
Create a Docker container
Assuming you have already installed Docker, go ahead and create a new directory; I’ll be naming it hugodocker
. Here we will add a Dockerfile
with the following content:
FROM klakegg/hugo:0.72.0-alpine
RUN apk add git
There is no official Hugo Docker image, but the good people at Hugo recommend you check out this repo by klakegg.
To build the Docker image, we will write a short bash
script. I like to call these scripts build.sh
; I also like to have all these docker
commands written down in scripts because that way I don’t have to remember them, and I can also use git
to manage any changes to them.
#!/bin/bash
docker build --tag hugodocker:0.1.0 .
Once you have built your Docker
image, you can run it interactively. Again, we will write a script that will take as an argument the path to your blog. Let’s call this script run.sh
.
#!/bin/bash
if [ -z "$1" ]
then
echo 'use: ./run.sh <PROJ-DIR>'
exit 1
fi
cd $1
docker run --rm -it \
-v $(pwd):/src \
-p 1313:1313 \
--dns 8.8.8.8 \
hugodocker:0.1.0 \
shell
The most important things here are the docker run
flags: -v
mounts your blog’s directory on the Docker container, -p
binds the container’s 1313 port to your host machine’s 1313 port, and (at least in my experience) --dns
is required to resolve a hostname such as github.com
from within the Docker container.
Make a new website with Hugo
Go ahead and create a new directory for your blog; mine will be called smallblog
. Run your Docker container with $ ./run.sh smallblog/
and once you’re in the container check that it has everything we need: type $ hugo version
and $ git version
. At the time of writing, I’m running Hugo 0.72.0 and Git 2.24.3.
Create a new site
Here I’ll be summarizing the instructions from Hugo’s Quick Start guide. First, you need to tell Hugo that you want to create a new site right where you are (inside your Docker container your current working directory should be /src
). Type $ hugo new site .
and don’t forget the .
(period). Now you have a config.toml
file and a bunch of directories.
Add a new theme
There are many Hugo themes available for free from https://themes.gohugo.io/. I use Radek Koziel’s hello-friend theme. Once you have chosen a theme, you’ll need to start a new Git repo in your current directory with $ git init
and then add the theme as a submodule with $ git submodule add https://github.com/panr/hugo-theme-hello-friend themes/hello-friend
.
To use the theme edit add a line with theme = "hello-friend"
at the end of your config.toml
file.
Run the Hugo server
Hugo comes with a web server so you can run your website locally before deploying it to GitHub Pages. To run it, simply type hugo server
and open http://localhost:1313/
in your web browser. Before we add any content to your website, you should know that new posts are labeled as “drafts”, so if you want to preview them locally you must tell Hugo to include drafts by including the -D
flag: $ hugo server -D
. For more on the hugo server
command, check the official documentation.
Add a new post
To create a new post just tell Hugo to $ hugo new posts/my-first-post.md
. This will create a new Markdown file inside content/posts
. See how the file is currently labeled as a draft (don’t forget about this little detail as it is very important). If we run the server again but include draft posts, you’ll see it on your website!
Deploy to GitHub Pages
Now we’re almost set to deploy your newly created site to GitHub Pages. We’re gonna try to get it to work, and see why it’s still not quite ready. The GitHub Pages website shows how to create a new site. Here I’m assuming we’re creating a Project site which we’ll call smallblog.
Go to github.com and create a new repository, name it smallblog
, and don’t worry about it being public or private (it doesn’t matter). Go back to your Docker container and a new Git remote: $ git remote add origin git@github.com:MooreMachine/smallblog.git
. Push your changes with $ git push -u origin master
.
Navigate to your GitHub repository’s settings and to the GitHub Pages section. Under Source choose master branch
. Then go to your site’s URL (check out https://mooremachine.github.io/smallblog/ for an example). You should be greeted by a 404 webpage, so how can we fix this?
When you’re using Hugo and GitHub Pages, you’ll have to tell GitHub to build your site from your repository’s master
, but also to check a docs/
directory for your static files. By default, Hugo puts these files in a place called public/
. Check it out for yourself: go to your Docker container and type $ hugo
. This will build your static files.
To build your site’s files in a directory that is not public/
, add the following to your config.toml
file:
publishDir = "docs"
Remove the public/
directory and build your files again with $ hugo
, and you’ll see a docs/
directory containing .html
, .css
, .xml
, .js
, and .woff*
files. Commit and push these new changes to your GitHub repository. Go back to your repo’s settings page and configure it to build from master
and the docs
directory.
Try reloading your website and see what happens. You’ll still get the same 404 error page. Even if you delete your cookies you won’t be able to see your blog. Why? Because you should change your baseURL
to https://username.github.io/smallblog/
in your config.toml
file. I tried multiple different options (you can check out my repo’s Git history) when setting the baseURL
but some things would break my site on GitHub Pages and others would break my local environment. So just call set your baseURL
to https://username.github.io/smallblog/
but know that to test things locally you’ll have to go to http://localhost:1313/smallblog/
(Hugo will still remind you of this).
At this point, you might have realized that while our new website is up and running, we can’t see our first post. This is because the post is still labeled as a draft. Go back to your Docker container and edit content/posts/my-first-post.md
and so that you have draft: false
. Before rebuilding your changes you should delete your docs/
directory. Running hugo
won’t delete previously generated files, so you have to do that yourself.
Once you have deleted your old docs/
files and built new ones with hugo
, push them to GitHub and see your website. Now you’re all done!
Summarizing
Hopefully you’ve found it easy to create a blog using GitHub pages. If you want a quick (incomplete) recap of what we did:
- Start by getting Hugo to run inside a Docker container
- Create a new directory for your blog
- Then create a new Hugo site inside that directory
- While editing your site you can use
$ hugo server -D
to run a local server to browse your blog - The trickiest part might be deploying it to GitHub pages, so make sure to save your built web files in a
docs/
directory rather than the defaultpublic/
directory - Use the right
baseURL
- Set
draft: false
when you’re done - And don’t forget to delete any generated files before running
hugo
and pushing the final version of your post