Building a blog with Jekyll, Docker and GitLab
I recently rebuilt my blog using Jekyll with Docker and GitLab so I'm going to share a similar process I used to create it.
The goal of this article is to build a simple Jekyll blog without installing anything on our machine and automate the deployment to a free GitLab page using GitLab CI.
Project structure
I chose the following structure for our blog named project
:
src
: the Jekyll sourcesdist
: the compiled static site
The development workflow will be as follows:
- make changes to the
src
folder by adding new posts, changing styles etc.. - run Jekyll inside a Docker container to compile and preview the static site mounted locally to the
dist
folder - inspect the generated site in the
dist
folder if needed - use GitLab CI to rebuild the GitLab page from the content of the
dist
folder after a push to the master branch
Project setup
Let's create the project
directory to host the new blog and add a docker-compose.yml
file containing the following:
version: '2'
services:
jekyll:
image: jekyll/jekyll
volumes:
- ./src:/srv/jekyll/site
- ./dist:/srv/jekyll/_site
ports:
- "4000:4000"
We can now build a new Jekyll project named site
that will be mounted to our local src
folder:
$ docker-compose run jekyll jekyll new site
If you look into your project
directory, you will see the following structure:
.
├── dist
├── docker-compose.yml
└── src
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _posts
│ └── xxxx-xx-xx-welcome-to-jekyll.markdown
├── about.md
└── index.md
Building and previewing the blog
When everything is in place we can build and serve our blog while watching for changes:
$ docker-compose run --service-ports jekyll jekyll serve --source=site
If you browse to http://localhost:4000
, you will see your new blog!
Gitlab setup
Add a .gitlab-ci.yml
file at the root of the project, containing the following:
pages:
image: alpine:latest
script:
- cp -R ./dist ./public
artifacts:
paths:
- public
only:
- master
From now, a GitLab CI pipeline will be launched each time there is a push to the master
branch and will mount our dist
folder content as the root of the GitLab page.
Setup a new Gitlab repository called project
:
Commit and push the changes to the master
branch:
$ git init
$ git remote add origin git@gitlab.com:{username}/project.git
$ git add .
$ git commit -m "Initial commit"
$ git push -u origin master
A new pipeline has just been created. Once it's passed, the blog is available at https://{username}.gitlab.io/project/
.
But, as you can see, asset paths are broken because the base url of the page is /project/
.
In order to change it, we need to edit /src/_config.yml
:
baseurl: "/project"
We can now rebuild the site:
$ docker-compose run jekyll jekyll build --source=site
When our changes are committed and pushed to the repo, the paths are fixed.
Daily workflow
When we want to work on the blog, for example, to create a new post, we just need to start Jekyll to build and serve the site:
$ docker-compose run --service-ports jekyll jekyll serve --source=site
The site will be automatically reloaded when there is a change in the
src
folder
To preview it, we can browse to http://localhost:4000/project/
.
When we are happy with the changes, we can push them to the GitLab repo and the live blog will be rebuilt.