Here´s what it took me to go online with my own Website / Blog again and make it GDPR compliant (at least I think it is).
What I wanted to achieve
I wanted to go online again without the fear of someone trying to sue me to death because I unintentionally did something wrong. Although the GDPR is usually a great thing for EU citizens, it got quite risky to host a Website for non-commercial purposes also. It feels like a minefield when you go out there and you have to make sure you publish a legal notice on your site, whether external content is loaded and from where and if you set cookies, you need one of those fancy cookie consent banners. When I put some information out there that barely anyone will read, I at least did not want to take care of all that stuff or get someones victim who thinks squeezing out money of me is a honorable profession.
Also, as soon as you put something on the Internet, you are at risk that someone will break it and / or misuse it. So you have to pay attention that whatever Software you use, it has to be configured properly and patched to the latest and greatest.
As a private individual I don’t want to deal with all that stuff.
Thoughts to achieve that
If I go online again, I wanted to have something with the following features:
- Preferrably a static site without the need of PHP, a database or other server-side stuff that I need to pay attention to or that can be attacked easily.
- It has to be somewhat easily managable by me. If I write an article, I want to do it in Joplin or Obsidian as plain Markdown and do not have to care to “convert” my article again for publishing on the Website.
- The Website should run just on my Hosters server. If possible, no external data should be downloaded from anywhere else than my Website. This makes it easier to write the proper Legal Notice for my Website, since I do not have a degree in law.
- I do not want to deal with cookies / consent banners, same story as for 3.
- It should support the Mermaid syntax.
The Solution
My personal solution for all of this is currently:
- Obsidian with Templates for the correct Frontmatter to write my articles in Markdown.
- Hugo as the static Site Builder.
- The Hugo theme xyz not because I liked the visuals, but because it has a feature to host everything it needs on your own Server.
- Some customization to the Theme to get Mermaid up and running in the newest version, but also to support Backticks (like I use them when writing Markdown) to render it correctly.
After tinkering with that setup for 2 days now to understand how Hugo / Templating and all that stuff works, I have a setup up and running that could be beneficial to others who seek the same. So let me share with you what I did to achieve this.
This is not a step by step tutorial. I want to show what changes I made from the defaults to get all this up and running. Each step, like spinning up a Hugo container, creating your first site or installing the template has its own, very good instructions and you will probably find settings on your way that you want to configure to tailor the setup to your needs.
The Workflow
This is how it goes at the moment:
graph TD obsidian[Write Post in<br>Obsidian] code-server[VS-Code Server<br>via Docker] webbrowser[Webbrowser<br>Testing] shared-storage[Shared Storage<br>Hugo Project] hoster hugo[Hugo<br>Docker] obsidian--Copy/Paste-->code-server code-server--Save File /content/posts/*.md-->shared-storage webbrowser<--Hugo via ip:1313---->hugo shared-storage--Read Project-->hugo shared-storage--Upload /public-->hoster hugo--Compiled Site-->shared-storage
I write my Articles in Obsidian and Copy Paste them into the /content/posts folder which is accessible via a code-server Docker Container (VS Code in a Browser).
While the Hug Docker Container is running, it picks up my changes, which I can immediately check in my Webbrowser to see if all looks like I want it to be.
If everything is alright, I start the Hug Docker Container with the build command and I upload the resulting contents of the /public folder to my hoster.
Yes, it’s not fully automated, but this is what I have currently.
Building a static Site with Hugo
To get Hugo up and running, I decided to run it as a Docker container. I opted for the hugomods/hugo:exts-non-root
Image from HUGOMODS, because I had no idea what I need and it has it all. When you do not know what you are doing, it can be hard to find out if you just did something wrong or if your build platform is just missing a dependency. With that image, I did not have to take care of dependencies at least.
The docker-compose.yml
file is rather simple for Hugo. This is what I use when testing my Site locally:
services:
hugo:
image: hugomods/hugo:exts-non-root
#command: build
command: server -b http://<ipOfDockerHost>:1313 --disableFastRender
volumes:
- /opt/hugo/src:/src
- /opt/hugo/hugo_cache:/tmp/hugo_cache
ports:
- 1313:1313
If I run a build process, I just uncomment / comment the 2 command parameters in Line #4 and #5.
What’s cool about Hugo when you run it as you see it above: It automatically re-creates the necessary files when you make changes to any files affecting your build. If you for example make a change to a post, you can see the change immediately after saving the file in your browser, if you had this same page open for preview. That’s pretty neat.
The Hugo Theme
The theme I use currently is Beautiful Hugo. By adding the parameter
[params]
selfHosted = true
to the hugo.toml
, you instruct the Theme / or Hugo during the Build process, that all files that are usually pulled from external sites (like fonts or js files), are downloaded during the build process and put into your /public folder where Hugo saves the final build you will put online.
You should read the documentation of the Theme maintainer of how to implement it into your Hugo project. It has many options to customize it to your needs.
Mermaid Support
This took me the longest time to figure out. The Beautiful Hugo theme already has Mermaid support built in, but it had 2 flaws I wanted to fix for my setup:
- The included mermaid.js version was too old for my taste and it did not support some syntax I wanted to use.
- The default implementation in the theme required me to use “Hugo syntax”
{{< mermaid >}}
instead of the fencing```mermaid
for my Mermaid blocks. I am used to the standard Markdown fencing when writing Markdown in Obsidian. This prevented me from just copy / pasting my articles into Hugo.
It took me numerous attempts and I went through all the instructions I could find out there, but I always ended up with either a local mermaid.js, but with the Hugo syntax or with the fencing syntax, but with the mermaid.js loaded externally.
So this is what I came up with:
Installing the Hugo Mods Mermaid Mod
You can get it from here.
To enable the Mod and make it run mermaid.js off my own Website, I had to make the following changes to my Hugo project.
Modify the hugo.toml
to enable the Mod:
[module]
[[module.imports]]
path = "github.com/hugomods/mermaid"
[params.mermaid]
js_url = '/js/mermaid.js'
I downloaded the latest mermaid.js from the JSDeliver CDN and put it into the /static/js
folder of my Hugo project.
To enable Mermaid in my Posts and Post Previews, I had to pull 2 files from the Theme Repo and 1 file from the Mermaid Mod Repo, make a small change and put them into the Override directories of my Hugo project.
Overrides for the Theme
You can get the files from the Themes GitHub Repo, just download them and put them into your Hugo project like described here.
The 1st file is /layouts/_default/single.html
and I added this before the last {{ end }}
:
{{ partial "mermaid/assets/js" . }}
The 2nd file is /layouts/partials/post_preview.html
and I also added this before the last {{ end }}
:
{{ partial "mermaid/assets/js" . }}
Mermaid Repo
I got the /layouts/partials/mermaid/assets/js.html
from the Mod Repo on GitHub and put it into the same directory of my Hugo project. I then made the following changes:
{{- if .Store.Get "hasMermaid" }}
<script defer src="{{ .Site.Params.mermaid.js_url }}">
mermaid.initialize({startOnLoad:true});
</script>
{{- end -}}
This effectively allows the self-hosted mermaid.js file to load and not throw an error. I know nothing about js, but the way the Mod was loading the mermaid.js from the JSDeliver CDN worked, but when switching to a local URL I always got an error message about a missing entrypoint ‘Default’. Changing the part above to what it is, allows the mermaid.js to load and do its thing.
The Result
Here is what the Dev Tools tell me when I browse my site (this is with local testing, but Online it looks the same, apart from the source address).
If we look at the Sources in the Dev Tools, we can see that the only source of data is my test Host. If you do this on the live Website, you will only see the URL of this Website.
If we go to the Applications/Cookies section, we see… nothing:
Exactly what I wanted. No Cookies and no external dependencies :-)
Caveats
The original Mermaid implementation by the theme maker shows the rendered Mermaid diagrams slightly bigger and centered, something I was not able to achieve yet with the changes I made. But it is fully local now, that’s more important than visuals for me at the moment.