I'm Matt - You're here for my blog!

Category: Open Source

Setting up a Pi-Hole on a Raspberry Pi Model A in 2024

It’s 2024.

You’re looking back at 2023 as a blur.

How many different Internet providers did you go through?

It could have been 3 – it could have been 300.

It was 3.

3 different Internet service providers, all with their own unique and special modem/router combo of varying feature sets – some good, some okay, and some terrible.

We began 2023 with Spectrum, our ISP since moving to this house in 2015. While Spectrum provided pretty decent service, outages and signal issues posed more issues then one would generally prefer, and their speed offerings weren’t quite up to snuff in our area.

Next came Verizon 5G Home Internet. As soon as this service became available in my area, I signed up. All in all, Verizon’s 5G Home Internet was pretty solid. The router was feature rich and not having to have a signal/supply line is pretty cool – just plug in the box near a window that has good 5G access and you’re set to enjoy a pretty consistent 300Mbs/60Mbs connection.

Enter AT&T Fiber. As good as Verizon’s service was for me, fiber is king – and so when I saw the install trucks running lines in my neighborhood, I just knew I had to get on the waiting list. So far AT&T Fiber has been great. It’s notably faster than my already snappy Verizon 5G. Since install, I’ve not had a single outage – despite significant weather events occurring, which would normally knock me offline at least temporarily. One things that’s not great though is the router functionality. And don’t get me wrong, it’s not terrible – it’s just missing some things I’ve become accustomed to when using Verizon’s modem/router, such as an internal DNS Server.

What’s this post about again? Oh, yeah. ISPs…

Wait. No. This isn’t a post about ISPs.

This is a post about setting up a Pi-Hole on one of the first ever released Raspberry Pis, the Raspberry Pi Model A Revision 2.0 from back in 2011, in 2024.

But… Why?

Like many of my fellow technophiles, I have a lot of ‘junk’ electronics laying around – filling boxes, drawers, cabinets, shelfs and even whole closets…

“Why not just through them out” -my wife, constantly.

“I might need them one day” -me, constantly.

So… Here I am… In need of a DNS server and in the possession of many pieces of aging technology without an assigned purpose.

Enter the 13yr old Raspberry Pi.

Having not touched a Raspberry Pi in quite some time, I figured I’d do a bit of Googling to figure out the path of least resistance for getting this Pi back into the land of the living. After a couple of clicks, I find that there’s now an official Raspberry Pi Imager, so that seems a good place to start.

For my purposes, since I’m going to just be installing Pi-Hole, I want a minimalistic OS as my base. Since this Raspberry Pi is so old, I’m limited on what OSes I can easily install via the Imager – so I’m opting for ‘Raspberry Pi OS Legacy 32-bit Lite’, as I don’t require the full desktop experience and figure those system resources could better be utilized powering the Pi-Hole.

When going through the imaging process, I was greeted by some prompts that made me happy I’d opted to go with the official Raspberry Pi Imager – the ability to adjust some setting for my OS during the flashing process, so that I don’t have to manually connect to my Raspberry Pi in order to get things like SSH going:

Once the flash completed, I inserted my newly imaged SD card into the fatty SD slot on my Raspberry Pi and connected it via ETH to my Orbi base station, and powered it up to see if it would come online… I mean.. This thing is basically an antique – and, as such, likely hasn’t even had electricity racing through its circuits in nearly a decade…

Based on the lovely glow, it either has power….or it has caught fire:

Let’s see if we can SSH in:

Saaaaa-weet.

This isn’t a tutorial, and is instead intended to be more of a show and tell – so I will spare you the play by play on setting things up, as there are a number of excellent tutorials that already exist for this purpose. But rest assured, I followed one or two of them, fumbled along with the setup (not really tho – the Pi-Hole installer UI holds your hands and makes it pretty easy).

After the Pi-hole install completed, I then ensured I had it a static IP assigned in my router (should have arguably done this from the start, but…well…yeah…) before configuring my router to use that IP (the Pi-Hole’s IP) as my primary DNS server…

BOOM!

Old dogs can be taught new tricks, it would seem.

I’ll admit – I somewhat entered into this experiment figuring that I’d have to redo it all over again on a newer device than the Raspberry Pi Model A Revision 2.0 from back in 2011, but this thing is proving to be sufficiently snappy thus far.

I have things basically configured as the default right now – leveraging both traffic filtering, logging and local DNS… I’ll run things as they are for a bit and tweak according to my needs. This said, I’m happy to report that after putting things through its paces for a normal evening, everything appears to be working as expected – streaming services and other connected services are working as expected out the box, with ads being blocked left and right!

Anywhos! Thanks for checking in!

-Matt

Standalone Components in Angular 15

Up next in the Funemployment series, I’m taking a look at Standalone Components – specifically, Standalone Components in Angular 15.

Since I follow the official Angular Twitter account, I recently saw a link to this tutorial shared and so I figured it would be a good place to start: https://codelabs.developers.google.com/angular-standalone-components

Standalone Components and Chatbots?! Perfect!

One of the first things one might notice is that the tutorial targets Angular 14 – but since I’m really wanting to get a jump on Angular 15, I figured I’d forge ahead and try to tackle whatever issues may arise as they arise.

My environment

Since the tutorial largely just works in Angular 15, I’m not going to reproduce it step-by-step here – instead, I’m just going to highlight some of the issues I encountered when following along verbatim.

tl;dr:
1) environments/environment is no longer generated by default: https://github.com/angular/angular-cli/commit/283b564d1de985f0af8c2fcb6192801a90baacda

2) ngOnInit and default constructor no longer generated by default: https://github.com/angular/angular-cli/commit/301b5669a724261d53444d5172334966903078c0

So, yeah… The tutorial mostly just translates to Angular 15, and most experienced Angular developers will be able to quickly workaround any issues that may arise from working through this Angular 14 tutorial in Angular 15… But if you’re curious about my journey, please feel free to continue on…

Hiccup #1 – in the ‘Create a new application’ section of the tutorial, we’re shown how to strip down our application in order to remove the ngModule (basically a cornerstone of ‘standalone components’) – and as part of those instructions, we’re shown how to enable production mode by leveraging the long familiar ./environments/environment.ts file… Okay… But I’m getting an error indicating this long standing file isn’t present in my project… odd… that fella is always hanging out there…

Can’t reference what doesn’t exist…

Since I can’t ever seem to just do what I set out to do, I must now satisfy my curiosity concerning why this file, which was previously generated as part of the new project, no longer exists… After a bit of poking around in the Angular CLI github repo, I see the following: https://github.com/angular/angular-cli/commit/283b564d1de985f0af8c2fcb6192801a90baacda

feat(@schematics/angular): remove environment files in new applications

This commit removes the usage of environment files and `fileReplacements` in new application projects. Previously, the environment files was used to distinguish between a prod build to invoke `enableProdMode`. The `enableProdMode` however needed only for the case of JIT mode in production mode, which is a rare case as JIT mode is recommanded to be used in production.

In the CLI, calling `enableProdMode` is not needed as `ngDevMode` it's set using the minifier.

Whelp… That settles that… Moving on…

Since we no longer have this environment.ts file out of the box with new apps, it seems logical to assume we can skip some steps – basically, we just need to ensure we bootstrap our now-standalone AppComponent.

main.ts for Angular 15 Standalone Component

Skipping ahead to the next section, “Display the photos”, things seem straight forward enough… It’s worth noting that there seems to be a bit of a typo in the HTML, as the closing ‘article’ tag isn’t properly formed – no worries, as we just need to add an ‘>’ to make it valid.

Screenshot of tutorial showing ‘</article’ rather than ‘</article>’

Upon saving and running our updated project, we will see that while things are technically working, they aren’t working great because we’re missing some assets – namely, the images…

Hmm.. That doesn’t look very nice…

This makes sense, as image assets aren’t going to be generated by ‘ng new’ and are merely artifacts for this demo project… For simplicity, I’m just going to download these assets from the github project for this demo app: https://github.com/angular/codelabs/tree/standalone-components/src/assets

This looks better…

Continuing on to ‘Add a new standalone component’, everything in the original tutorial translates perfectly to Angular 15 and we can see our lazy loaded component as expected when we click the ‘Find out more about these guys!’ button as instructed:

Kewwwwl…

Another small note to make… Once you get to the ‘Add event handling to the form‘ section, step 4 of the ‘Add the send message form model to the component’ subsection instructs us to remove the default constructor:

Whelp… We don’t have a constructor in our newly created Angular 15 standalone component… Not particularly important, as it was empty and not really doing anything – but why doesn’t it exist?! MY ADHD WILL NOT ALLOW ME TO CONTINUE ON WITH WHAT I SET OUT TO DO UNTIL I KNOW… After a bit more poking around the Angular CLI repo, I see the following indicating that ngOnInit and the default constructor have been removed in Angular 15, as apparently users of these features generally prefer to simply add them manually: https://github.com/angular/angular-cli/commit/301b5669a724261d53444d5172334966903078c0

Moving on…

Reactive form up and running…

The next section, ‘Add a chat dialog’, just works. Unrelated note: I really liked this section… Having never played with a virtual agent / chat system, I learned something new, which is always fun! And that’s pretty much it – standalone components in Angular 15…

NEAT-O!

At this point, I’m going to stick a fork in this write up and consider it done. The remainder of the Angular Standalone Component tutorial details deploying the project to Google App Engine with Express.js – which I feel is a bit out of scope for this write up, which was to detail the hang ups I encountered working through this Angular 14 tutorial in Angular 15 (which were very minimal – YAY!).

Happy coding!
-Matt

Exploring Denoland – Home of the Deno JavaScript Runtime

With some of my newly found ‘free time’ while Funemployed, I really wanted to start playing around with some of the newer projects that I’ve simply not had the time or energy for.

At the top of this list has been Deno, the new-ish JavaScript, TypeScript and WebAssembly runtime based on V8, co-created by Ryan Dahl (Node.js creator).

Why Deno? Well, for starters I love new and shiny things. But also, I have a special place in my heart for JavaScript runtimes – having been an early adopter of Node.js, at a time when serverside JavaScript was a controversial topic in the dev world (Thanks, Whiteboard IT! It’s because of my time with this company that I was exposed to a lot of really cool things, including Node.js and CouchDB/NoSQL). “How early?”, one might ask… Early enough that I’m listed as contributor #306 in the Node.js AUTHORS file – as a result of contributing a slash to the first official Windows installer.

I began my journey with Deno as I normally do – essentially iterating on some basic Hello World types of projects to get familiar with the dev flow, tooling and capabilities. Pretty quickly, I encountered something in my codebase that confused me – a warning notifying me that the deno window typings didn’t have everything supported by window exposed. Surprisingly, it wasn’t just me randomly plugging in code that landed me here – it was in following along with the Deno lifecycle docs that brought me to this error.

“Element implicitly has an ‘any’ type because type ‘typeof globalThis’ has no index signature.deno-ts(7017)”

At this point in my journey, not only was I getting the warning in VSCode, but I was also unable to get beforeunload or onbeforeunload to fire… Hmm… So off to Google I go – which lead me to this thread discussing a related matter.

In digging a bit deeper, I came to realize that beforeunload/onbeforeunload weren’t firing due to my Deno version – with support for these not being added to window in Deno until v1.24.0 (and me currently running v1.23.0). “Alright”, I thought – “I just need to upgrade and this will all be solved.”

Sure enough, once on 1.24.0 I was able to play with beforeunload/onbeforeunload – but the “Element implicitly has an ‘any’ type because type ‘typeof globalThis’ has no index signature.deno-ts(7017)” warning remained…

Having wished I had more time to contribute to open source over the last several years, I saw this as an opportunity to make my wish a reality – and so I did what any developer would do, created a fork and started to work on a new branch in the hopes I could become a Deno contributor!

As most experienced devs know, stepping into a large and complex codebase isn’t always the easiest thing to do – especially if you’ve never worked with some of the core tooling. With this being my first real exposure to Rust, I was completely unfamiliar with Cargo and how to go about building and testing my changes in an efficient manner… Fortunately, after a handful of web searches, I learned the basics of working in Rust and with Cargo, how to run specific tests by name, and I was off to the races to become a real life Deno contributor.

My commit is simple enough – really just a few lines to add beforeunload and onbeforeunload to the type definition for Deno window, and some updated integration tests to ensure everything is working as expected – you can see the pull request / merge here. While a small contribution by pretty much all standards of measurement, it felt good to see an issue, fix the issue and contribute that fix back to the community – and I hope to be doing more of this in the near future.

So, what’s next? Well, I guess I can actually begin with what I set out to do – learn Deno (rather than Deno’s codebase) and start playing with Fresh! 😁

Happy Coding!
-Matt

© 2024 blog.immatt

Theme by Anders NorenUp ↑