Build Your Blog with Jekyll, Docker, Gitlab
The goal of this article is to build a simple Jekyll blog without installing anything on your machine (using Docker technology) and automate the deployment to a free GitLab page using GitLab CI.
If you don’t know what Docker is read my article Docker Presentation
Project structure
I chose the following structure for our blog named project:
src: the Jekyll sources
dist: the compiled static site
The development workflow will be as follows:
Editor will make changes to the `src` folder by adding new posts, changing styles and so on
Then, 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
You need an account on gitlab.com. It’s free.
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.
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.
Create a Jekyll based Blog
Clone a jekyll repository and rename it to projectid.gitlab.io
Create .gitlab-ci.yml
image: ruby:2.3
variables:
JEKYLL_ENV: production
before_script:
- bundle install
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
Have fun!