The blog based on Hugo deployed on GitHub Pages with Github Actions.
To create a Hugo site, the first thing you should install Hugo. To avoid installing Hugo on the PC, Docker is a good choice which allows users to package the application with all of its dependencies into inside container.
- creating a
docker-compose.yml
file with the configurations below, and create a new emptyhugo
directory
version: "3"
services:
server:
image: klakegg/hugo:0.93.2-ext-ubuntu-onbuild
container_name: hugo-server
# uncomment this when first run
# command: new site /src
command: server
volumes:
- "./hugo:/src"
ports:
- "1313:1313"
- uncomment the line
command: new site /src
and comment the linecommand: server
in thedocker-compose.yml
file - run
docker-compose up
- comment the line
command: new site /src
and uncomment the linecommand: server
in thedocker-compose.yml
file - run
docker-compose up
again, then you can see an empty site inlocalhost:1313
address by browser
The configure file of docker-compose.yml
as the below shown:
version: "3"
services:
server:
image: klakegg/hugo:0.93.2-ext-ubuntu-onbuild
container_name: hugo-server
# uncomment this when first run
# command: new site /src
command: server
volumes:
- "./hugo:/src"
ports:
- "1313:1313"
Let me explain the details of the configurations:
- image: The server create container based an image from a public repository in Docker Hub, which is recommended by Hugo. As for the tags, you can use other as you like, but
-ext
is recommended since some theme may use additional tools. - command: The default entrypoint of the container is
hugo
, when we setcommand: [option]
, it will runhugo [option]
inside container. However, thehugo server
command will fail with an errorhugo-server | Error: Unable to locate config file or config directory. Perhaps you need to create a new site.
when we build a website firstly since we have nothing in current workspace. To solve the problem, we can uncommentcommand: new site /src
and commentcommand: server
, which will create a create a new Hugo site in current workspace. - volumes: The key mounts the project directory(
./hugo
) on the host to the path('/src') inside the container. Using./hugo
instead of current directory is because an errorhugo-server | Error: /src already exists and is not empty. See --force.
will occur if the initial directory is not empty. Another way to solve the problem is using--force
flag. - ports: The key binds the container and the host machine to the same port
1313
.
Since there is no docker-compose.yml
, we can create a website in current directory.
- If you have no hugo website, run
docker run --rm -it -v ${pwd}:/src klakegg/hugo:0.93.2-ext-ubuntu-onbuild new site .
to create a new Hugo site. - run server:
docker run --rm -it -v ${pwd}:/src -p 1313:1313 klakegg/hugo:0.93.2-ext-ubuntu-onbuild server
, then you can see an empty site inlocahost:1313
There are so many beautiful themes for Hugo, we can select one in the Hugo Themes. Here I use zozo theme(fork from hugo-theme-zozo) to show how to apply a theme for our site.
since changing theme opeation just related to git operation and file change, so we can change theme by two approaches, inside or outside container.
If we want to upload the docker-compose.yml
to your github repository, the method is recommended.
- using
zozo
as submodule with
git submodule add --depth=1 https://github.com/nicolgo/hugo-theme-zozo.git hugo/themes/zozo
git submodule update --init --recursive # needed when you reclone your repo (submodules may not get cloned automatically)
- Updating the theme:
git submodule update --remote --merge
- Setting in
config.toml
:
theme: "zozo"
- enter continer with:
docker exec -it hugo-server /bin/bash
- Using theme as submodule with
git init
git submodule add --depth=1 https://github.com/nicolgo/hugo-theme-zozo.git themes/zozo
git submodule update --init --recursive # needed when you reclone your repo (submodules may not get cloned automatically)
- Updating the theme:
git submodule update --remote --merge
- Setting in
config.toml
with:
echo theme = \"zozo\" >> config.toml
- start container by docker-compose or docker command.
There are two ways to publish your website.
- using two repositories. one is a private repository to store file. another is a public repository named
username.github.io
, which store the static pages generated in the./public
directory by Hugo. - only use one repository but two branches. one is the main branch with original files, another branch used to store static pages generated by Hugo. The repository can be public or private.
Here we use one public repository to store our blog files and deployed the pages to
username.github.io
with GitHub Actions automatically.
- create a new public repository follow the guide.
- upload blog file to the repository.
- create a file in
.github/workflows/gh-pages.yml
- if you did not create a
Hugo
to store your file, you just follow the guide to write thegh-pages.yml
. The details is:
name: github pages
on:
push:
branches:
- main # Set a branch to deploy
pull_request:
jobs:
deploy:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
# extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
if you use a isolated Hugo
directory, you should change the file as below:
name: github pages
on:
push:
branches:
- main # Set a branch to deploy
pull_request:
jobs:
deploy:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest'
# extended: true
- name: Build
working-directory: ./hugo
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.ref == 'refs/heads/main' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./hugo/public
- rename
baseURL
inconfig.toml
with the valuehttps://<USERNAME>.github.io
and upload it. - In the repository profile, going Settings->Pages, change the source branch to
gh-pages
. Congratulation, your site created successfully!
see GitHub Action
- enter the docker container with:
docker exec -it hugo-server /bin/bash
- using
hugo
command to generate a content file base on templates inArchethypes
folder
hugo new posts/first-blog.md
or create a content by Leaf Bundle
way:
hugo new posts/first-blog/index.md
There are two ways to group your images: Static Files or Page Bundles.
- create a
static/
directory in site directory - adding a file
static/image.png
, then include it in markdown file with![Example image](/image.png)
- create a content with the command below,
index.md
is a must.
hugo new posts/first-blog/index.md
- add an image to
posts/first-blog/image.png
The file structure will like this:
- posts
- first-blog
- index.md
- image.png
- first-blog
- include the image in markdown file with
![Example image](./image.png)
[3] How to use Develop Jekyll (and GitHub Pages) locally using Docker containers