Showing posts with label svelte. Show all posts
Showing posts with label svelte. Show all posts
Saturday, 28 March 2026
Home-lab design (2026 edition) part 2 - Inside the NUC
Following on from last-month's look at the [physical boxes that make up my home "lab"](https://blog.themillhousegroup.com/2026/02/home-lab-design-pt1-physical-boxes.html) in 2026, there's only one box that actually deserves any deeper inspection; the Intel NUC5PGYH, an incredibly-lucky hard-rubbish find from a few years back that, after sourcing a suitable 19V (i.e. laptop) power supply, de-Windows-ing, and most recently, a RAM doubling (at the princely cost of $25) to 8Gb, has proven itself to be an ideal platform for various x86-based experimentation.
Up until last month, the NUC has been running Debian Bookworm, keeping up my long-standing tradition of using Debian-based Linux for my home servers. The primary applications running on this box before 2026 were [_Home Assistant_](https://www.home-assistant.io/) via the [packaged-up `haos.qcow2` virtual machine image](https://www.home-assistant.io/installation/linux/#install-home-assistant-operating-system), the excellent [_OctoPrint_](https://octoprint.org/) for [3D printer](https://blog.themillhousegroup.com/search/label/3dprinting) monitoring, the [_BrickSync_](https://bricksync.net/) inventory-management software that keeps multiple [online LEGO parts stores](https://blog.themillhousegroup.com/2024/06/home-cooked-and-delicious.html) in sync, and various self-written node.js-based webapps that aren't suitable for public hosting on the otherwise-brilliant (and free) [Netlify](https://www.netlify.com/) platform.
HAOS runs as a VM, which was fairly easy to get going following the instructions as linked above, and pretty-much looks after itself. OctoPrint, being a "proper" solution, runs properly as a system service; the latter apps I'd run fairly erratically using `screen` sessions. Finally, after a particularly annoying festival of `screen`-cursing and port-interfering, I'd had enough. The SvelteKit apps I prefer these days are [fairly trivial to Dockerise](https://khromov.se/dockerizing-your-sveltekit-applications-a-practical-guide/), and I've spent enough time with Docker in my work life to appreciate the true segregation and repeatability that it brings - "cattle, not pets". And thus so began a new phase - transforming the NUC into a more-appropriate host for these "workloads".
### Moving it all over
After carefully tidying up the home directory of the Debian installation (which featured the usual assortment of scripts, Github clones and random downloaded files), it was time to say goodbye. My new OS for the NUC is [Proxmox VE](https://www.proxmox.com/en/products/proxmox-virtual-environment/overview), which is still Debian-based underneath, so I guess my run continues. I liked the idea of completely installing from scratch, and having the absolute thinnest layer possible between the VM workloads and the bare metal. It certainly shows in Proxmox's boot time, which is extremely impressive; no starting desktops or initializing sound systems here - just straight down to business!
The conceptual layout of the VMs inside Proxmox is also refreshingly simple:
```mermaid
architecture-beta
group prox(affinity:server)[Proxmox VE]
service ahaos(affcircle:c-house-blue)[HAOS 100] in prox
service zdocker(affcircle:c-nas-blue)[Docker 101] in prox
```
That's it. _Everything_ that's not Home Assistant will be run as a Docker container inside VM 101.
Moving the `HAOS` image (that I'd backed up over to my NAS, simply by stopping the VM and copying the `haos.qcow2` file) was easy, courtesy of this excellent [step-by-step guide](https://forum.proxmox.com/threads/guide-install-home-assistant-os-in-a-vm.143251/). With `haos.qcow2` safely copied into your Proxmox `local` storage, you can install it like this in the main Shell:
```
root@nuc:/home# qm importdisk 100 /var/lib/vz/import/haos.qcow2 local-lvm
importing disk '/var/lib/vz/import/haos.qcow2' to VM 100 ...
Logical volume "vm-100-disk-1" created.
Logical volume pve/vm-100-disk-1 changed.
transferred 0.0 B of 32.0 GiB (0.00%)
transferred 327.7 MiB of 32.0 GiB (1.00%)
transferred 655.4 MiB of 32.0 GiB (2.00%)
...
```
Now for *Docker*, there are many opinions about the best way to run it, but I like an easy life, so another VM is my choice. I already had a `docker.qcow2` image, which runs a super-slim _Alpine Linux_ host OS, [just enough to host Docker](https://wiki.alpinelinux.org/wiki/Docker), so we do it all again. Exactly the same. Cattle, not pets ;-)
```
root@nuc:~# qm importdisk 101 /var/lib/vz/import/docker.qcow2 local-lvm
importing disk '/var/lib/vz/import/docker.qcow2' to VM 101 ...
Logical volume "vm-101-disk-1" created.
Logical volume pve/vm-101-disk-1 changed.
transferred 0.0 B of 32.0 GiB (0.00%)
transferred 331.0 MiB of 32.0 GiB (1.01%)
transferred 665.2 MiB of 32.0 GiB (2.03%)
transferred 996.1 MiB of 32.0 GiB (3.04%)
transferred 1.3 GiB of 32.0 GiB (4.06%)
```
### Final touches (USB device mapping)
I have a couple of USB devices that hang off the NUC, and Proxmox VE has actually substantially improved my quality-of-life with its device-ID-specific mapping which means even if a device is power-cycled (as happens all the time with the 3D printer; it's too noisy to leave on) it still remains consistently available to the consuming applications. Under Debian, such a device would appear as a new `bus:device` pair every time, causing havoc.
#### Mapping the Sonoff Zigbee dongle through to the `haos` VM:
#### Mapping the 3D printer through to the `docker` VM:
Labels:
3dprinting,
alpine,
containerization,
debian,
docker,
haos,
homeassistant,
homeautomation,
homelab,
markdown-enabled,
nuc,
octoprint,
proxmox,
proxmoxve,
qcow2,
svelte,
sveltekit,
usb
Saturday, 3 January 2026
2026 - Off we go again
Happy New Year!
After some refreshing time off I'm looking to refresh my "home lab" with some self-hosted projects, so this is likely to be a big focus of this year's posts.
Of course, as much as possible I'm still [doing](https://blog.themillhousegroup.com/2023/09/frenzyjs-saga-of-flood-fill.html) [projects](https://blog.themillhousegroup.com/2022/06/introducing-cardle.html) "out in the open" and hosting them on [Netlify](https://www.netlify.com), whose [SvelteKit](https://svelte.dev/docs/kit/introduction) [integration](https://svelte.dev/docs/kit/adapter-netlify) is still the smoothest and easiest way to get a modern, public-facing website that I've found.
But for situations where full public access isn't appropriate, I've been experimenting with [Dockerization of Svelte apps](https://khromov.se/dockerizing-your-sveltekit-applications-a-practical-guide/) and self-hosted Docker and I'm liking what I'm seeing.
More to come.
Sunday, 28 September 2025
The fascinating intersection of SVG and Svelte
## The context
I'm working on a new top-secret web project that had some interesting graphical requirements:
- Tileable images that scale to fit the entire device viewport
- Support rotation in 4 steps (N,S,E,W)
- Support overlaying
- Support filling in distinct steps
- Support theming; i.e. be able to draw the images using (at least) a "light" and "dark" variant
Pretty steep requirements, and once I realised the final two requirements were non-optional, PNGs just weren't going to cut it; the sheer number of permutations would be prohibitive.
## Evangelising Svelte - Svangelising?
[Svelte](https://svelte.dev/) is definitely my "current squeeze" when it comes to building web front-ends; it's minimal, seems to avoid React's primary footguns and with [SvelteKit](https://svelte.dev/docs/kit/introduction), makes development of full-stack apps an absolute breeze. It truly feels like standing on the shoulders of giants when using these powerful tools!
Svelte has an extremely interesting property in that due to the way that `.svelte` files are laid out, i.e.:
```
```
... you can drop an *SVG file* into a Svelte project, change its extension to `.svelte` and it **Just Works** - it's a Svelte file that just happens to not have any `script` or `style`.
## SVelteGraphics Version 1
Given that an SVG "is just" (or perhaps [`satisfies` the definition of](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator)) a Svelte component, that means we can give it props, right?
`FillableThing.svelte`:
```
```
Which we can use like this:
`Caller.svelte`:
```
```
... although this is arguably not particularly useful; being able to set `filled` is nice, but we really want dynamic control over *which* SVG we're actually rendering in the first place.
## Snippet Like It's Hot
Further messing-around with the possibilities inherent in this finally led me to this "shape", that uses a [Svelte snippet](https://svelte.dev/docs/svelte/snippet):
`FillableThingSnippet.svelte`
```
{#snippet thingSnippet(filled: boolean)}
{/snippet}
```
So what I've ended up with is the "guts" of the original SVG (that had the two paths `main` and `inner`) inside a Svelte `snippet` that I can put anywhere in my Svelte app, and call with:
`Caller.svelte`
```
{@render thingSnippet(true)}
```
and as long as I've got my themed CSS variables (e.g. `--theme-color` and `--theme-fill-color`) defined, I've got fillable, themable SVG content.
## Bonus: The MDN SVG Tutorial
MDN has a [fantastic tutorial](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch) that introduces the components of SVGs one-by-one, and I'm really interested in exploring programmatic manipulations of these. Stay tuned!
Saturday, 22 February 2025
Introducing ... Blitzcore!
My family has become quite addicted to an excellent little card game called [Dutch Blitz](https://en.wikipedia.org/wiki/Dutch_Blitz). It's easy to learn, compact, reasonably quick to play (although the exact length of an entire game can vary *wildly*...) and it's lots of fun.
The only downside is the scoring system, which involves pen-and-paper and certain amount of maths, making the scorekeeper role unappealing to younger players.
To this end, I'm pleased to release [Blitzcore](https://blitzcore.themillhousegroup.com) ("Blitz-Score") to the world, allowing your phone to do the maths for you and present a clear picture of the score [1](#foot-1).
Paintakingly designed to fit onto exactly one phone-sized browser page like [all good mobile-first webapps](https://blog.themillhousegroup.com/2023/08/searching-for-next-spa.html), it uses bright colours that match the game, big easy-to-hit buttons, and just-in-time calculation to ensure the score is always accurate, no matter what you just edited.
Your player name and colour preferences are stored in LocalStorage to make it even quicker to get going next time.
This is my first "big" (not really) webapp in [Svelte 5](https://svelte.dev/) and [SvelteKit](https://svelte.dev/docs/kit/introduction) and it's been a pretty delightful experience. I `push` to my Github private repo and Netlify (free tier) picks it up and publishes to the world in about 45 seconds. The page load time is absolutely stupendous - Svelte/SvelteKit/Vite is absolutely killing it here.
The only trouble I've ever had has been occasionally Svelte *not* reacting to a change when expected, which so-far has been 100% due to my failure to wrap derived values in [the `$derived()` rune](https://svelte.dev/docs/svelte/$derived). It can be quite a pain to track down these things, which seemed to mostly be around manipulating array entries (using `slice` and friends), but I got there in the end. Enjoy!
---
1 To be clear, this is not a version of the game itself - the creators have actually [attempted to do this for mobile devices](https://dutchblitz.com/), which I have never tried ... [⤴︎](#foot-1-src)
Labels:
dev,
dutch-blitz,
markdown-enabled,
netlify,
node.js,
svelte,
typescript
Subscribe to:
Posts (Atom)



