4.4 KiB
title | date | draft | slug | tags | type | ||||
---|---|---|---|---|---|---|---|---|---|
Migrate from Ghost to Hugo | 2024-02-17 | true | migrate-from-ghost-to-hugo |
|
programming |
Current solution
I've had a blog since early 2022. Historically, I chose Ghost to make this site. At the time, several factors led me to choose this CMS rather than another:
- Ease of deployment and use
- Online administration page and article editor
- Simple, modern theme
- Regular updates
But after using it for quite some time, a number of problems have arisen that can't really be corrected:
- Limited customization
- Complex theme modification if you want to be able to update it afterwards
- Significant resource requirements for Ghost+Mysql (see Conclusion)
- No options for advanced content organization
- Too many unused options to justify this choice (subscription, user account, etc.)
All these problems, combined with the fact that my needs had evolved, led me to change the technical solution for my blog.
Choosing a new solution
Today, there are many options for blogging. Third-party hosted options like Medium, CMS like Wordpress and Ghost, but also static websites generators. For this new version of my blog, I've opted for a static websites generator.
Here again, there are several solutions, but I've settled on Hugo.
Hugo is a GO-based opensource framewok created in 2013. It's known for being very fast, highly customizable and with a very active community.
After choosing Hugo I had to choose a theme, I had several requirements in terms of features. I ended up choosing Blowfish.
It's a highly flexible and customizable theme, regularly updated, with a minimalist, modern design.
Migration
Settings
Contents and optimization
find ./content/ -type f -name '*.png' -exec sh -c 'cwebp -q 90 $1 -o "${1%.png}.webp"' _ {} \;
https://pawelgrzybek.com/webp-and-avif-images-on-a-hugo-website/
Storage and automatic deployment
Git-LFS
apt install git-lfs
git lfs install
git lfs migrate \
import \
--include="*.jpg,*.svg,*.ttf,*.woff*,*.min.*,*.webp,*.ico,*.png,*.jpeg" \
--include-ref=refs/heads/main
CI/CD
hugo.Dockerfile:
FROM golang:1.22-alpine AS build
ARG CGO=1
ENV CGO_ENABLED=${CGO}
ENV GOOS=linux
ENV GO111MODULE=on
RUN apk update && \
apk add --no-cache gcc musl-dev g++ git
RUN go install -tags extended github.com/gohugoio/hugo@v0.122.0
I then use the following commands to build the Hugo image:
docker build -t git.d3vyce.fr/d3vyce/hugo:latest -f hugo.Dockerfile .
docker push git.d3vyce.fr/d3vyce/hugo:latest
Dockerfile:
# Build Stage
FROM git.d3vyce.fr/d3vyce/hugo:latest AS build
WORKDIR /opt/blog
COPY . /opt/blog/
RUN git submodule update --init --recursive
RUN hugo
# Publish Stage
FROM nginx:1.25-alpine
WORKDIR /usr/share/nginx/html
COPY --from=build /opt/blog/public /usr/share/nginx/html/
COPY nginx/ /etc/nginx/
EXPOSE 80/tcp
name: Build Blog Docker Image
on:
push:
branches:
- main
jobs:
build docker:
runs-on: linux_amd
steps:
- name: checkout code
uses: actions/checkout@v3
# with:
# lfs: 'true'
- name: Checkout LFS
run: |
function EscapeForwardSlash() { echo "$1" | sed 's/\//\\\//g'; }
readonly ReplaceStr="EscapeForwardSlash ${{ gitea.repository }}.git/info/lfs/objects/batch"; sed -i "s/\(\[http\)\( \".*\)\"\]/\1\2`$ReplaceStr`\"]/" .git/config
git config --local lfs.transfer.maxretries 1
/usr/bin/git lfs fetch origin refs/remotes/origin/${{ gitea.ref_name }}
/usr/bin/git lfs checkout
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker registry
uses: docker/login-action@v2
with:
registry: git.d3vyce.fr
username: ${{ github.actor }}
password: ${{ secrets.GIT_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: git.d3vyce.fr/${{ github.repository }}:latest
https://gitea.com/gitea/act_runner/issues/164