Compare commits
110 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 | |||
1d9ddc82fe | |||
92245be188 | |||
98a3eb71f5 | |||
4e6b042a44 | |||
ed28488273 | |||
|
043d08e58f | ||
8c08ba1c77 | |||
|
cbaca6f4cd | ||
5eee2a07a9 | |||
|
05662d2c49 | ||
372510262b | |||
|
10cbe94397 | ||
6f9bb31ad4 | |||
8a2f19e8a9 | |||
a7a61df040 | |||
77482ba074 | |||
5ea6e0a20f | |||
26aabc9abd | |||
e6ebd5b79f | |||
bebfe1638e | |||
b5126bf051 | |||
0dc97732e8 | |||
0e9946c92e | |||
d72e30196d | |||
d6f6105841 | |||
5344b98f8e | |||
d7b82cf128 | |||
|
3ef5ca570b | ||
3a8a10c95c | |||
|
9dc1f6275f | ||
66d514d52f | |||
|
46c12f8c98 |
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
|
||||
|
15
.vscode/settings.json
vendored
@ -1,15 +1,26 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"codepen",
|
||||
"disqus",
|
||||
"fontawesome",
|
||||
"fortawesome",
|
||||
"frontmatter",
|
||||
"slsw"
|
||||
"Lieshoutt",
|
||||
"Rickvan",
|
||||
"rickvanlieshoutcom",
|
||||
"slsw",
|
||||
"soundcloud",
|
||||
"todos",
|
||||
"weibo"
|
||||
],
|
||||
"grammarly.selectors": [
|
||||
{
|
||||
"language": "markdown",
|
||||
"scheme": "file"
|
||||
}
|
||||
]
|
||||
],
|
||||
"sonarlint.connectedMode.project": {
|
||||
"connectionId": "public-sonarcloud",
|
||||
"projectKey": "Mastermindzh_rickvanlieshout.com"
|
||||
}
|
||||
}
|
||||
|
57
CHANGELOG.md
@ -2,21 +2,62 @@
|
||||
|
||||
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.2.3](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.2.2...v1.2.3) (2023-04-19)
|
||||
### [1.3.1](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.3.0...v1.3.1) (2023-10-29)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* dependency updates and the removal of hatsby-plugin-offline ([302c6d0](https://github.com/mastermindzh/rickvanlieshout.com/commits/302c6d00e2555475a7fec6a63b78146d1d502a8b))
|
||||
* 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)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* added my public keys to a keys.json file in the root of the website ([8a2f19e](https://github.com/mastermindzh/rickvanlieshout.com/commits/8a2f19e8a9abec4a3529c08cd06cf7e042e67725))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 404 on lego.com page of removed product ([0dc9773](https://github.com/mastermindzh/rickvanlieshout.com/commits/0dc97732e81458b39cccc6c100516e05f245697f))
|
||||
* added links to orphaned categories and tags pages ([0e9946c](https://github.com/mastermindzh/rickvanlieshout.com/commits/0e9946c92eb5022961a9f457ce82636a60e0e9ee))
|
||||
* added opengraph tags ([e6ebd5b](https://github.com/mastermindzh/rickvanlieshout.com/commits/e6ebd5b79f17ac41e4e1954857da8cd8ab50224a))
|
||||
* **opengraph:** added mandatory opengraph tags to all pages. Also fixed some other minor bugs ([98a3eb7](https://github.com/mastermindzh/rickvanlieshout.com/commits/98a3eb71f55c17da7964d6c5014e599a459329e1))
|
||||
* package.json & package-lock.json to reduce vulnerabilities ([9dc1f62](https://github.com/mastermindzh/rickvanlieshout.com/commits/9dc1f6275fdd1f6fe5fd9485f554345a1df268ec))
|
||||
* remove noindex and noindex follow tags ([d72e301](https://github.com/mastermindzh/rickvanlieshout.com/commits/d72e30196df5ca6944ae6dde7b4417c9efeb38d3))
|
||||
* removed nofollow links to my own website ([bebfe16](https://github.com/mastermindzh/rickvanlieshout.com/commits/bebfe1638e9ef1dc35b0b0fd6e8907edd344951f))
|
||||
* several pages linked to redirected urls. This replaces those links with the destination instead ([b5126bf](https://github.com/mastermindzh/rickvanlieshout.com/commits/b5126bf051dcdfe7159d24eb2cddeb3f8e1ceee8))
|
||||
* solve 404 on front-thumb image ([5344b98](https://github.com/mastermindzh/rickvanlieshout.com/commits/5344b98f8e37fb661a1ec70aaba1c5ef92cfa370))
|
||||
* updated npm packages and pinned unist-util-find to 1.0.2 to fix build errors ([5ea6e0a](https://github.com/mastermindzh/rickvanlieshout.com/commits/5ea6e0a20f9c8aff33a9ae18143e6f8fd3634127))
|
||||
* upgrade gatsby-plugin-image from 3.11.0 to 3.12.0 ([05662d2](https://github.com/mastermindzh/rickvanlieshout.com/commits/05662d2c492ae70575947b9327d64fa642a63698))
|
||||
* upgrade multiple dependencies with Snyk ([cbaca6f](https://github.com/mastermindzh/rickvanlieshout.com/commits/cbaca6f4cd9ba9ff290fcb2ede5a81d8c0e3f285))
|
||||
* upgrade multiple dependencies with Snyk ([10cbe94](https://github.com/mastermindzh/rickvanlieshout.com/commits/10cbe94397c43f80ff28cb5c81126fc3af632547))
|
||||
* upgrade multiple dependencies with Snyk ([3ef5ca5](https://github.com/mastermindzh/rickvanlieshout.com/commits/3ef5ca570b05e0cbc6c670eb9df179b1be1dba9c))
|
||||
* upgrade multiple dependencies with Snyk ([46c12f8](https://github.com/mastermindzh/rickvanlieshout.com/commits/46c12f8c98ab8beb7b6be040fa73761eb73b2dd9))
|
||||
|
||||
|
||||
### New content
|
||||
|
||||
* A new blog about the LegoLeague event held at INFORIT ([4e6b042](https://github.com/mastermindzh/rickvanlieshout.com/commits/4e6b042a44d9a9f5d68dba653c1472be80d21ce9))
|
||||
* **legoleague:** fixed some writing ([92245be](https://github.com/mastermindzh/rickvanlieshout.com/commits/92245be1883f7e136dae7888a64a472cf6597180))
|
||||
|
||||
### [1.2.3](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.2.2...v1.2.3) (2023-04-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* dependency updates and the removal of gatsby-plugin-offline ([302c6d0](https://github.com/mastermindzh/rickvanlieshout.com/commits/302c6d00e2555475a7fec6a63b78146d1d502a8b))
|
||||
|
||||
### [1.2.2](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.2.1...v1.2.2) (2023-04-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* .language-text not breaking on mobile ([5fe2d8e](https://github.com/mastermindzh/rickvanlieshout.com/commits/5fe2d8e834a4d7588f04e4a3b1608618253f6d52))
|
||||
|
||||
|
||||
### New content
|
||||
|
||||
* blogpost about flashing lsi 9211 cards ([ebca5f9](https://github.com/mastermindzh/rickvanlieshout.com/commits/ebca5f980d8e1a109494c5db15d2728bcfbc964b))
|
||||
@ -25,7 +66,6 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
|
||||
## [1.2.0](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.1.0...v1.2.0) (2023-02-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* added social images to the frontmatter of most blogs ([6f0fb54](https://github.com/mastermindzh/rickvanlieshout.com/commits/6f0fb545dfcbb59f677b2408622cdbc4de19325f))
|
||||
@ -33,7 +73,6 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
* removed the estranged '1' from the description of the latest blogpost ([b963241](https://github.com/mastermindzh/rickvanlieshout.com/commits/b9632410d2369e09300231e7152941d850a4f421))
|
||||
* socialImage code doesnt properly use publicURL ([561faa3](https://github.com/mastermindzh/rickvanlieshout.com/commits/561faa3a4585a73f0dc8aba63d72146dd670b544))
|
||||
|
||||
|
||||
### New content
|
||||
|
||||
* added a picture of Eddy's completed urn. Also changed my function title to Tech Lead ([c50c6fb](https://github.com/mastermindzh/rickvanlieshout.com/commits/c50c6fb9273ddd3fb180609fd977cf6d0dbbdb74))
|
||||
@ -41,14 +80,12 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
|
||||
## [1.1.0](https://github.com/mastermindzh/rickvanlieshout.com/compare/v1.0.0...v1.1.0) (2022-11-07)
|
||||
|
||||
|
||||
### New content
|
||||
|
||||
* Added a new post about adopting conventional commits ([b710c24](https://github.com/mastermindzh/rickvanlieshout.com/commits/b710c243aca703040716af52df4405a05eddd458))
|
||||
|
||||
## 1.0.0 (2022-11-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add autolink headers support ([4d38e96](https://github.com/mastermindzh/rickvanlieshout.com/commits/4d38e9633242dbf3adbd47a77c807f990be3acd8))
|
||||
@ -60,11 +97,10 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
* up version ([1c175ab](https://github.com/mastermindzh/rickvanlieshout.com/commits/1c175abff92bcf56d8809dd9caf8e16de0f4a849))
|
||||
* **workflows:** add release workflow ([25cf13a](https://github.com/mastermindzh/rickvanlieshout.com/commits/25cf13ae57084be63d8f42581b7c6b5c976930ed))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [#955](https://git.mastermindzh.tech/mastermindzh/rickvanlieshout.com/issues/955) ([6686a6c](https://github.com/mastermindzh/rickvanlieshout.com/commits/6686a6c1edc109152a80e92d684c114be9a287ab))
|
||||
* add __BASE_PATH__ to jest config ([5e00151](https://github.com/mastermindzh/rickvanlieshout.com/commits/5e00151d0b153863324194a1f1a92c88b2d8937f))
|
||||
* add **BASE_PATH** to jest config ([5e00151](https://github.com/mastermindzh/rickvanlieshout.com/commits/5e00151d0b153863324194a1f1a92c88b2d8937f))
|
||||
* add flow-typed ([b9aaa81](https://github.com/mastermindzh/rickvanlieshout.com/commits/b9aaa81ec257f48f30f1984f63b6204fc2d92b5e))
|
||||
* align the headers ([01fe350](https://github.com/mastermindzh/rickvanlieshout.com/commits/01fe35095c11b94eae34a17c64ea626d4d3cf665))
|
||||
* cannot build gatsby sitemap [#199](https://git.mastermindzh.tech/mastermindzh/rickvanlieshout.com/issues/199) ([d12a922](https://github.com/mastermindzh/rickvanlieshout.com/commits/d12a9220ddd71ebbfeadcca4736d2453f9fa17ab))
|
||||
@ -496,7 +532,6 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
* update yarn.lock ([5f23174](https://github.com/mastermindzh/rickvanlieshout.com/commits/5f231740a9472f2e5545b1611ce9af8eec40246d))
|
||||
* use aliase [#199](https://git.mastermindzh.tech/mastermindzh/rickvanlieshout.com/issues/199) ([46743e9](https://github.com/mastermindzh/rickvanlieshout.com/commits/46743e9e1ab569934bc04e9d0d4816b1c3de668f))
|
||||
|
||||
|
||||
### New content
|
||||
|
||||
* writing as an architect is hard ([027add7](https://github.com/mastermindzh/rickvanlieshout.com/commits/027add7be1b119dbeb2027497a18cd969e939e77))
|
||||
|
@ -1,8 +1,8 @@
|
||||
# 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)
|
||||
[](https://ci.mastermindzh.tech/Mastermindzh/rickvanlieshout.com)
|
||||
|
||||
## todos
|
||||
|
||||
|
@ -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 |
|
||||
|
@ -14,31 +14,39 @@
|
||||
},
|
||||
{
|
||||
"label": "About me",
|
||||
"path": "/pages/about"
|
||||
"path": "/pages/about/"
|
||||
},
|
||||
{
|
||||
"label": "Resume",
|
||||
"path": "/pages/resume"
|
||||
"path": "/pages/resume/"
|
||||
},
|
||||
{
|
||||
"label": "Contact me",
|
||||
"path": "/pages/contacts"
|
||||
"path": "/pages/contacts/"
|
||||
}
|
||||
],
|
||||
"legalMenu": [
|
||||
{
|
||||
"label": "Cookies",
|
||||
"path": "/pages/legal/cookies"
|
||||
"path": "/pages/legal/cookies/"
|
||||
},
|
||||
{
|
||||
"label": "Disclaimer",
|
||||
"path": "/pages/legal/disclaimer"
|
||||
"path": "/pages/legal/disclaimer/"
|
||||
},
|
||||
{
|
||||
"label": "Categories",
|
||||
"path": "/categories/"
|
||||
},
|
||||
{
|
||||
"label": "Tags",
|
||||
"path": "/tags/"
|
||||
}
|
||||
],
|
||||
"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",
|
||||
|
@ -41,4 +41,4 @@ All well known browser offer a way for you to revoke any cookie. Explore the lin
|
||||
|
||||
- [Deleting cookies in Chrome](https://support.google.com/chrome/answer/95647?co=GENIE.Platform%3DDesktop&hl=en)
|
||||
- [Deleting cookies in Firefox](https://support.mozilla.org/en-US/kb/delete-cookies-remove-info-websites-stored)
|
||||
- [Deleting cookies in Edge](https://privacy.microsoft.com/en-us/windows-10-microsoft-edge-and-privacy)
|
||||
- [Deleting cookies in Edge](https://support.microsoft.com/en-us/windows/microsoft-edge-browsing-data-and-privacy-bb8174ba-9d73-dcf2-9b4a-c582b4e640dd)
|
||||
|
@ -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 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
|
||||
|
||||
@ -64,6 +64,7 @@ Building an interactive and fully customizable dashboard on top of VAA's existin
|
||||
I'll list some of the training courses I've had whilst working.
|
||||
Some of these have (official) certificates, some don't, but all have brought value and knowledge.
|
||||
|
||||
- Young Executive Program (YEP) - [De Baak](https://debaak.nl/trainingen/young-executives-program)
|
||||
- Hiring & interview training ([icm.nl](https://www.icm.nl/opleidingen-en-trainingen/hrm/selectiegesprekken-voeren/))
|
||||
- Conversation techniques & de-escalation ([TIJDwinst.com](https://gesprekstechnieken.com/cursus-gesprekstechnieken/)](<https://gesprekstechnieken.com/cursus-gesprekstechnieken/>)).
|
||||
- Kubernetes (NobleProg Certification Kubernetes on Azure (AKS), 26 August 2019 - 27 August 2019)
|
||||
@ -96,7 +97,7 @@ The list below is far from complete and unordered but focuses on the skills & te
|
||||
- Teaching, coaching & presenting
|
||||
- Agile development
|
||||
- Docker, Kubernetes & CI/CD
|
||||
Event-based architecture
|
||||
- Event-based architecture
|
||||
- Reactive architecture
|
||||
- Typescript (Javascript)
|
||||
- dotnetcore
|
||||
@ -105,4 +106,4 @@ Event-based architecture
|
||||
- NoSQL (Mongo, Postgre)
|
||||
- SQL (MSSQL, Postgre, sqlite, mariadb)
|
||||
- Elasticsearch & Kibana
|
||||
- Kafka
|
||||
- Kafka / RabbitMQ
|
||||
|
@ -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"
|
||||
@ -19,7 +19,7 @@ A cluster is basically a group of computers that work together to run a very int
|
||||
|
||||
## What software are you going to use?
|
||||
|
||||
I am going to use [raspbian](http://www.raspbian.org/) for the OS and I will be using python (and [mpi4py](http://mpi4py.scipy.org/)) to program the cluster.
|
||||
I am going to use [raspbian](https://www.raspbian.org/) for the OS and I will be using python (and [mpi4py](https://mpi4py.scipy.org/)) to program the cluster.
|
||||
|
||||
## What did you need and how much did it cost
|
||||
|
||||
@ -35,9 +35,9 @@ Below you will find a list of items you would need if you were to build a 4 pi c
|
||||
|
||||
This all adds up to ( €180.43 which is $233.76 according to [google](https://www.google.nl/search?site=&source=hp&q=180.43+euro+to+dollar&oq=180.43+euro+to+dollar&gs_l=hp.3..33i21l2.879.5191.0.5287.28.24.3.1.1.0.157.1273.22j1.23.0....0...1c.1.53.hp..9.19.917.0.jex09uDmbow))
|
||||
|
||||
I ordered **some** of the stuff from a shop in china called "[banggood](http://banggood.com)". Since they deliver all around the world I will add the links to those items below.
|
||||
I ordered **some** of the stuff from a shop in china called "[banggood](https://banggood.com)". Since they deliver all around the world I will add the links to those items below.
|
||||
|
||||
- The raspberry pi cases can be found [here](http://www.banggood.com/Transparent-Box-Case-Shell-For-Raspberry-Pi-512MB-Version-p-923015.html)
|
||||
- The 8gb SD cards can be found [here](http://www.banggood.com/8GB-SD-HC-SDHC-Flash-Secure-Digital-Memory-Card-Camera-p-938458.html)
|
||||
- The USB hub can be found [here](http://www.banggood.com/Wholesale-Laptop-PC-New-Black-4-Port-Tap-USB-2_0-High-Speed-Hub-ON-Or-OFF-Sharing-Switch-p-45306.html)
|
||||
- The USB power cables can be found [here](http://www.banggood.com/Retractable-Micro-USB-Data-Sync-Charger-Cable-For-Cellphones-p-90245.html)
|
||||
- The raspberry pi cases can be found [here](https://www.banggood.com/Transparent-Box-Case-Shell-For-Raspberry-Pi-512MB-Version-p-923015.html)
|
||||
- The 8gb SD cards can be found [here](https://www.banggood.com/8GB-SD-HC-SDHC-Flash-Secure-Digital-Memory-Card-Camera-p-938458.html)
|
||||
- The USB hub can be found [here](https://www.banggood.com/Wholesale-Laptop-PC-New-Black-4-Port-Tap-USB-2_0-High-Speed-Hub-ON-Or-OFF-Sharing-Switch-p-45306.html)
|
||||
- The USB power cables can be found [here](https://www.banggood.com/Retractable-Micro-USB-Data-Sync-Charger-Cable-For-Cellphones-p-90245.html)
|
||||
|
@ -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:
|
||||
|
||||
|
Before Width: | Height: | Size: 2.5 MiB |
After Width: | Height: | Size: 243 KiB |
@ -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"
|
||||
@ -18,7 +18,7 @@ Installing an OS for a Raspberry pi is quite different from installing an OS on
|
||||
|
||||
First off, if you want to use Windows, skip this bit by clicking [here.](#windows)
|
||||
|
||||
First we will have to download the .img from the Raspbian website, we can do so by clicking [here](http://downloads.raspberrypi.org/raspbian_latest). After downloading the image we can use a kernel application known as "dd" to write the file to our SD card. We will first need to find out which /dev/ the SD card is currently using. To do this we can use the following command:
|
||||
First we will have to download the .img from the Raspbian website, we can do so by clicking [here](https://downloads.raspberrypi.org/raspbian_latest). After downloading the image we can use a kernel application known as "dd" to write the file to our SD card. We will first need to find out which /dev/ the SD card is currently using. To do this we can use the following command:
|
||||
|
||||
```bash
|
||||
lsblk
|
||||
@ -59,7 +59,7 @@ sudo kill -USR1 `pidof dd`
|
||||
|
||||
If you ended up here you have chosen to use the much inferior Windows to get Linux on your Raspberry pi's. Don't worry though, you can still install the, much superior, Linux images to your SD cards.
|
||||
|
||||
The very first thing we have to do is download the Raspbian image, which we can do by clicking [here](http://downloads.raspberrypi.org/raspbian_latest). After downloading the image we will have to download some software to write the image to the SD card. The tool we are going to use is called win32DiskImager, and can be downloaded free of charge [right here.](http://downloads.sourceforge.net/project/win32diskimager/Archive/Win32DiskImager-0.9.5-install.exe?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fwin32diskimager%2F&ts=1410459796&use_mirror=cznic)
|
||||
The very first thing we have to do is download the Raspbian image, which we can do by clicking [here](https://downloads.raspberrypi.org/raspbian_latest). After downloading the image we will have to download some software to write the image to the SD card. The tool we are going to use is called win32DiskImager, and can be downloaded free of charge [right here.](https://downloads.sourceforge.net/project/win32diskimager/Archive/Win32DiskImager-0.9.5-install.exe?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fwin32diskimager%2F&ts=1410459796&use_mirror=cznic)
|
||||
|
||||
After the tool has been downloaded (and installed) we have to start it by double clicking on the .exe file, which will leave us staring at the following tool:
|
||||
|
||||
|
@ -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"
|
||||
@ -56,7 +56,7 @@ After installing some of the required software we still have to install "mpich3"
|
||||
```bash
|
||||
mkdir /home/pi/mpich3
|
||||
cd mpich3
|
||||
wget http://www.mpich.org/static/downloads/3.0.4/mpich-3.0.4.tar.gz
|
||||
wget https://www.mpich.org/static/downloads/3.0.4/mpich-3.0.4.tar.gz
|
||||
tar xzf mpich-3.0.4.tar.gz
|
||||
sudo mkdir -p /home/rpimpi/mpich3-install
|
||||
sudo mkdir -p /home/pi/mpich_build
|
||||
|
@ -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
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 89 KiB |
@ -76,7 +76,7 @@ sudo apt-get update && sudo apt-get upgrade
|
||||
sudo pacman -Syu
|
||||
```
|
||||
|
||||
If however you're using a mac you'll have to do it by hand. Since Apple hasn't yet released an update nor commented on the matter. Instructions for a mac can be found [here](http://mac-how-to.wonderhowto.com/how-to/every-mac-is-vulnerable-shellshock-bash-exploit-heres-patch-os-x-0157606/).
|
||||
If however you're using a mac you'll have to do it by hand. Since Apple hasn't yet released an update nor commented on the matter. Instructions for a mac can be found [here](https://mac-how-to.wonderhowto.com/how-to/every-mac-is-vulnerable-shellshock-bash-exploit-heres-patch-os-x-0157606/).
|
||||
|
||||
## In summary
|
||||
|
||||
@ -84,7 +84,7 @@ So should you worry? Yes and no. If your computer (/server) is exposed to an out
|
||||
|
||||
## Documentation
|
||||
|
||||
For those of you who like to research this "Shellshock" vulnerability some more, here are 2 entries in the NVD: [CVE-2014-6271](http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271) & [CVE-2014-7169](http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-7169).
|
||||
For those of you who like to research this "Shellshock" vulnerability some more, here are 2 entries in the NVD: [CVE-2014-6271](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271) & [CVE-2014-7169](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-7169).
|
||||
|
||||
If you want to see Shellshock in action I recommend watching the following video from Quidsup:
|
||||
|
||||
|
@ -2,30 +2,30 @@
|
||||
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"
|
||||
---
|
||||
|
||||
Some of you might be wondering "why doesn't he write more blogs about the cluster?" and I wouldn't blame you. I have a pretty good reason for not blogging about the pi cluster (even though I promised sample code). That reason is "home automation". As some of you might know I'm big into home automation, and have done quite a bit already. But it's always fun to try something different!
|
||||
|
||||
I usually use single or double relay boards which you can control with an arduino or a Raspberry pi. This time however I ordered an 8 relay board instead of a double relay board. I got the board from China at a store called "Sainsmart", here's the link to the exact board I got: [http://www.sainsmart.com/8-channel-dc-5v-relay-module-for-arduino-pic-arm-dsp-avr-msp430-ttl-logic.html](http://www.sainsmart.com/8-channel-dc-5v-relay-module-for-arduino-pic-arm-dsp-avr-msp430-ttl-logic.html)
|
||||
I usually use single or double relay boards which you can control with an arduino or a Raspberry pi. This time however I ordered an 8 relay board instead of a double relay board. I got the board from China at a store called "Sainsmart", here's the link to the exact board I got: [https://www.sainsmart.com/products/8-channel-5v-relay-module](https://www.sainsmart.com/products/8-channel-5v-relay-module)
|
||||
|
||||
So what does that have to do with the cluster you ask? Well, I used to have a Raspberry pi to experiment with.... But I used that in the cluster to save some money. (here I was, thinking to be smart!) So I had to "disassemble"(taking the top off) the cluster to connect the relay board. In the next blog-post I'll have a couple of pictures showing off the relay board and the pi cluster.
|
||||
|
||||
## I donated a pi!
|
||||
## I donated a pi
|
||||
|
||||
While talking on IRC with a friend[(Robbie Ferguson)](http://baldnerd.com) of mine I discovered that he had never used a Raspberry pi before. And to make matters worse he told me he had lost interest in them now. When I asked why he never got one he told me the following:
|
||||
While talking on IRC with a friend[(Robbie Ferguson)](https://baldnerd.com) of mine I discovered that he had never used a Raspberry pi before. And to make matters worse he told me he had lost interest in them now. When I asked why he never got one he told me the following:
|
||||
|
||||
> When they were new I couldn't get one here in Canada, and now it's been so long that I've lost interest.
|
||||
|
||||
While discussing the fact he jokingly told me, if you'll send me one I'll try it out. A small problem arose though, me sending a pi to Canada would cost way more than actually buying one over there. So we decided that I'd just send him the money and he would order his own. I can't wait to see what he does with it.
|
||||
If you guys are interested in seeing what he does with it too you can check out [Category5.tv](http://www.category5.tv/)
|
||||
If you guys are interested in seeing what he does with it too you can check out [Category5.tv](https://category5.tv/)
|
||||
|
||||
What Robbie doesn't know is that I wanted to do something for the show / him anyways. I was originally planning on just donating $20, but giving him the joy that comes from owning a Raspberry pi seemed like a way better plan! Besides, he's been working really really hard on the new Studio D so he deserves some fun!
|
||||
|
||||
|
@ -43,14 +43,14 @@ Well alright then, we've got a couple of things "ready" to show others. The firs
|
||||
|
||||
We quickly decided upon changing the hub design to a more elegant "hat" (hat being a board you can attach to the Raspberry Pi, not the fedora kind). A render of one such hats can be found below.
|
||||
|
||||

|
||||

|
||||
|
||||
We also started working on the controllers. The final design will be compromised of a few "boxes" between which telephone wires run to connect them together. My fantastic soldering / glueing job on the inner workings of a controller and the laser cutted wooden box can be found below.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
@ -15,13 +15,13 @@ disqusId: "11"
|
||||
|
||||
First off, it's been a while.... I know. ☺
|
||||
|
||||
I'm trying to separate [mi-soft.nl](http://mi-soft.nl) and myself, yet keep them together somehow. I have removed almost all personal content from [mi-soft.nl](http://mi-soft.nl) and am currently busy moving it to this "personal website". The end goal is to have them completely separate apart from the "software" tab. Software that I want to reveal to the public (more so than some scripts I use myself) will still be uploaded to [mi-soft.nl](http://mi-soft.nl) and more personal projects (like [CSVtoDatabase](https://github.com/Mastermindzh/Scripts/blob/master/java/CSVtoDatabase.java)) on my [github](https://github.com/Mastermindzh/).
|
||||
I'm trying to separate [mi-soft.nl](https://mi-soft.nl) and myself, yet keep them together somehow. I have removed almost all personal content from [mi-soft.nl](https://mi-soft.nl) and am currently busy moving it to this "personal website". The end goal is to have them completely separate apart from the "software" tab. Software that I want to reveal to the public (more so than some scripts I use myself) will still be uploaded to [mi-soft.nl](https://mi-soft.nl) and more personal projects (like [CSVtoDatabase](https://github.com/Mastermindzh/Scripts/blob/master/java/CSVtoDatabase.java)) on my [github](https://github.com/Mastermindzh/).
|
||||
|
||||
In order to "keep the sites together" I have given this site the exact same look as [mi-soft.nl](http://mi-soft.nl) except for the colours. I have also made a little system that allows users to switch the website's language. Everything apart from the blog will be Multilingual. Doing all these upgrades however also means upgrading Disqus, which meant losing all my comments. While sad, I feel like it had to be done.
|
||||
In order to "keep the sites together" I have given this site the exact same look as [mi-soft.nl](https://mi-soft.nl) except for the colours. I have also made a little system that allows users to switch the website's language. Everything apart from the blog will be Multilingual. Doing all these upgrades however also means upgrading Disqus, which meant losing all my comments. While sad, I feel like it had to be done.
|
||||
|
||||
## Replacing the "about me" page on [mi-soft.nl](http://mi-soft.nl)
|
||||
## Replacing the "about me" page on [mi-soft.nl](https://mi-soft.nl)
|
||||
|
||||
I will be replacing the about me page on [mi-soft.nl](http://mi-soft.nl) with a "Linux software review" (LSR for short) section. LSR will consist of short video's (in Dutch) promoting Linux software.
|
||||
I will be replacing the about me page on [mi-soft.nl](https://mi-soft.nl) with a "Linux software review" (LSR for short) section. LSR will consist of short video's (in Dutch) promoting Linux software.
|
||||
|
||||
## Another maker project
|
||||
|
||||
@ -36,7 +36,7 @@ I have only 2 days of school left this year, (and maybe a ceremony) which means
|
||||
- Clean all my servers (both soft and hardware)
|
||||
- Finish my portfolio (in both Dutch and English)
|
||||
- Get started with LSR
|
||||
- Write at least 5 new tutorials on [mi-soft.nl](http://mi-soft.nl)
|
||||
- Write at least 5 new tutorials on [mi-soft.nl](https://mi-soft.nl)
|
||||
- Write at least 2 new blogs. (not counting this one)
|
||||
|
||||
Let's hope I can get all my planned projects done and then some.
|
||||
|
@ -35,7 +35,7 @@ After deciding to use an arduino I had another big decision to make. Should I fo
|
||||
|
||||
After that came my struggle with the drawing software. I tried creating a drawing in Coreldraw Pro.... that was... a painful experience to say the least. Then I tried drawing with a program called InkScape, while better it still didn't yield any results. Finally I decided to give up and ask for help from a friend.
|
||||
|
||||
Luckily my friend [Ron Nabuurs](http://www.ronnabuurs.nl) is brilliant when it comes to designing a drawing which can be lasercut. So after explaining my idea to [Ron](http://www.ronnabuurs.nl) he decided to help me out. A picture of what we ended up with can be found below. The source file we used can be found on git.
|
||||
Luckily my friend [Ron Nabuurs](https://www.ronnabuurs.nl) is brilliant when it comes to designing a drawing which can be lasercut. So after explaining my idea to [Ron](https://www.ronnabuurs.nl) he decided to help me out. A picture of what we ended up with can be found below. The source file we used can be found on git.
|
||||
|
||||

|
||||
|
||||
|
@ -11,7 +11,7 @@ disqusId: "16"
|
||||
socialImage: "./media/plate.jpg"
|
||||
---
|
||||
|
||||
Last friday I actually got to cut the parts for my TekTree! So excited! This is by far the biggest "piece" I have ever laser cut but luckily everything went well. This in part is thanks to my brilliant friend [Ron](http://www.ronnabuurs.nl) who helped me create the sketches for the laser cutter. Thanks again [Ron](http://www.ronnabuurs.nl)!
|
||||
Last friday I actually got to cut the parts for my TekTree! So excited! This is by far the biggest "piece" I have ever laser cut but luckily everything went well. This in part is thanks to my brilliant friend [Ron](https://www.ronnabuurs.nl) who helped me create the sketches for the laser cutter. Thanks again [Ron](https://www.ronnabuurs.nl)!
|
||||
|
||||
**Top tip!** You don't have to laser cut the designs. Just print the designs with a regular printer and stick it on some wood. Then just use something like a bandsaw to cut the pieces!
|
||||
|
||||
|
@ -11,23 +11,23 @@ disqusId: "17"
|
||||
socialImage: "./media/wiring1.jpg"
|
||||
---
|
||||
|
||||
In the 3rd part of my TekTree project I'll show you guys how to wire everything. This time I even used separate colours for the power,ground and signal wires. So no more complaining ! ^\_^ All in all I think the result looks absolutely wicked. Even without the arduino case which has yet to come in the mail. (and probably won't fit)
|
||||
In the 3rd part of my TekTree project I'll show you guys how to wire everything. This time I even used separate colours for the power, ground and signal wires. So no more complaining! ^\_^ All in all I think the result looks absolutely wicked. Even without the Arduino case which has yet to come in the mail. (and probably won't fit)
|
||||
|
||||
## Wiring part 1 - schematics
|
||||
|
||||
Before I started to jam wires in every nook and cranny I could find I had to come up with a plan. Most of that plan has been put into a "Fritzing" sketch which can be found below and on [Github](https://github.com/Mastermindzh/TekTree). The only thing I couldn't figure out how to model on fritzing is the actual christmas tree and the power cord for the arduino.
|
||||
Before I started to jam wires in every nook and cranny I could find I had to come up with a plan. Most of that plan has been put into a "Fritzing" sketch which can be found below and on [Github](https://github.com/Mastermindzh/TekTree). The only thing I couldn't figure out how to model on fritzing is the actual Christmas tree and the power cord for the Arduino.
|
||||
|
||||
The arduino will get power from a regular adaptor. The only modification I did to the adapter is putting a button on one of the wires. And the only reason I did that is because I'm too lazy to unplug the TekTree when I want to turn it off :)
|
||||
The Arduino will get power from a regular adaptor. The only modification I made to the adapter was putting a button on one of the wires. The only reason I did that is because I'm too lazy to unplug the TekTree when I want to turn it off :)
|
||||
|
||||

|
||||
|
||||
## Why so many wires?
|
||||
|
||||
I want the project to be "manageable" for everyone. To do this I kept the wiring as simple as possible. Every LED has 2 prongs, 1 goes to ground 1 goes to the arduino. Simple. Same goes for the potentiometers, 3 legs, 1 power 1 ground 1 signal. The only led's I did bundle together (in terms of wiring) is the star. I did this to create a single star instead of multiple led's.
|
||||
I want the project to be "manageable" for everyone. To do this I kept the wiring as simple as possible. Every LED has 2 prongs, 1 goes to ground 1 goes to the Arduino. Simple. Same goes for the potentiometers, 3 legs, 1 power 1 ground 1 signal. The only leds I did bundle together (in terms of wiring) is the star. I did this to create a single star instead of multiple led's.
|
||||
|
||||
## Well you could've made it way prettier... and
|
||||
|
||||
Well yes, as all of us know I'm perfectly capable of designing a [refined build](/images/blogs/han4pi/Front_thumb.png). I didn't want to go with a pcb this time however because that would make the barrier to entry way higher on this project. And that is something I definitely **don't** want.
|
||||
Well yes, as all of us know I'm perfectly capable of designing a [refined build](/images/blogs/han4pi/front.png). I didn't want to go with a pcb this time however because that would make the barrier to entry way higher on this project. And that is something I definitely **don't** want.
|
||||
|
||||
I also didn't "group" all my ground wires together. (led -> led -> led -> board) This would've made the project a lot neater but it wouldn't be anywhere near as service friendly. (which was kinda the idea...)
|
||||
|
||||
|
BIN
content/posts/2015/tektree-part-3-wiring/media/front.png
Normal file
After Width: | Height: | Size: 280 KiB |
@ -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"
|
||||
@ -13,7 +13,7 @@ disqusId: "20"
|
||||
|
||||

|
||||
|
||||
One of the final assignments for a school course called "APP" (Algorithms Programming language & Paradigms) was/is to learn a new programming language using the book "[Seven languages in Seven weeks](https://pragprog.com/book/btlang/seven-languages-in-seven-weeks)".
|
||||
One of the final assignments for a school course called "APP" (Algorithms Programming language & Paradigms) was/is to learn a new programming language using the book "[Seven languages in Seven weeks](https://pragprog.com/search/?q=seven-languages-in-seven-weeks)".
|
||||
|
||||
The idea of this book is that you can get comfortable with a programming language in just a week. As you can probably guess from the title the book covers 7 languages in total and I will be covering at least 1 (Scala).
|
||||
|
||||
|
@ -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"
|
||||
@ -21,7 +21,7 @@ While Pacman started collecting all the little dots, I took a quick look at the
|
||||
|
||||
The next message on this page tells me about a popular build tool called `sbt` so I went ahead and installed that as well.
|
||||
|
||||
The final step on this page recommends me to install "[The Scala IDE](http://scala-ide.org/?_ga=1.153666491.264179122.1490891096)" or use the IntelliJ plugin. Seeing as I adore the JetBrains product line I've opted to choose the latter.
|
||||
The final step on this page recommends me to install "[The Scala IDE](https://scala-ide.org/?_ga=1.153666491.264179122.1490891096)" or use the IntelliJ plugin. Seeing as I adore the JetBrains product line I've opted to choose the latter.
|
||||
|
||||
While browsing the downloads page I noticed Pacman had beat his level. (a.k.a collected all the dots. a.k.a the install has finished) Which means it's high time for me to continue on with the assignments.
|
||||
|
||||
@ -130,9 +130,9 @@ Day 1's theoretical questions are:
|
||||
|
||||
My answers to these are:
|
||||
|
||||
1. [http://www.scala-lang.org/api/current/](http://www.scala-lang.org/api/current/)
|
||||
1. [https://www.scala-lang.org/api/current/](https://www.scala-lang.org/api/current/)
|
||||
2. [https://www.toptal.com/scala/why-should-i-learn-scala](https://www.toptal.com/scala/why-should-i-learn-scala)
|
||||
3. [http://www.scala-lang.org/old/node/5367](http://www.scala-lang.org/old/node/5367)
|
||||
3. [https://www.scala-lang.org/old/node/5367](https://www.scala-lang.org/old/node/5367)
|
||||
|
||||
Finally, we get to move on to the practical assignment for the week. For the assignment, I have to create a "Tic-tac-toe" game for 2 players.
|
||||
|
||||
|
@ -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"
|
||||
@ -194,8 +194,8 @@ The theoretical questions for day 2 are:
|
||||
|
||||
Once again these questions are trivial if you've actually paid attention while reading the book. Anyway, here are the answers:
|
||||
|
||||
1. [http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html](http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html)
|
||||
2. [http://stackoverflow.com/questions/1812401/exactly-what-is-the-difference-between-a-closure-and-a-block](http://stackoverflow.com/questions/1812401/exactly-what-is-the-difference-between-a-closure-and-a-block)
|
||||
1. [https://docs.scala-lang.org/tutorials/scala-for-java-programmers.html](https://docs.scala-lang.org/tutorials/scala-for-java-programmers.html)
|
||||
2. [https://stackoverflow.com/questions/1812401/exactly-what-is-the-difference-between-a-closure-and-a-block](https://stackoverflow.com/questions/1812401/exactly-what-is-the-difference-between-a-closure-and-a-block)
|
||||
|
||||
The results of the second day's practical assignments can found on [Github](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/tree/master/Scala/Day%202/src/myApp) or below:
|
||||
|
||||
|
@ -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"
|
||||
@ -133,7 +133,7 @@ Finally! We get to do something with concurrency, now Scala can really show me w
|
||||
|
||||
The book starts off by telling me about Actors, which have pools of threads and queues, and message passing. When you send a message (using the ! operator) you place an object on its queue. The actor then reads the message and takes action. Usually, the actor uses a pattern matcher to detect what it has to do before it starts doing something.
|
||||
|
||||
The book provides a sample application but that plain doesn't work. Upon investigating the issue I discovered that Scala's built-in concurrency feature is deprecated in favour of [Akka](http://akka.io/). This saddens me beyond belief. I have already worked with Akka and had expected Scala to offer me something else. This also means that the rest of the book is not going to be useful anymore.
|
||||
The book provides a sample application but that plain doesn't work. Upon investigating the issue I discovered that Scala's built-in concurrency feature is deprecated in favour of [Akka](https://akka.io/). This saddens me beyond belief. I have already worked with Akka and had expected Scala to offer me something else. This also means that the rest of the book is not going to be useful anymore.
|
||||
|
||||
Stubborn as I am, even with a closing deadline, I decided I wasn't going to let a stupid book stop me and decided to update the code to work with Akka. All of which can be found at [Github](https://github.com/Mastermindzh/Seven-Languages-in-Seven-Weeks/tree/master/Scala/Day%203/src/Concurrency).
|
||||
|
||||
|
@ -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,19 +2,19 @@
|
||||
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"
|
||||
---
|
||||
|
||||
At my place of work, [INFORIT](http://inforit.nl/), we are talking about adopting conventional commits as a company standard.
|
||||
At my place of work, [INFORIT](https://inforit.nl/), we are talking about adopting conventional commits as a company standard.
|
||||
However... debating commits is a tricky endeavor, everyone seems to have their own opinion about it and pretty much no one is following even the basic git rules (e.g title + body). It is precisely because of all of this that an earlier proposal about standardizing commit messages brought us nothing.
|
||||
|
||||
Now though, a solid 2 years later, our company has grown tremendously!
|
||||
@ -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
|
||||
|
@ -10,7 +10,7 @@ tags:
|
||||
description: "Good software design practices and a few perfectionistic tendencies lead to almost 5 years without any writing. This post is a deep dive into a few of the struggles of the past 5 years"
|
||||
---
|
||||
|
||||
I've been rebuilding the old "[rickvanlieshout.com](https://rickvanlieshout.com)" for over 5 years now...
|
||||
I've been rebuilding the old "[rickvanlieshout.com](https://www.rickvanlieshout.com)" for over 5 years now...
|
||||
But the website isn't that big. It could be done way faster and it has been done way faster.
|
||||
The thing is, I rewrote it several times, each time with a different design and updated packages.
|
||||
|
||||
|
@ -2,16 +2,16 @@
|
||||
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
|
||||
socialImage: ./media/flash-result.jpg
|
||||
---
|
||||
|
||||
|
||||
|
98
content/posts/2023/lego-league/index.md
Normal file
@ -0,0 +1,98 @@
|
||||
---
|
||||
title: LegoLeague - Battling it out with little robots made from Lego
|
||||
date: "2023-09-18"
|
||||
template: "post"
|
||||
category: "Lego"
|
||||
tags:
|
||||
- "lego"
|
||||
- "spike"
|
||||
- "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
|
||||
---
|
||||
|
||||

|
||||
|
||||
A little before the start of the summer period my colleague Jan-Kees came up to me and proposed the idea of an internal LegoLeague. After a little bit of back-and-forth about what LegoLeague exactly was I agreed it would be a great idea to bring some colleagues together and have a little fun during work hours.
|
||||
Pretty much right away excitement got the better of us and we started drafting a plan... when? where? how? prizes? teams!?? A lot.
|
||||
But First...
|
||||
|
||||
## What is LegoLeague?
|
||||
|
||||
LegoLeague is an event where teams come together to build, program and test a [Lego Spike robot](https://www.lego.com/en-nl/product/lego-education-spike-prime-set-45678) to perform autonomous tasks. The tasks range from collecting "power cores", pushing or pulling levers, to dropping Lego blocks in a hopper to get some bonus points.
|
||||
|
||||
All of this is accompanied by a theme, in our case energy production, which adds a layer of fun to solving these challenges.
|
||||
The video below shows a teaser of 2022-2023's "SuperPowered" event, the very thing we based our LegoLeague on:
|
||||
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/okR1AMFNV3Q?si=cq4KqyVVK6sAsCpY"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
|
||||
For each task a team completes successfully they will score points.
|
||||
Teams get 2 minutes and 30 seconds (2:30) to score as many points as they can.
|
||||
The video below outlines some of the challenges the teams have available to them with a little explanation of how they function and even some info on the scores. This video is especially useful for teams that don't want to peruse the entire rule book but still wanted to figure out an optimal strategy.
|
||||
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/ILTjo0LHZQA?si=YqJvSYX3JNclPPeJ"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
allowfullscreen>
|
||||
</iframe>
|
||||
|
||||
To build the robot each team gets a [Lego Spike Prime set](https://www.lego.com/nl-nl/product/lego-education-spike-prime-set-45678) and nothing more!
|
||||
In the original event, teams had access to a little more Lego in various kits but for our little event at [INFORIT](https://inforit.nl), we were only able to source the basic kits in time.
|
||||
Having said that, we wouldn't have been able to get our hands on any of the kits at all if it wasn't for the ["PReT" organization in Weesp](https://www.pretweesp.nl/). Thanks guys!
|
||||
|
||||

|
||||
|
||||
As for the programming... Teams are free to use either "[scratch](https://scratch.mit.edu/)" or "Python" to program their robots.
|
||||
Scratch being much easier for those who don't spend all day behind their computer working on software development whilst Python allows for more flexibility in what can be achieved.
|
||||
Spoiler alert: all teams chose scratch, it's much more accessible for non-developers!
|
||||
|
||||
## The competition at INFORIT
|
||||
|
||||
So yeah, we now know what a LegoLeague is and we have the approval to host the competition at [INFORIT](https://inforit.nl), now what?
|
||||
Well, Jan-Kees got to work building the arena and setting it up and I set out to gather team members. Given that it was the summer break I had to hustle to get teams together but eventually we managed to create some beautiful teams.
|
||||
|
||||
Fortunately, [INFORIT](https://inforit.nl) values employee happiness, autonomy and continuous improvement. As such I was able to offer the 2 Friday afternoons free of day-to-day work, to work on the robot whilst providing catering, music, and the like to the teams whilst they are participating!
|
||||
|
||||
In the end, we were successful in creating 4 teams of at least 3 people who were all mixed with developers and non-developers to keep the balance fair. Meanwhile, Jan-Kees also finished building the arena which you can see in the header of this blog or the pictures in the picture section.
|
||||
|
||||
## Pictures
|
||||
|
||||
Of course, we've taken loads of pictures during the event but those are mostly for internal use.
|
||||
Below I've included some pictures of the event that are all cleared for social media distribution with a little description of what's happening in each picture to, hopefully, convey some of the vibes of the event itself.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Winners, losers, etc
|
||||
|
||||
In the end, this is still a competition. People competed hard to come out on top and 1 team did so successfully.
|
||||
Congratulations guys!
|
||||
|
||||
")
|
||||
|
||||
## Nah, we are all winners in the end
|
||||
|
||||
Having 4 teams gave us the unique opportunity to reward them all with something nice. The 3 teams that got podium places all got their medals and their rewards and the team in fourth place got their consolation prize.
|
||||
|
||||
Luckily though, we're all winners, even the Jury members and the organizers.
|
||||
This event has brought us all closer together and improved the connection between our colleagues.
|
||||
I, personally, had a blast and would love to do similar things in the future.
|
||||
|
||||
That's it again, thanks for reading and see you next time!
|
BIN
content/posts/2023/lego-league/media/board.jpg
Normal file
After Width: | Height: | Size: 4.4 MiB |
BIN
content/posts/2023/lego-league/media/complicated.png
Normal file
After Width: | Height: | Size: 284 KiB |
BIN
content/posts/2023/lego-league/media/lego-spike-set.png
Normal file
After Width: | Height: | Size: 297 KiB |
BIN
content/posts/2023/lego-league/media/lex-counting.jpg
Normal file
After Width: | Height: | Size: 3.8 MiB |
BIN
content/posts/2023/lego-league/media/robot-warrior.jpg
Normal file
After Width: | Height: | Size: 3.9 MiB |
BIN
content/posts/2023/lego-league/media/testing-coding-repeat.jpg
Normal file
After Width: | Height: | Size: 4.2 MiB |
BIN
content/posts/2023/lego-league/media/winners.jpg
Normal file
After Width: | Height: | Size: 4.4 MiB |
@ -4,10 +4,10 @@ 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
|
||||
socialImage: ./media/building-the-owl.jpg
|
||||
---
|
||||
|
||||
## The problem
|
||||
@ -47,8 +47,8 @@ I emptied a shelf, picked up some [white base plates](https://www.lego.com/en-us
|
||||
- [Holiday main street](https://www.lego.com/en-us/product/holiday-main-street-10308)
|
||||
- [Santa's sleigh](https://www.lego.com/en-nl/product/santa-s-sleigh-40499)
|
||||
- [Santa's visit](https://www.lego.com/en-nl/product/santa-s-visit-10293)
|
||||
- [Winter elve's scene](https://www.lego.com/en-nl/product/winter-elves-scene-40564)
|
||||
- [Winter polar bears](https://www.lego.com/en-us/product/wintertime-polar-bears-40571)
|
||||
- [Winter elves scene](https://www.lego.com/en-nl/product/winter-elves-scene-40564)
|
||||
- [Winter polar bears](https://web.archive.org/web/20221106002040/https://www.lego.com/en-us/product/wintertime-polar-bears-40571)
|
||||
- [Santa's workshop](https://www.lego.com/en-nl/product/santa-s-workshop-40565?CMP=AFC-AffiliateUK-lFWN%2FyX1zOg-3425491-124738-1)
|
||||
|
||||
The result of a few days of work and the Christmas village has been completed:
|
||||
|
@ -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.
|
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
@ -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,14 +164,7 @@ export default {
|
||||
start_url: "/",
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: "gatsby-plugin-react-helmet-canonical-urls",
|
||||
options: {
|
||||
siteUrl: config.url,
|
||||
stripQueryString: true,
|
||||
},
|
||||
},
|
||||
// remove the old serviceworker if it is available.
|
||||
// remove the old service worker if it is available.
|
||||
"gatsby-plugin-remove-serviceworker",
|
||||
"gatsby-plugin-image",
|
||||
"gatsby-plugin-catch-links",
|
||||
|
@ -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/" },
|
||||
];
|
||||
|
@ -4,7 +4,7 @@ import menu from "./menu";
|
||||
export default {
|
||||
site: {
|
||||
siteMetadata: {
|
||||
url: "https://rickvanlieshout.com",
|
||||
url: "https://www.rickvanlieshout.com",
|
||||
title: "Rick van Lieshout ~ Mastermindzh",
|
||||
subtitle: "The thoughts, discoveries and murmurings of a Software enthusiast",
|
||||
copyright: "All rights reserved.",
|
||||
|
53152
package-lock.json
generated
168
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rickvanlieshout-com",
|
||||
"version": "1.2.3",
|
||||
"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,114 +48,114 @@
|
||||
"npm run format:scss"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "@commitlint/cz-commitlint"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"classnames": "^2.3.2",
|
||||
"disqus-react": "^1.1.5",
|
||||
"gatsby": "^5.8.1",
|
||||
"gatsby-link": "^5.8.0",
|
||||
"gatsby-plugin-catch-links": "^5.8.0",
|
||||
"gatsby-plugin-feed": "^5.8.0",
|
||||
"gatsby-plugin-google-gtag": "^5.8.0",
|
||||
"gatsby-plugin-image": "^3.8.0",
|
||||
"gatsby-plugin-manifest": "^5.8.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.1",
|
||||
"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.8.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.8.0",
|
||||
"gatsby-plugin-sharp": "^5.8.1",
|
||||
"gatsby-plugin-sitemap": "^6.8.0",
|
||||
"gatsby-remark-autolink-headers": "^6.8.0",
|
||||
"gatsby-remark-copy-linked-files": "^6.8.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.8.0",
|
||||
"gatsby-remark-images": "^7.14.0",
|
||||
"gatsby-remark-images-medium-zoom": "^1.7.0",
|
||||
"gatsby-remark-prismjs": "^7.8.0",
|
||||
"gatsby-remark-responsive-iframe": "^6.8.0",
|
||||
"gatsby-remark-smartypants": "^6.8.0",
|
||||
"gatsby-source-filesystem": "^5.8.0",
|
||||
"gatsby-transformer-remark": "^6.8.0",
|
||||
"gatsby-transformer-sharp": "^5.8.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.1",
|
||||
"@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.51",
|
||||
"@swc/jest": "^0.2.26",
|
||||
"@types/gatsby-transformer-remark": "^2.9.1",
|
||||
"@types/jest": "^29.5.0",
|
||||
"@types/node": "^18.15.11",
|
||||
"@types/react": "^18.0.37",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@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.59.0",
|
||||
"@typescript-eslint/parser": "^5.59.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"browserslist": "^4.21.5",
|
||||
"@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.1",
|
||||
"concurrently": "^7.6.0",
|
||||
"eslint": "^8.38.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.3",
|
||||
"eslint-import-resolver-typescript": "^3.7.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"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.1",
|
||||
"lost": "9.0.1",
|
||||
"markdownlint": "^0.28.1",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss-scss": "^4.0.6",
|
||||
"prettier": "^2.8.7",
|
||||
"prettier-plugin-packagejson": "^2.4.3",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"rimraf": "^4.4.1",
|
||||
"sass": "^1.62.0",
|
||||
"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.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.5.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.0.4"
|
||||
},
|
||||
"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,5 +1,5 @@
|
||||
/**
|
||||
* GHColors theme by Avi Aryan (http://aviaryan.in)
|
||||
* GHColors theme by Avi Aryan (https://aviaryan.in)
|
||||
* Inspired by Github syntax coloring
|
||||
*/
|
||||
[data-theme="light"] {
|
||||
|
@ -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;
|
||||
@ -11,6 +11,7 @@ interface Props {
|
||||
socialImage?: string;
|
||||
children: React.ReactNode;
|
||||
noIndex?: boolean;
|
||||
slug?: string;
|
||||
}
|
||||
|
||||
const Layout: React.FC<Props> = ({
|
||||
@ -19,6 +20,7 @@ const Layout: React.FC<Props> = ({
|
||||
description,
|
||||
socialImage = "",
|
||||
noIndex = false,
|
||||
slug,
|
||||
}: Props) => {
|
||||
const { author, url } = useSiteMetadata();
|
||||
const metaImage = socialImage || author.photo;
|
||||
@ -30,12 +32,15 @@ const Layout: React.FC<Props> = ({
|
||||
<html lang="en" />
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:site_name" content={title} />
|
||||
<meta property="og:image" content={metaImageUrl} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={metaImageUrl} />
|
||||
<meta property="twitter:site" content="@mastermindzh" />
|
||||
{noIndex && <meta name="robots" content="noindex" />}
|
||||
</Helmet>
|
||||
{children}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
|
||||
import * as styles from "./Page.module.scss";
|
||||
import type { Nullable } from "@/types";
|
||||
|
||||
import { Helmet } from "react-helmet";
|
||||
import * as styles from "./Page.module.scss";
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
@ -19,12 +19,17 @@ const Page: React.FC<Props> = ({ title, children }: Props) => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={pageRef} className={styles.page}>
|
||||
<div className={styles.inner}>
|
||||
{title && <h1 className={styles.title}>{title}</h1>}
|
||||
<div className={styles.body}>{children}</div>
|
||||
<>
|
||||
<Helmet>
|
||||
<meta property="og:type" content="website" />
|
||||
</Helmet>
|
||||
<div ref={pageRef} className={styles.page}>
|
||||
<div className={styles.inner}>
|
||||
{title && <h1 className={styles.title}>{title}</h1>}
|
||||
<div className={styles.body}>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,5 +1,7 @@
|
||||
import type { Node } from "@/types";
|
||||
import React from "react";
|
||||
import { Helmet } from "react-helmet";
|
||||
import { useSiteMetadata } from "../../hooks";
|
||||
import { Author } from "./Author";
|
||||
import { Comments } from "./Comments";
|
||||
import { Content } from "./Content";
|
||||
@ -14,24 +16,34 @@ interface Props {
|
||||
const Post: React.FC<Props> = ({ post }: Props) => {
|
||||
const { html } = post;
|
||||
const { tagSlugs, slug, readingTime } = post.fields;
|
||||
const { tags, title, date, disqusId } = post.frontmatter;
|
||||
const { tags, title, date, disqusId, category } = post.frontmatter;
|
||||
const { url } = useSiteMetadata();
|
||||
|
||||
return (
|
||||
<div className={styles.post}>
|
||||
<div className={styles.content}>
|
||||
<Content body={html} title={title} subTitle={readingTime?.text} />
|
||||
</div>
|
||||
<>
|
||||
<Helmet>
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="article:publisher" content={url} />
|
||||
<meta property="article:section" content={category} />
|
||||
<meta property="article:tag" content={tags ? tags[0] : ""} />
|
||||
</Helmet>
|
||||
|
||||
<div className={styles.footer}>
|
||||
<Meta date={date} />
|
||||
{tags && tagSlugs && <Tags tags={tags} tagSlugs={tagSlugs} />}
|
||||
<Author />
|
||||
</div>
|
||||
<div className={styles.post}>
|
||||
<div className={styles.content}>
|
||||
<Content body={html} title={title} subTitle={readingTime?.text} />
|
||||
</div>
|
||||
|
||||
<div className={`${styles.comments} hideInPrintView`}>
|
||||
<Comments disqusId={disqusId} postSlug={slug} postTitle={post.frontmatter.title} />
|
||||
<div className={styles.footer}>
|
||||
<Meta date={date} />
|
||||
{tags && tagSlugs && <Tags tags={tags} tagSlugs={tagSlugs} />}
|
||||
<Author />
|
||||
</div>
|
||||
|
||||
<div className={`${styles.comments} hideInPrintView`}>
|
||||
<Comments disqusId={disqusId} postSlug={slug} postTitle={post.frontmatter.title} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -165,7 +165,7 @@ exports[`Post renders correctly 1`] = `
|
||||
Written by:
|
||||
|
||||
<a
|
||||
href="/pages/about"
|
||||
href="/pages/about/"
|
||||
>
|
||||
<strong>
|
||||
Rick van Lieshout
|
||||
|
@ -6,7 +6,6 @@ import { ICONS } from "@/constants";
|
||||
import { Dictionary } from "@/types";
|
||||
import { getContactHref, getIcon } from "@/utils";
|
||||
|
||||
|
||||
type Props = {
|
||||
contacts: Dictionary<string>;
|
||||
};
|
||||
@ -26,8 +25,13 @@ const Contacts: React.FC<Props> = ({ contacts }: Props) => (
|
||||
<Icon name={name} icon={getIcon(name)} />
|
||||
</a>
|
||||
</li>
|
||||
) : null,
|
||||
) : null
|
||||
)}
|
||||
<li className={styles.item} key="keys">
|
||||
<a className={styles.link} href="/keys.json" rel="noopener noreferrer" target="_blank">
|
||||
<Icon name="keys" icon={getIcon("keys")} />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
@ -93,6 +93,24 @@ exports[`Contacts renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
|
@ -138,6 +138,24 @@ exports[`Sidebar renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -63,6 +63,10 @@ const ICONS = {
|
||||
path: "M3.6,7.8 C5,10.6 7.4,12.9 10.2,14.4 L12.4,12.2 C12.7,11.9 13.1,11.8 13.4,12 C14.5,12.4 15.7,12.6 17,12.6 C17.6,12.6 18,13 18,13.6 L18,17 C18,17.6 17.6,18 17,18 C7.6,18 0,10.4 0,1 C0,0.4 0.4,0 1,0 L4.5,0 C5.1,0 5.5,0.4 5.5,1 C5.5,2.2 5.7,3.4 6.1,4.6 C6.2,4.9 6.1,5.3 5.9,5.6 L3.6,7.8 L3.6,7.8 Z",
|
||||
viewBox: "0 0 18 18",
|
||||
},
|
||||
keys: {
|
||||
path: "M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z",
|
||||
viewBox: "0 0 20 20",
|
||||
},
|
||||
};
|
||||
|
||||
export default ICONS;
|
||||
|
@ -13,7 +13,7 @@ const CategoriesTemplate: React.FC = () => {
|
||||
const categories = useCategoriesList();
|
||||
|
||||
return (
|
||||
<Layout title={`Categories - ${title}`} description={subtitle}>
|
||||
<Layout title={`Categories - ${title}`} description={subtitle} slug="/categories/">
|
||||
<Sidebar />
|
||||
<Page title="Categories">
|
||||
<ul>
|
||||
|
@ -139,6 +139,24 @@ exports[`CategoriesTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -28,7 +28,7 @@ const CategoryTemplate: React.FC<Props> = ({ data, pageContext }: Props) => {
|
||||
currentPage > 0 ? `${group} - Page ${currentPage} - ${siteTitle}` : `${group} - ${siteTitle}`;
|
||||
|
||||
return (
|
||||
<Layout title={pageTitle} description={siteSubtitle}>
|
||||
<Layout title={pageTitle} description={siteSubtitle} slug={`/category/${group}/`}>
|
||||
<Sidebar />
|
||||
<Page title={group}>
|
||||
<Feed edges={edges} />
|
||||
|
@ -139,6 +139,24 @@ exports[`CategoryTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -26,7 +26,7 @@ const IndexTemplate: React.FC<Props> = ({ data, pageContext }: Props) => {
|
||||
const pageTitle = currentPage > 0 ? `Posts - Page ${currentPage} - ${siteTitle}` : siteTitle;
|
||||
|
||||
return (
|
||||
<Layout title={pageTitle} description={siteSubtitle}>
|
||||
<Layout title={pageTitle} description={siteSubtitle} slug="">
|
||||
<Sidebar isIndex />
|
||||
<Page>
|
||||
<Feed edges={edges} />
|
||||
|
@ -139,6 +139,24 @@ exports[`IndexTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -10,7 +10,7 @@ const NotFoundTemplate: React.FC = () => {
|
||||
const { title, subtitle } = useSiteMetadata();
|
||||
|
||||
return (
|
||||
<Layout title={`Not Found - ${title}`} description={subtitle}>
|
||||
<Layout title={`Not Found - ${title}`} description={subtitle} slug="/404.html">
|
||||
<Sidebar />
|
||||
<Page title="Oh no! page be lost">
|
||||
<p>
|
||||
|
@ -139,6 +139,24 @@ exports[`NotFoundTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -26,6 +26,7 @@ const PageTemplate: React.FC<Props> = ({ data }: Props) => {
|
||||
title={`${title} - ${siteTitle}`}
|
||||
description={metaDescription}
|
||||
socialImage={socialImage?.publicURL}
|
||||
slug={data.markdownRemark.fields.slug}
|
||||
>
|
||||
<Sidebar />
|
||||
<Page title={title}>
|
||||
@ -40,6 +41,9 @@ export const query = graphql`
|
||||
markdownRemark(fields: { slug: { eq: $slug } }) {
|
||||
id
|
||||
html
|
||||
fields {
|
||||
slug
|
||||
}
|
||||
frontmatter {
|
||||
title
|
||||
date
|
||||
|
@ -139,6 +139,24 @@ exports[`PageTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -24,6 +24,7 @@ const PostTemplate: React.FC<Props> = ({ data }: Props) => {
|
||||
title={`${title} - ${siteTitle}`}
|
||||
description={metaDescription}
|
||||
socialImage={socialImage?.publicURL}
|
||||
slug={data.markdownRemark.fields.slug}
|
||||
>
|
||||
<Post post={data.markdownRemark} />
|
||||
</Layout>
|
||||
|
@ -166,7 +166,7 @@ exports[`PostTemplate renders correctly 1`] = `
|
||||
Written by:
|
||||
|
||||
<a
|
||||
href="/pages/about"
|
||||
href="/pages/about/"
|
||||
>
|
||||
<strong>
|
||||
Rick van Lieshout
|
||||
|
@ -28,7 +28,7 @@ const TagTemplate: React.FC<Props> = ({ data, pageContext }: Props) => {
|
||||
currentPage > 0 ? `${group} - Page ${currentPage} - ${siteTitle}` : `${group} - ${siteTitle}`;
|
||||
|
||||
return (
|
||||
<Layout title={pageTitle} description={siteSubtitle} noIndex>
|
||||
<Layout title={pageTitle} description={siteSubtitle} slug={`/tag/${group}/`}>
|
||||
<Sidebar />
|
||||
<Page title={group}>
|
||||
<Feed edges={edges} />
|
||||
|
@ -139,6 +139,24 @@ exports[`TagTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -13,7 +13,7 @@ const TagsTemplate: React.FC = () => {
|
||||
const tags = useTagsList();
|
||||
|
||||
return (
|
||||
<Layout title={`Tags - ${title}`} description={subtitle}>
|
||||
<Layout title={`Tags - ${title}`} description={subtitle} slug="/tags/">
|
||||
<Sidebar />
|
||||
<Page title="Tags">
|
||||
<ul>
|
||||
|
@ -139,6 +139,24 @@ exports[`TagsTemplate renders correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="/keys.json"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<title>
|
||||
keys
|
||||
</title>
|
||||
<path
|
||||
d="M15 6a1.54 1.54 0 0 1-1.5-1.5 1.5 1.5 0 0 1 3 0A1.54 1.54 0 0 1 15 6zm-1.5-5A5.55 5.55 0 0 0 8 6.5a6.81 6.81 0 0 0 .7 2.8L1 17v2h4v-2h2v-2h2l3.2-3.2a5.85 5.85 0 0 0 1.3.2A5.55 5.55 0 0 0 19 6.5 5.55 5.55 0 0 0 13.5 1z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -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
static/.well-known/org.flathub.VerifiedApps.txt
Normal file
@ -0,0 +1 @@
|
||||
ac4c4068-88f8-4291-9180-894c0391fed8
|
5
static/keys.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"documentSigningKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPH8NJi1EDmYv6mMtd8eC9VBPDf/faGn9GV2PhSo4KtK",
|
||||
"workLaptop": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIG5VEDMI0GkOUVjLsSLQF1mRr9UbdXF3YPIsYtqyXxj",
|
||||
"devPc": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII9hfhULcwnmtzXATxU6oqWPhTS06WXPVzx28knx9rPL"
|
||||
}
|