New blog, who dis?
Ahhh, here we go again with yet another new blog...
You see, I've tried starting (and maintaining) a blog a few times now. You can probably guess how that went the last time I tried by taking a look at blog.hongs.me. It's been almost exactly 6 years.
But since I've had many interesting projects since then, especially recently, I thought I would try once more yet again.
One key note is that I am hosting this on my own server rack behind me, with GitHub pages-like automatic build and deploy.
GitHub pages and Forgejo
I'll probably have a separate post talking about my underlying setup, but the short version is:
On my docker swarm cluster, I've recently set up a Forgejo instance. If not familiar, it's a hard-fork of Gitea, which is a open source alternative to GitLab and GitHub that can be self-hosted.1
What I like about Forgejo/Gitea over other similar, simpler, git hosting software (like cgit), is that they come with package registries2 and GitHub-compatible actions runner3 for running CI/CD pipelines.
These, in combination, allow me to build, package, and push my projects automatically, including this blog -- very similarly to how GitHub pages work.4
Static Site Generator
I wanted something similar where I can just push some source markdown documents, have them automatically built with a static-site generator, and then have the built web files be pushed automatically to a public page.
The last "blog" that I set up was using jekyll for the static-site generator. I've just done a quick search around for what people are using nowadays. Many have recommended Hugo or Zola. Without much else research, I just chose Zola as people claim it is faster and the templating engine is "better".
Automatic builds
Luckily, there was already a "GitHub action" for building and publishing Zola, with an option to only perform build. That is useful for this case where we are not pushing to GitHub pages.5
My workflow step just looks like:
- name: Build
uses: https://github.com/shalzz/[email protected]
env:
BUILD_ONLY: true
BUILD_THEMES: true
I need to specify the full URL to the action repo since Forgejo defaults to using https://data.forgejo.org unless DEFAULT_ACTIONS_URL is specified.6
Automatic push
Now the more "difficult" part is getting that built site and pushing it to somewhere that's gonna host a public site with it.
In my current setup, the simplest approach was to just have a Docker container running an nginx7 image, with the web root mounted on a shared volume.
I already have a setup for hosting different services, where all of my HTTP/S traffic goes through a Traefik8 reverse proxy.
So then I just have to copy the build files over to the shared docker volume... somehow.
I didn't really want to overcomplicate this, so instead...
-
I just quickly wrote up some web server in Python that will take a tar archive uploaded via a POST request and extract it to a directory.
-
That server will be running on another docker container and have the same volume mounted for the web root.
-
That docker container is built and pushed in a CI workflow in another repo, utilizing Forgejo's container registry
...talk about not overcomplicating things.
To be fair, it was much simpler than fixing up my broken portainer and then hooking up the API. Or giving the build-push container access to the entire cluster -- or creating access control rules now. Or migrating everything back to kubernetes and setting up roles and ACLs.
The Python server and the workflow can be found at brian/blog-deploy
That container is deployed along with the Nginx container actually serving the web page (this blog).
And then, in the blog's workflow, files uploaded:
- name: Package and Deploy
run: |
tar czf blog.tgz -C public .
curl -X POST -H "Content-Type: application/gzip" -F "[email protected]" http://docker-00:8008/
Uhh, yeah. That's it.
Future
Hopefully, I actually maintain and write more posts for this blog, starting with migrating over the posts from the previous blog.
And oh yeah, happy 2026!
73
-B
-
There is a feature and other ideas comparison on Forgejo's page ↩
-
Forgejo and Gitea can be used as registries for common package managers like Debian's APT, PyPI, go, and even containers. See information on Forgejo's supported package registry types here ↩
-
Gitea (and Forgejo) can run CI/CD pipelines, provided by their act runner. ↩
-
Zola can be used with GitHub pages with the
zola-deploy-actionlink ↩ -
https://forgejo.org/docs/next/user/actions/reference/#jobsjob_idstepsuses ↩
-
Nginx is a web server that can also be used as a reverse proxy and load balancer, amongst many things. ↩
-
I use https://traefik.io/traefik for my reverse proxy. It can be useful for setups like mine where multiple services can be routed through a single IP. It also handles my HTTPS certificate management and TLS termination. ↩