Docker Jekyll with Chirpy
Deploy your own Jekyll with theme Chirpy in Docker
Build your own Jekyll with theme Chirpy in Docker
Setting up your own Jekyll blog using the Chirpy theme doesn’t have to be complicated. Whether you want to test it locally, develop in a containerized environment, or deploy your blog using Docker, this guide walks you through every step.
In this post, we’ll cover:
- 🛠️ How to containerize a Jekyll project using Docker.
- 🎨 How to integrate the Chirpy theme.
Before you start — you’ll need your own private Jekyll repo (use the chirpy-starter template), a
${GITHUB_TOKEN}scoped to that repo to build it, and your Docker image kept private if you push it to Docker Hub — it’ll contain yourGITHUB_TOKENbaked into the git history layer otherwise.
This setup is perfect if:
- You want to avoid installing Ruby and all its dependencies on your host.
- You like isolated and reproducible environments.
- You’re building for production mode.
Let’s get your blog running in a container in just a few minutes.
🐳 1 - Build Jekyll + Chirpy theme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
ARG GITHUB_TOKEN
# Update and Install
RUN apt-get update && \
apt-get install -y \
curl \
git \
build-essential \
libssl-dev \
libreadline-dev \
zlib1g-dev \
libsqlite3-dev \
libyaml-dev \
libcurl4-openssl-dev \
libffi-dev \
libgdbm6 \
libgdbm-dev \
gcc \
make \
autoconf \
bzip2 \
libbz2-dev \
unzip \
gnupg2 \
nginx && \
apt-get clean
# Install Node.js 18
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \
apt-get install -y nodejs
# Install rbenv and ruby-build
RUN curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-installer | bash
# Configure rbenv
ENV PATH /root/.rbenv/bin:$PATH
RUN eval "$(rbenv init -)" && \
rbenv install 3.1.2 && \
rbenv global 3.1.2
# Install Jekyll and Bundler
RUN /bin/bash -c "export PATH=/root/.rbenv/bin:/root/.rbenv/shims:$PATH && eval \"\$(rbenv init -)\" && gem install jekyll bundler && rbenv rehash"
# Clone your Repository
RUN git clone https://${GITHUB_TOKEN}:x-oauth-basic@github.com/youruser/jekyll.git /root/jekyll-chirpy
EXPOSE 80
WORKDIR /root/jekyll-chirpy
# Install Ruby and Node.js (bundle + npm + build)
RUN /bin/bash -c "export PATH=/root/.rbenv/bin:/root/.rbenv/shims:$PATH && \
eval \"\$(rbenv init -)\" && \
gem install sass-embedded -v 1.86.0 && \
bundle install && \
npm install && \
npm run build"
RUN rm -rf /var/www/html && mkdir -p /var/www/html
# NGINX simple
RUN echo 'server { \
listen 80; \
root /var/www/html; \
index index.html; \
location / { \
try_files $uri $uri/ =404; \
} \
}' > /etc/nginx/sites-enabled/default
# CMD for Prod (pull + build + serve)
CMD ["/bin/bash", "-c", "\
cd /root/jekyll-chirpy && \
git pull origin master && \
export PATH=/root/.rbenv/bin:/root/.rbenv/shims:$PATH && \
/root/.rbenv/shims/bundle install && \
JEKYLL_ENV=production /root/.rbenv/shims/bundle exec jekyll build && \
rm -rf /var/www/html/* && \
cp -r _site/* /var/www/html && \
nginx -g 'daemon off;'"]
✅ Done
This image will download your Jekyll repo and serve it through nginx, rebuilding on every container start. When you push new content to your repo, you only need to restart the container to pick it up — no rebuild of the image required.
Notice the
CMDdoesgit pullat container startup, not at image build time — that’s what lets a plain restart deploy new content instead of a full image rebuild. This blog itself is deployed exactly this way: a CI pipeline SSHes in, pulls the latest commit, and restarts the container.
