The blog you are currently viewing is built using Hugo, a static site generator, and is hosted on OVH. The entire codebase for this blog is hosted on my self-hosted Forgejo instance, which provides a secure and customizable environment for version control. To streamline the deployment process, Forgejo Actions is used, ensuring that any updates to the blog are automatically built and deployed through a CI/CD pipeline.
In this article, I will describe how this blog is published using this specific setup. The process involves configuring Hugo for static site generation, managing the codebase with Forgejo, and automating deployments with Forgejo Actions. The hosting is handled by OVH, which serves the static content efficiently.
This setup is one of many possible ways to publish a blog, showcasing an efficient workflow using Hugo, Forgejo and OVH.
Hugo
When I want to publish a new article, I start by running the hugo new
command, which generates a new Markdown file in my blog’s content directory. This file serves as the template for my post, complete with metadata like the title, date, and tags. I then write my article directly in this Markdown file, using its simple syntax for formatting text, links, and images. To preview my work in real-time, I use the hugo server -D
command, which launches a local development server. This allows me to see how my article will look once published, including drafts, and automatically refreshes the page as I make changes.
Forgejo
Once I’m satisfied with the article, I use standard Git commands to commit the Markdown file and push it to my Hugo repository. This repository is self-hosted on my Forgejo instance, ensuring that my content and version history remain under my control. A simple git add
, git commit
, and git push
is all it takes to sync my changes, triggering the next step in my publishing workflow.
Forgejo Actions and OVH
As soon as the git push
is complete, a Forgejo Actions pipeline automatically kicks in. This pipeline is configured to build the static HTML files using Hugo and then securely upload them via SFTP to my OVH hosting space.
Here is the detail of the workflow :
on:
workflow_dispatch:
push:
branches:
- master
jobs:
build:
runs-on: docker
env:
# renovate: datasource=github-releases depName=gohugoio/hugo versioning=regex:^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)$ extractVersion=^v?(?<version>\d+\.\d+\.\d+)$
HUGO_VERSION: 0.148.2
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Go
uses: https://github.com/actions/setup-go@v5
with:
go-version: "1.24"
- name: Set up Hugo
uses: https://github.com/peaceiris/actions-hugo@v3
with:
hugo-version: ${{ env.HUGO_VERSION }}
- name: Build pages
run: hugo --minify
- name: Deploy with Password
uses: https://github.com/wlixcc/SFTP-Deploy-Action@v1.2.6
with:
username: ${{ secrets.SFTP_USER }}
password: ${{ secrets.SFTP_PASS }}
server: ${{ secrets.SFTP_HOST }}
port: 22
local_path: "public/*"
remote_path: "www/"
sftp_only: true
delete_remote_files: true
Conclusion
Setting up a modern blog with Hugo and a CI/CD pipeline has never been easier, thanks to the wealth of tools and resources available today. Whether you choose a self-hosted solution like the one described here—using Hugo, Forgejo, and Forgejo Actions—or follow a different approach, such as the method demonstrated in Christian Lempa’s YouTube tutorial, the process is both accessible and highly customizable. With just a few commands and a bit of configuration, you can automate your entire publishing workflow, from writing in Markdown to deploying static content. The flexibility of these tools means you can adapt them to fit your specific needs, making it simpler than ever to share your ideas with the world. If you’re looking to start your own blog, now is the perfect time to explore these powerful and efficient solutions!