Local Network Apps

Starting to replace cloud services with things I host at home

For years I had Fitbit watches. I used them firstly as watches, mostly for time, but also so I could see who had sent me a message without getting out my phone. Fitbit became part of Google and, over time, folded in completely. At that point I switched away for all the usual reasons. I used a Garmin watch briefly. I got a lower-end one, which was fine, but lost it at some point along an international trip. I haven’t really felt like replacing it. I still would like a minimal smart watch, but what I miss more is is a place to track basic health stuff. With that sort of information in particularly I’m feeling pretty done using cloud services and wanted something private that I control.

I’ve been tracking weight for the longest time, so I decided to start there. Plus it’s an easy measure, a single metric, updated daily at most. I wanted to replicate how I’ve been tracking weight using the Fitbit and Garmin apps - I don’t have a fancy scale, so just manually entering one data-point every morning from within my house.

At my house I have a tiny server closet shelf. It has a Raspberry Pi running Pi-hole and “Intel NUC”-alike box running Plex. I decided to just host whatever needed hosting on that later box. No cloud, just a server in my closet. I absolutely don’t want to create much more work for my personal sysadmin, which would be me. The setup had to be normal, simple even. What I wanted was just to put the application on the box and run it. I don’t want to install any new packages I just want to run my app.

So, no runtime dependencies. My application should run on it’s own. I don’t have time to wrangle Node.js or python and the assorted package managers, as they litter my system with various versions of the scripting environment and dependencies. …not on my free time anyhow. I want a simple deployment package that is self contained. I looked toward Docker first, it felt appropriate. I’d been wondering if I should use the docker image for Plex anyhow, rather than the .deb package I’m using currently. I started to make a list of how I’d need to update things and then couldn’t bring myself to start working it. It felt like the kind of risky and intrusive setup that I didn’t want to spend my free time on. With that I started to sour on my usual choices of Python or node.js.

The other option for a self contained application was to use a language that easily produces one. I decided I’d either use Rust or Go. For no reason that I’d been reading about Rust more recently, I picked it. I took a quick scan of frameworks and choose Rocket. In retrospect I should have done more than a quick scan as I naively assumed that authentication would be a solved problem in any framework, but in Rocket I had to implement it. As with the last little app I built, I took a shortcut and didn’t implement CSRF protections

Building the Rocket app was fun. The docs and examples are great. Rocket makes a lot of the right assumptions about what you’ll need. I used the Tera templates and like, it all just worked. I did have a few moments of struggling with type & lifetime annotations, but nothing that an extra few minutes didn’t resolve.

For the frontend I kept things very simple. I’ve got the “HTML as the engine of application state” (aka HATEOS) ideas loaded back in my head as I recently read the HTMX book. Consequently, I resolved to not use a JavaScript framework, just HTML and classic browser features. This app is extremely simple, essentially one page - with a single-field form, a graph and a list. I used d3 for the graph, but otherwise there is no JavaScript. Just regular HTML form submissions and server rendered HTML. For this case the approach totally makes sense. It’s not a compromise at all and the app feels super quick.

I’m really happy with this approach to writing and self-hosting apps I want to have. Certainly there are some kinks to iron out; setting up a VPN so I can use this an application outside my house, adding up some sort of TLS certificate so my browser complains less, making deployment less manual, checking that my backups include the database for this app, making authentication a bit more respectable, etc… but I’m looking forward to taking care of those small things and investing more in replacing my usage of the big cloud vendors with small services that I control.

If any of this resonates with you the code for my app is up on Codeberg.