mirror of
https://github.com/mastermindzh/rickvanlieshout.com
synced 2025-09-09 17:56:07 +02:00
Compare commits
81 Commits
v1.3.0
...
snyk-upgra
Author | SHA1 | Date | |
---|---|---|---|
|
9098e27cae | ||
b9d1b1ae13 | |||
|
0ce8af8cc7 | ||
6eee5ac150 | |||
7e897d7aa7 | |||
2e65d236d0 | |||
9b34c6226b | |||
af3497f3d8 | |||
029e59c029 | |||
|
07b36b5b06 | ||
|
084a9cdfc2 | ||
9f05d8a715 | |||
283c25681b | |||
2d71d81e2d | |||
|
ce1d321ca5 | ||
e0e70ef02b | |||
|
6a68317467 | ||
bb9c60cae1 | |||
|
68be00f203 | ||
4a2cda3b3a | |||
44f64093b7 | |||
|
c049550537 | ||
|
63358f9ae1 | ||
65b5a25d55 | |||
|
f388078e7b | ||
2001f3177f | |||
ff05ed96ff | |||
f18dd8874f | |||
|
65ee109e90 | ||
|
9a2be8d95c | ||
|
2dc8dc3ffb | ||
dcff39ec77 | |||
|
aced724d40 | ||
499897f894 | |||
|
3b8b879bb1 | ||
04717d6035 | |||
|
271152db62 | ||
41ed9dd34c | |||
|
03122f846a | ||
fe9627da68 | |||
|
32536e64c7 | ||
a55a136087 | |||
830b9cf4d8 | |||
aa87dd0be7 | |||
|
a86aca1a71 | ||
|
cf99cbf027 | ||
|
76fa1f530d | ||
34d69891ca | |||
3756a9c1c8 | |||
|
09019de153 | ||
bc7e35b888 | |||
|
fd15d4ac18 | ||
|
6148d98155 | ||
d6a7dbefde | |||
|
f543e30e42 | ||
4be2bf852e | |||
ca2602f883 | |||
e3aca41540 | |||
|
73534260f7 | ||
479a9225bc | |||
|
5dc76679ef | ||
dd293bcc63 | |||
|
71571bd7fb | ||
6a2239aa2b | |||
|
bac1e1d9d6 | ||
5329fdd6a4 | |||
82115dd07a | |||
247a9a17e0 | |||
e7fae60efb | |||
1c4c9d058a | |||
e065f16fb5 | |||
|
dae867c1b0 | ||
8245e1f0d8 | |||
0e0d470ef5 | |||
|
f13f40df35 | ||
81dee3ad5c | |||
7dc8aade23 | |||
7019f34005 | |||
167b70159c | |||
ed28488273 | |||
|
043d08e58f |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.14.0
|
||||
node-version: 22.12.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@@ -1,10 +1,17 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"codepen",
|
||||
"disqus",
|
||||
"fontawesome",
|
||||
"fortawesome",
|
||||
"frontmatter",
|
||||
"slsw"
|
||||
"Lieshoutt",
|
||||
"Rickvan",
|
||||
"rickvanlieshoutcom",
|
||||
"slsw",
|
||||
"soundcloud",
|
||||
"todos",
|
||||
"weibo"
|
||||
],
|
||||
"grammarly.selectors": [
|
||||
{
|
||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@@ -2,6 +2,18 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [1.3.1](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.3.0...v1.3.1) (2023-10-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fixed tags and categories in several blog posts ([7019f34](https://github.com/mastermindzh/rickvanlieshout.com/commits/7019f340050c04eed6065c4ddd4582d6b2d22b9b))
|
||||
* now setting og:url correctly as well as the canonical url ([e065f16](https://github.com/mastermindzh/rickvanlieshout.com/commits/e065f16fb505eb8f9e5acef6f92c5a016e276ebc))
|
||||
* set current url tags in both ssr and browser space ([1c4c9d0](https://github.com/mastermindzh/rickvanlieshout.com/commits/1c4c9d058a7382ebe52dd1b188b22ca8d7a185c3))
|
||||
* several fixes to improve ahrefs site score ([8245e1f](https://github.com/mastermindzh/rickvanlieshout.com/commits/8245e1f0d8854cd6a727a8b837ee3259ee040d48))
|
||||
* upgrade gatsby from 5.12.1 to 5.12.3 ([043d08e](https://github.com/mastermindzh/rickvanlieshout.com/commits/043d08e58f9962688bd615b8e8d535e4111e7aa2))
|
||||
* upgrade gatsby from 5.12.3 to 5.12.4 ([f13f40d](https://github.com/mastermindzh/rickvanlieshout.com/commits/f13f40df35cc0230ddcf7766a7b2e73477696439))
|
||||
|
||||
## [1.3.0](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.2.3...v1.3.0) (2023-09-23)
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Rickvanlieshout.com
|
||||
|
||||
This is the repository for my personal blog/website [rickvanlieshout.com](https://rickvanlieshout.com).
|
||||
This is the repository for my personal blog/website [rickvanlieshout.com](https://www.rickvanlieshout.com).
|
||||
|
||||
[](https://ci.mastermindzh.tech/Mastermindzh/rickvanlieshout.com)
|
||||
|
||||
|
@@ -7,8 +7,8 @@ A list of categories used in the blog
|
||||
| ----------- | -------------------------------------------------------- |
|
||||
| blog | random blog stuff |
|
||||
| IOT | anything to do with IOT |
|
||||
| Homelab | anything to do with my homelab (including smart home...) |
|
||||
| Development | anything to do with regular development |
|
||||
| homelab | anything to do with my homelab (including smart home...) |
|
||||
| development | anything to do with regular development |
|
||||
| exploits | blogs about exploits and bugs in open-source software |
|
||||
| Lego | blogs about Lego |
|
||||
| lego | blogs about Lego |
|
||||
| house | Content about the place I live |
|
||||
|
@@ -46,7 +46,7 @@
|
||||
"author": {
|
||||
"name": "Rick van Lieshout",
|
||||
"photo": "/content/me.png",
|
||||
"bio": "I'm a passionate software architect that bifurcates his love between great software development and leading others to learn and adopt new things.",
|
||||
"bio": "I'm a passionate CTO who bifurcates his love between great software development and leading others in their continuous improvement journeys",
|
||||
"contacts": {
|
||||
"email": "info@rickvanlieshout.com",
|
||||
"github": "mastermindzh",
|
||||
|
@@ -20,14 +20,14 @@ template: "page"
|
||||
_Always_<br />
|
||||
A fair share of my private work is done through open-source media. I don't have a portfolio but I have a [Github](https://github.com/mastermindzh) where I share most things.
|
||||
|
||||
**Tech lead / CTO at INFORIT**<br />
|
||||
**CTO at Frontliners (previously INFORIT)**<br />
|
||||
_2018 - Now_<br />
|
||||
At INFORIT I am responsible for the entire technical architecture of the new TFX stack that I launched shortly after 2018. This involves setting up and maintaining a modern event-based microservice architecture on a Kubernetes-based SaaS cloud solution and migrating to modern programming languages such as dotnetcore and React.
|
||||
At Frontliners I am responsible for the entire technical architecture of the new TFX stack that I launched shortly after 2018. This involves setting up and maintaining a modern event-based microservice architecture on a Kubernetes-based SaaS cloud solution and migrating to modern programming languages such as dotnetcore and React.
|
||||
|
||||
The other main responsibility I have is creating and maintaining a coherent team of lead developers by sharing knowledge, making decisions, and empowering leads to explore technologies outside of their comfort zone.
|
||||
|
||||
At INFORIT I also help with the recruitment of new employees, setting up and maintaining agile strategies including proper test management, and general software development.
|
||||
During my time at INFORIT, we've grown from 5-7 in-house developers to 10, full-sized, SCRUM teams.
|
||||
At Frontliners I also help with the recruitment of new employees, setting up and maintaining agile strategies including proper test management, and general software development.
|
||||
During my time at Frontliners, we've grown from 5-7 in-house developers to 10, full-sized, SCRUM teams.
|
||||
|
||||
Most relevant technologies used: dotnetcore, React, Angular, Kafka, RabbitMQ, Mongo, PostgreSQL, Growthbook, Docker & Kubernetes
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
title: "Raspberry pi cluster Step 1: Shopping"
|
||||
date: "2014-09-05 23:00"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "raspberry"
|
||||
- "cluster"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
title: "Raspberry pi cluster Step 2: Assembling the hardware"
|
||||
date: "2014-09-10"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "raspberry"
|
||||
- "cluster"
|
||||
@@ -14,7 +14,7 @@ socialImage: "./media/improvising.jpg"
|
||||
|
||||
So today I finally received the required parts to finish up my Raspberry pi cluster and I was **extremely** excited! To share this excitement with you lot here's a picture of all the parts I'll be using:
|
||||
|
||||

|
||||

|
||||
|
||||
I began by building the Raspberry pi "tower", sadly I forgot to take a picture with the DSLR so I only have this one cell image to show you guys:
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
title: "Raspberry pi cluster Step 3: Installing the OS"
|
||||
date: "2014-09-14"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "raspberry"
|
||||
- "cluster"
|
||||
|
@@ -2,7 +2,7 @@
|
||||
title: "Raspberry pi cluster Step 4: Setting up the master node"
|
||||
date: "2014-09-17"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "raspberry"
|
||||
- "cluster"
|
||||
|
@@ -2,14 +2,14 @@
|
||||
title: "Raspberry pi cluster step 5: Expanding the cluster"
|
||||
date: "2014-09-19"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "raspberry"
|
||||
- "cluster"
|
||||
- "pi"
|
||||
description: "Today's blog post will be about expanding the cluster with more nodes."
|
||||
disqusId: "6"
|
||||
socialImage: "./media/pidark_full.JPG"
|
||||
socialImage: "./media/pidark.jpg"
|
||||
---
|
||||
|
||||
In today's post we'll have a look at expanding the cluster with more nodes! We will have a look at how to clone them and how we can set up a universal login using ssh keys.
|
||||
@@ -40,7 +40,7 @@ sudo nano /etc/network/interfaces
|
||||
|
||||
After setting up all 4 pi's and plugging it all in you should see all 4 led's light up on the pi's. If this is not the case you might've forgotten to change either the ip address or the hostname. (which will lead to a conflict resulting in one of them not having internet access). Mine now looks like this (note the dramatic night picture taken at 10 past 12 am):
|
||||
|
||||

|
||||

|
||||
|
||||
## Logging in to the nodes with ssh keys
|
||||
|
||||
|
@@ -2,12 +2,12 @@
|
||||
title: "The pi cluster, home automation & kickstarter monitoring"
|
||||
date: "2014-09-27"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "python"
|
||||
- "raspberry"
|
||||
- "pi"
|
||||
- "home automation"
|
||||
- "home-automation"
|
||||
description: "Today's blog is about home automation."
|
||||
disqusId: "7"
|
||||
---
|
||||
|
@@ -3,9 +3,9 @@ title: Scala Day 0 - What is Scala?
|
||||
date: "2017-03-30"
|
||||
template: "post"
|
||||
draft: false
|
||||
category: "Development"
|
||||
category: "development"
|
||||
tags:
|
||||
- "Development"
|
||||
- "development"
|
||||
- "slsw"
|
||||
description: "My final assignment for a school course is to learn a new language from a book (uh-oh). I picked Scala and here's why"
|
||||
disqusId: "20"
|
||||
|
@@ -3,9 +3,9 @@ title: Scala Day 1 - The Basics
|
||||
date: "2017-04-02"
|
||||
template: "post"
|
||||
draft: false
|
||||
category: "Development"
|
||||
category: "development"
|
||||
tags:
|
||||
- "Development"
|
||||
- "development"
|
||||
- "slsw"
|
||||
description: "Let's take a deep dive into a programming book and Scala!"
|
||||
disqusId: "21"
|
||||
|
@@ -3,9 +3,9 @@ title: Scala Day 2 - Let's get functional
|
||||
date: "2017-04-03"
|
||||
template: "post"
|
||||
draft: false
|
||||
category: "Development"
|
||||
category: "development"
|
||||
tags:
|
||||
- "Development"
|
||||
- "development"
|
||||
- "slsw"
|
||||
description: "Today we'll focus on the functional aspects of Scala"
|
||||
disqusId: "22"
|
||||
|
@@ -3,9 +3,9 @@ title: Scala Day 3 - Concurrency is key!
|
||||
date: "2017-04-04"
|
||||
template: "post"
|
||||
draft: false
|
||||
category: "Development"
|
||||
category: "development"
|
||||
tags:
|
||||
- "Development"
|
||||
- "development"
|
||||
- "slsw"
|
||||
description: "A day full of functional joy and concurrency "
|
||||
disqusId: "23"
|
||||
|
@@ -3,9 +3,9 @@ title: Scala Day 4 - A challenge!
|
||||
date: "2017-04-05"
|
||||
template: "post"
|
||||
draft: false
|
||||
category: "Development"
|
||||
category: "development"
|
||||
tags:
|
||||
- "Development"
|
||||
- "development"
|
||||
- "slsw"
|
||||
description: "The last day of my journey with Scala is said to be a challenge"
|
||||
disqusId: "24"
|
||||
|
@@ -2,13 +2,13 @@
|
||||
title: Adopting conventional commits and standard versions in a git and npm codebase
|
||||
date: "2022-11-07"
|
||||
template: "post"
|
||||
category: "Development"
|
||||
category: "development"
|
||||
tags:
|
||||
- "git"
|
||||
- "conventional commits"
|
||||
- "semantic commits"
|
||||
- "INFORIT"
|
||||
- "Standard releases"
|
||||
- "conventional-commits"
|
||||
- "semantic-commits"
|
||||
- "inforit"
|
||||
- "standard-releases"
|
||||
|
||||
description: "A dive into conventional commits and their benefit whilst releasing with standard versions."
|
||||
socialImage: "./media/husky-error.png"
|
||||
@@ -340,7 +340,7 @@ Now, let's add a Husky git hook to combat future commits that are unconventional
|
||||
npx husky-init && npm install
|
||||
```
|
||||
|
||||
This will automatically create the `.husky/pre-commit` file. Let's edit it and add commitlint:
|
||||
This will automatically create the `.husky/` directory. Let's create a file in it called `commit-msg` and add commitlint:
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env sh
|
||||
|
@@ -2,14 +2,14 @@
|
||||
title: Flashing the LSI-9211 to IT mode using an EFI shell
|
||||
date: "2023-04-12"
|
||||
template: "post"
|
||||
category: "Homelab"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "lsi"
|
||||
- "lsi9211"
|
||||
- "raid card"
|
||||
- "storage"
|
||||
- "SAS2000"
|
||||
- "it mode"
|
||||
- "it-mode"
|
||||
description: "Flashing the LSI-9211 used to be way more difficult, luckily the EFI shell makes this task a lot simpler!"
|
||||
socialImage: ./media/flash-result.jpg
|
||||
---
|
||||
|
@@ -9,6 +9,7 @@ tags:
|
||||
- "programming"
|
||||
- "team"
|
||||
- "work"
|
||||
- "inforit"
|
||||
description: "At INFORIT we love to play! Be it DND, board games or in this case... Legos. Read on to find out what we've been up to this past summer vacation"
|
||||
socialImage: ./media/lego-spike-set.png
|
||||
---
|
||||
|
@@ -4,7 +4,7 @@ date: "2023-02-14"
|
||||
template: "post"
|
||||
category: "blog"
|
||||
tags:
|
||||
- "Lego"
|
||||
- "lego"
|
||||
- "house"
|
||||
description: "What started as a simple decoration piece to fill some empty space in my home quickly grew into a new hobby of which the remnants can be found throughout my house"
|
||||
socialImage: ./media/building-the-owl.jpg
|
||||
|
@@ -0,0 +1,130 @@
|
||||
---
|
||||
title: Infrastructure as code - Service uptime monitoring
|
||||
date: "2025-01-18"
|
||||
template: "post"
|
||||
category: "homelab"
|
||||
tags:
|
||||
- "uptime"
|
||||
- "kuma"
|
||||
- "iac"
|
||||
- "infrastructure"
|
||||
- "code"
|
||||
- "servers"
|
||||
description: "In this post I demonstrate how I've moved from an old and simple UptimeKuma setup to a setup with AutoKuma so I can register my monitors with 'infrastructure as code'"
|
||||
socialImage: ./media/uptimekuma.png
|
||||
---
|
||||
|
||||
If there’s one thing I’ve always embraced, it’s the philosophy of working smarter, not harder. Infrastructure as Code (IaC) has been one of the cornerstones of my career. a perfect blend of laziness and the pursuit of predictability. From my earliest days experimenting with Docker back in 2014 to leading a platform team at my current company, IaC has proven invaluable for simplifying complexity, ensuring reproducibility, and enabling automation.
|
||||
|
||||
Below you'll find my journey and why I think every engineer should embrace it, eventually walking you through one of the latest automations I set up at home: Automatically creating uptime monitors in UptimeKuma based on Docker labels.
|
||||
|
||||
## The Early Days: Discovering Docker
|
||||
|
||||
Back in 2014, I stumbled upon Docker, and it was a game-changer. At the time, I was frustrated by the manual and error-prone process of setting up environments for my code (especially on other people's machines....). Docker offered a way to reliably recreate these environments with simple, declarative configuration files. Suddenly, I could spin up a development environment in minutes and be confident it would work exactly the same on another machine.
|
||||
|
||||
In 2017, I taught several university classes on Docker, emphasizing the importance of reproducibility. My students learned how to containerize applications and ensure their work could be shared and run anywhere, regardless of underlying infrastructure. Reproducibility wasn’t just a technical advantage; it became a mindset I encouraged in every project.
|
||||
|
||||
And yes.. for those that know me well, I did go overboard in some of the details and even ended up explaining the entire Copy-On-Write (COW) nature of the Docker filesystem in those classes... But ah well, people learned a lot :P.
|
||||
|
||||
## Home Servers: The Personal Lab
|
||||
|
||||
My passion for IaC extended to my home servers. By 2017, nearly everything I ran at home was Docker-based. I created dozens of bash scripts and system services to orchestrate my personal infrastructure. Whether it was media servers, backup systems, or development environments, everything was automated and version-controlled. Even my own computers mostly became IaC based as I figured out that part of the Linux community was saving their setups (and install instructions, usually) in so called "dotfiles". To this day you can still find my setup (and its changes when I switch machine) in my [Dotfiles on Github](https://github.com/Mastermindzh/dotfiles/).
|
||||
|
||||
All in all, my home setup became a sandbox for testing new ideas and tools, many of which eventually found their way into my professional work as well.
|
||||
|
||||
## Scaling IaC in the Workplace
|
||||
|
||||
At my current company, I introduced Docker about eight years ago. It was a gradual process, but within a year, we had our first Kubernetes cluster running. This transition wasn’t just about adopting new tools; it was about embedding the principles of IaC into the organization’s culture.
|
||||
|
||||
Over time, I spearheaded the creation of a dedicated platform team. With an architect/Product Owner and four DevOps engineers, this team took IaC to the next level. They implemented robust CI/CD pipelines, infrastructure monitoring, and scalable deployment patterns. Some of these practices mirrored what I had done at home, while others were tailored to the unique needs of the business. The result was a resilient and predictable infrastructure that supports rapid development and deployment.
|
||||
|
||||
## Setting Up Uptime Monitoring with UptimeKuma
|
||||
|
||||
One of the most satisfying aspects of IaC is the ability to automate even the smallest tasks. Take uptime monitoring, for example. At home and at work, ensuring that services are available is critical. Recently, I’ve been using my old UptimeKuma instance, a self-hosted monitoring tool that’s as powerful as it is user-friendly, a lot more after introducing it to some friends (who started homelabbing) and at work.
|
||||
|
||||
Setting up UptimeKuma is straightforward, you can simply use our old friend Docker:
|
||||
|
||||
```docker run -d --name uptime-kuma -v ./data/uptimekuma:/app/data -p 3001:3001 louislam/uptime-kuma```
|
||||
|
||||
And access the Dashboard by navigating to <http://localhost:3001> to configure your monitors.
|
||||
But that isn't automatic enough for me, I like to put my things in compose files for home usage.
|
||||
|
||||
## Automating uptime monitors with AutoKuma
|
||||
|
||||
[AutoKuma](https://github.com/BigBoot/AutoKuma) allows us to set labels on our Docker containers that will then automatically generate monitors in UptimeKuma.
|
||||
|
||||
One of my containers (UptimeKuma actually) has the following labels attached:
|
||||
|
||||
```yml
|
||||
labels:
|
||||
kuma.monitoring.group.name: "Monitoring"
|
||||
kuma.uptime_kuma.http.parent_name: "monitoring"
|
||||
kuma.uptime_kuma.http.name: "Kuma status monitoring"
|
||||
kuma.uptime_kuma.http.url: "http://${HOST_IP}:3001"
|
||||
```
|
||||
|
||||
This actually does 2 things:
|
||||
|
||||
- creates a group with the *key/id* `monitoring` and the name `Monitoring`
|
||||
- Adds a monitor with the *key/id* `uptime_kuma` to UptimeKuma with the type `http`, name `Kuma status monitoring`, and url `http://${HOST_IP}:3001`
|
||||
|
||||
Adding these labels, whilst AutoKuma is running and configured to pick up labels starting with `kuma` is enough for monitors to show up (after restarting the containers).
|
||||
All in all, my `docker-compose.yml` file for both UptimeKuma and AutoKuma now looks like this:
|
||||
|
||||
```yml
|
||||
services:
|
||||
autokuma:
|
||||
image: ghcr.io/bigboot/autokuma:master
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
AUTOKUMA__KUMA__URL: http://${HOST_IP}:3001
|
||||
AUTOKUMA__KUMA__USERNAME: ${KUMA_USERNAME}
|
||||
AUTOKUMA__KUMA__PASSWORD: ${KUMA_PASSWORD}
|
||||
AUTOKUMA__TAG_NAME: AutoKuma
|
||||
AUTOKUMA__TAG_COLOR: "#42C0FB"
|
||||
AUTOKUMA__DEFAULT_SETTINGS: |-
|
||||
docker.docker_container: {{container_name}}
|
||||
http.max_redirects: 10
|
||||
*.max_retries: 3
|
||||
AUTOKUMA__DOCKER__LABEL_PREFIX: kuma
|
||||
AUTOKUMA__MIGRATE: true
|
||||
volumes:
|
||||
- ${APP_DATA}/autokuma:/data
|
||||
- ${DOCKER_SOCKET}:/var/run/docker.sock
|
||||
depends_on:
|
||||
- kuma
|
||||
|
||||
kuma:
|
||||
image: louislam/uptime-kuma:1
|
||||
volumes:
|
||||
- ${APP_DATA}/uptimekuma:/app/data
|
||||
- ${DOCKER_SOCKET}:/var/run/docker.sock
|
||||
ports:
|
||||
- 3001:3001
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
kuma.monitoring.group.name: "Monitoring"
|
||||
kuma.uptime_kuma.http.parent_name: "monitoring"
|
||||
kuma.uptime_kuma.http.name: "Kuma status monitoring"
|
||||
kuma.uptime_kuma.http.url: "http://${HOST_IP}:3001"
|
||||
```
|
||||
|
||||
## Problems... the compose file doesn't work :O
|
||||
|
||||
If you'd try to run the compose file in the previous chapter, even after replacing all the variables, things likely still won't work.
|
||||
This is because AutoKuma relies on the credentials for UptimeKuma which we setup during the initial launch of UptimeKuma.
|
||||
Unfortunately, that account is the only account we can currently set up in UptimeKuma since it doesn't have user management.
|
||||
And yes, that means we **have** to use these same credentials to get AutoKuma to work, which also prohibits us from enabling MFA.
|
||||
|
||||
Anyway, after setting up the kuma account, simply adjust both the `KUMA_USERNAME` and `KUMA_PASSWORD` variables and restart the containers.
|
||||
After doing so we should see the monitor appear in UptimeKuma:
|
||||
|
||||

|
||||
|
||||
## The Future of IaC
|
||||
|
||||
Infrastructure as Code isn’t just a technical approach; it’s a philosophy that prioritizes automation, reproducibility, and simplicity. Whether you’re managing a home lab or a global platform, IaC provides the tools and practices to build resilient systems with minimal effort.
|
||||
|
||||
For me, IaC has been a journey of continuous learning and experimentation. From Docker to Kubernetes, from bash scripts to dedicated platform teams, the principles remain the same: automate everything, document everything, and embrace the predictability that code brings to infrastructure.
|
||||
|
||||
If you haven’t already, give UptimeKuma and AutoKuma a try. Their combination is an excellent example of how IaC can simplify even the most mundane tasks, leaving you more time to focus on what really matters... or just to be a little lazier.
|
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
@@ -1,3 +0,0 @@
|
||||
import "./src/assets/scss/main.scss";
|
||||
import "./src/assets/scss/prism/github.scss";
|
||||
import "./src/assets/scss/prism/prism-tomorrow.scss";
|
19
gatsby-browser.tsx
Normal file
19
gatsby-browser.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import "./src/assets/scss/main.scss";
|
||||
import "./src/assets/scss/prism/github.scss";
|
||||
import "./src/assets/scss/prism/prism-tomorrow.scss";
|
||||
|
||||
export const onRouteUpdate = ({ location }: { location: { pathname: string } }) => {
|
||||
const elements = document.querySelectorAll("[data-url]");
|
||||
const currentUrl = `https://www.rickvanlieshout.com${location.pathname ?? ""}`;
|
||||
|
||||
const setAttributeIfAvailable = (element: Element, elementIdentifier: string) => {
|
||||
if (element.hasAttribute(elementIdentifier)) {
|
||||
element.setAttribute(elementIdentifier, currentUrl);
|
||||
}
|
||||
};
|
||||
|
||||
elements.forEach((element) => {
|
||||
setAttributeIfAvailable(element, "href");
|
||||
setAttributeIfAvailable(element, "content");
|
||||
});
|
||||
};
|
@@ -164,13 +164,6 @@ export default {
|
||||
start_url: "/",
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: "gatsby-plugin-react-helmet-canonical-urls",
|
||||
options: {
|
||||
siteUrl: config.url,
|
||||
stripQueryString: true,
|
||||
},
|
||||
},
|
||||
// remove the old service worker if it is available.
|
||||
"gatsby-plugin-remove-serviceworker",
|
||||
"gatsby-plugin-image",
|
||||
|
@@ -18,7 +18,19 @@ const setColorTheme = `
|
||||
}
|
||||
})();
|
||||
`;
|
||||
export const onRenderBody = ({ setPreBodyComponents }: RenderBodyArgs) => {
|
||||
export const onRenderBody = ({
|
||||
setPreBodyComponents,
|
||||
setHeadComponents,
|
||||
pathname,
|
||||
}: RenderBodyArgs) => {
|
||||
const currentUrl = `https://www.rickvanlieshout.com${pathname}`;
|
||||
|
||||
setHeadComponents([
|
||||
<meta data-url="currentUrl" key="og:url" property="og:url" content={currentUrl} />,
|
||||
<link data-url="currentUrl" key="canonical" rel="canonical" href={currentUrl} />,
|
||||
<meta data-url="currentUrl" property="test:rick" key="test:rick" content={currentUrl} />,
|
||||
]);
|
||||
|
||||
setPreBodyComponents([
|
||||
React.createElement("script", {
|
||||
key: "theme",
|
@@ -1,5 +1,5 @@
|
||||
export default [
|
||||
{ label: "Articles", path: "/" },
|
||||
{ label: "About Me", path: "/pages/about" },
|
||||
{ label: "Contact Me", path: "/pages/contacts" },
|
||||
{ label: "About Me", path: "/pages/about/" },
|
||||
{ label: "Contact Me", path: "/pages/contacts/" },
|
||||
];
|
||||
|
25694
package-lock.json
generated
25694
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
167
package.json
167
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rickvanlieshout-com",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"description": "My personal blog / website",
|
||||
"keywords": [
|
||||
"gatsby",
|
||||
@@ -18,8 +18,8 @@
|
||||
"author": "Rick van Lieshout <info@rickvanlieshout.com>",
|
||||
"scripts": {
|
||||
"build": "npm run clean && gatsby build",
|
||||
"commit": "git-cz",
|
||||
"clean": "rimraf .cache public",
|
||||
"commit": "git-cz",
|
||||
"format": "npm run format:ts && npm run format:scss",
|
||||
"format:scss": "stylelint \"src/**/*.scss\" --fix",
|
||||
"format:ts": "eslint \"src\" --ext .tsx,.ts --fix && prettier --write .",
|
||||
@@ -29,9 +29,9 @@
|
||||
"lint:ts": "eslint \"src\" --ext .tsx,.ts && prettier --check .",
|
||||
"prepare": "husky install",
|
||||
"release": "standard-version",
|
||||
"release:major": "standard-version --release-as major",
|
||||
"release:minor": "standard-version --release-as minor",
|
||||
"release:patch": "standard-version --release-as patch",
|
||||
"release:major": "standard-version --release-as major",
|
||||
"reset-snapshots": "find -type f -name '*.snap*' -delete && npm run test",
|
||||
"semantic-release": "semantic-release",
|
||||
"serve": "gatsby serve",
|
||||
@@ -48,115 +48,114 @@
|
||||
"npm run format:scss"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "@commitlint/cz-commitlint"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"classnames": "^2.3.2",
|
||||
"disqus-react": "^1.1.5",
|
||||
"gatsby": "^5.12.1",
|
||||
"gatsby-link": "^5.12.0",
|
||||
"gatsby-plugin-catch-links": "^5.12.0",
|
||||
"gatsby-plugin-feed": "^5.12.0",
|
||||
"gatsby-plugin-google-gtag": "^5.12.0",
|
||||
"gatsby-plugin-image": "^3.12.0",
|
||||
"gatsby-plugin-manifest": "^5.12.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.2",
|
||||
"classnames": "^2.5.1",
|
||||
"disqus-react": "^1.1.6",
|
||||
"gatsby": "^5.14.3",
|
||||
"gatsby-link": "^5.14.1",
|
||||
"gatsby-plugin-catch-links": "^5.14.0",
|
||||
"gatsby-plugin-feed": "^5.14.0",
|
||||
"gatsby-plugin-google-gtag": "^5.14.0",
|
||||
"gatsby-plugin-image": "^3.14.0",
|
||||
"gatsby-plugin-manifest": "^5.14.0",
|
||||
"gatsby-plugin-optimize-svgs": "^1.0.5",
|
||||
"gatsby-plugin-react-helmet": "^6.12.0",
|
||||
"gatsby-plugin-react-helmet-canonical-urls": "^1.4.0",
|
||||
"gatsby-plugin-react-helmet": "^6.14.0",
|
||||
"gatsby-plugin-remove-serviceworker": "^1.0.0",
|
||||
"gatsby-plugin-robots-txt": "^1.8.0",
|
||||
"gatsby-plugin-sass": "^6.12.0",
|
||||
"gatsby-plugin-sharp": "^5.12.0",
|
||||
"gatsby-plugin-sitemap": "^6.12.0",
|
||||
"gatsby-remark-autolink-headers": "^6.12.0",
|
||||
"gatsby-remark-copy-linked-files": "^6.12.0",
|
||||
"gatsby-plugin-sass": "^6.14.0",
|
||||
"gatsby-plugin-sharp": "^5.14.0",
|
||||
"gatsby-plugin-sitemap": "^6.14.0",
|
||||
"gatsby-remark-autolink-headers": "^6.14.0",
|
||||
"gatsby-remark-copy-linked-files": "^6.14.0",
|
||||
"gatsby-remark-external-links": "0.0.4",
|
||||
"gatsby-remark-images": "^7.12.0",
|
||||
"gatsby-remark-images": "^7.14.0",
|
||||
"gatsby-remark-images-medium-zoom": "^1.7.0",
|
||||
"gatsby-remark-prismjs": "^7.12.0",
|
||||
"gatsby-remark-responsive-iframe": "^6.12.0",
|
||||
"gatsby-remark-smartypants": "^6.12.0",
|
||||
"gatsby-source-filesystem": "^5.12.0",
|
||||
"gatsby-transformer-remark": "^6.12.0",
|
||||
"gatsby-transformer-sharp": "^5.12.0",
|
||||
"gatsby-remark-prismjs": "^7.14.0",
|
||||
"gatsby-remark-responsive-iframe": "^6.14.0",
|
||||
"gatsby-remark-smartypants": "^6.14.0",
|
||||
"gatsby-source-filesystem": "^5.14.0",
|
||||
"gatsby-transformer-remark": "^6.14.0",
|
||||
"gatsby-transformer-sharp": "^5.14.0",
|
||||
"prismjs": "^1.29.0",
|
||||
"react": "^18.2.0",
|
||||
"react-cookie-consent": "^8.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-cookie-consent": "^9.0.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-toggle": "^4.1.3",
|
||||
"reading-time": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/config-conventional": "^17.6.6",
|
||||
"@commitlint/cz-commitlint": "^17.5.0",
|
||||
"@jest/globals": "^29.5.0",
|
||||
"@commitlint/config-conventional": "^17.8.1",
|
||||
"@commitlint/cz-commitlint": "^19.6.1",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@mastermindzh/eslint-config": "^1.0.2",
|
||||
"@mastermindzh/prettier-config": "^1.0.0",
|
||||
"@semantic-release/exec": "6.0.3",
|
||||
"@semantic-release/git": "10.0.1",
|
||||
"@swc/core": "^1.3.67",
|
||||
"@swc/jest": "^0.2.26",
|
||||
"@types/gatsby-transformer-remark": "^2.9.1",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"@swc/core": "^1.10.4",
|
||||
"@swc/jest": "^0.2.37",
|
||||
"@types/gatsby-transformer-remark": "^2.9.4",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^22.10.3",
|
||||
"@types/react": "^18.3.18",
|
||||
"@types/react-dom": "^18.3.5",
|
||||
"@types/react-helmet": "^6.1.6",
|
||||
"@types/react-test-renderer": "^18.0.0",
|
||||
"@types/react-toggle": "^4.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"browserslist": "^4.21.9",
|
||||
"@types/react-test-renderer": "^18.3.1",
|
||||
"@types/react-toggle": "^4.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"browserslist": "^4.24.3",
|
||||
"codecov": "^3.8.3",
|
||||
"commitizen": "^4.3.0",
|
||||
"commitlint": "^17.6.6",
|
||||
"concurrently": "^8.2.0",
|
||||
"eslint": "^8.43.0",
|
||||
"commitizen": "^4.3.1",
|
||||
"commitlint": "^19.6.1",
|
||||
"concurrently": "^9.1.2",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-import-resolver-typescript": "^3.5.5",
|
||||
"eslint-import-resolver-typescript": "^3.7.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jest": "^27.2.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-jest": "^27.9.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react": "^7.37.3",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"husky": "^8.0.3",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"jest-cli": "^29.5.0",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-cli": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-svg-transformer": "^1.0.0",
|
||||
"lint-staged": "^13.2.3",
|
||||
"lost": "9.0.1",
|
||||
"markdownlint": "^0.29.0",
|
||||
"postcss": "^8.4.24",
|
||||
"postcss-scss": "^4.0.6",
|
||||
"lint-staged": "^15.3.0",
|
||||
"lost": "9.0.2",
|
||||
"markdownlint": "^0.37.3",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-scss": "^4.0.9",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-packagejson": "^2.4.3",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"rimraf": "^4.4.1",
|
||||
"sass": "^1.63.6",
|
||||
"prettier-plugin-packagejson": "^2.5.6",
|
||||
"react-test-renderer": "^18.3.1",
|
||||
"rimraf": "^6.0.1",
|
||||
"sass": "^1.83.0",
|
||||
"source-map-support": "^0.5.21",
|
||||
"standard-version": "^9.5.0",
|
||||
"stylelint": "^15.9.0",
|
||||
"stylelint-config-recommended-scss": "^9.0.1",
|
||||
"stylelint-order": "^6.0.3",
|
||||
"stylelint-scss": "^4.6.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.1.6",
|
||||
"unist-util-find": "1.0.2"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "@commitlint/cz-commitlint"
|
||||
}
|
||||
"stylelint": "^16.12.0",
|
||||
"stylelint-config-recommended-scss": "^14.1.0",
|
||||
"stylelint-order": "^6.0.4",
|
||||
"stylelint-scss": "^6.10.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.2",
|
||||
"unist-util-find": "3.0.0"
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import React from "react";
|
||||
import Helmet from "react-helmet";
|
||||
|
||||
import { useSiteMetadata } from "@/hooks";
|
||||
import { CookieBar } from "../Cookiebar/CookieBar";
|
||||
import * as styles from "./Layout.module.scss";
|
||||
import { useSiteMetadata } from "@/hooks";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
@@ -35,7 +35,7 @@ const Layout: React.FC<Props> = ({
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:site_name" content={title} />
|
||||
<meta property="og:image" content={metaImageUrl} />
|
||||
{slug && <meta property="og:url" content={`${url}${slug}`} />}
|
||||
<meta property="og:title" content={title} />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
|
@@ -9,7 +9,7 @@ const Author = () => {
|
||||
<div className={styles.author}>
|
||||
<p className={styles.bio}>
|
||||
Written by:{" "}
|
||||
<a href="/pages/about">
|
||||
<a href="/pages/about/">
|
||||
<strong>{author.name}</strong>
|
||||
</a>
|
||||
{typeof window !== "undefined" ? (
|
||||
|
@@ -6,7 +6,7 @@ exports[`Author renders correctly 1`] = `
|
||||
Written by:
|
||||
|
||||
<a
|
||||
href="/pages/about"
|
||||
href="/pages/about/"
|
||||
>
|
||||
<strong>
|
||||
Rick van Lieshout
|
||||
|
@@ -165,7 +165,7 @@ exports[`Post renders correctly 1`] = `
|
||||
Written by:
|
||||
|
||||
<a
|
||||
href="/pages/about"
|
||||
href="/pages/about/"
|
||||
>
|
||||
<strong>
|
||||
Rick van Lieshout
|
||||
|
@@ -166,7 +166,7 @@ exports[`PostTemplate renders correctly 1`] = `
|
||||
Written by:
|
||||
|
||||
<a
|
||||
href="/pages/about"
|
||||
href="/pages/about/"
|
||||
>
|
||||
<strong>
|
||||
Rick van Lieshout
|
||||
|
@@ -55,10 +55,10 @@ RewriteCond %{SERVER_PORT} ^80$
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^rickvanlieshout.com [NC]
|
||||
RewriteRule ^(.*)$ http://www.rickvanlieshout.com/$1 [L,R=301]
|
||||
RewriteRule ^(.*)$ https://www.rickvanlieshout.com/$1 [L,R=301]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^mastermindzh.com [NC]
|
||||
RewriteRule ^(.*)$ http://www.mastermindzh.com/$1 [L,R=301]
|
||||
RewriteRule ^(.*)$ https://www.mastermindzh.com/$1 [L,R=301]
|
||||
|
||||
# Optional: explicitly enable per-directory rewrites in the .htaccess context.
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"documentSigningKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPH8NJi1EDmYv6mMtd8eC9VBPDf/faGn9GV2PhSo4KtK",
|
||||
"workLaptop": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ4LSpR4wx4U/ruu5qZ7hCERSyINp2tCk6IS7cYPfKt+",
|
||||
"workLaptop": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIG5VEDMI0GkOUVjLsSLQF1mRr9UbdXF3YPIsYtqyXxj",
|
||||
"devPc": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII9hfhULcwnmtzXATxU6oqWPhTS06WXPVzx28knx9rPL"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user