An introduction to htmx and the hypermedia and HATEOAS concepts behind it, followed by a conversion of a simple todo app from a Node/Express setup that serves JSON and renders client-side in JavaScript to an htmx version where the server returns HTML fragments instead. I compare the two implementations and discuss when htmx makes sense, particularly for server-side developers who want to avoid writing frontend JavaScript...
In this walkthrough, I build a minimal Node/Express REST API backed by SQLite as a learning exercise for migrating an app away from Mongoose. I cover query strings versus request bodies, CRUD endpoints for a users table, and rewriting string-interpolated SQL as parameterized queries to prevent injection. I close with a table of REST conventions for HTTP methods and a link to the finished project on GitHub...
A security vulnerability announced for Forgejo, which also affects Gitea and Gogs, prompted me to look into the fork history behind my self-hosted Gogs setup: Gitea split from Gogs in 2016 over project management disagreements, and Forgejo forked from Gitea in 2022 after its trademarks moved to a company. Impressed by Forgejo’s handling of the issue and only lightly invested in Gogs, I’m considering a switch. The takeaway is that project governance matters alongside features, and security announcements for the tools you rely on are worth following...
A guide to pushing a single git repository to two remotes, prompted by my running a private Gogs instance alongside GitHub. I cover naming remotes meaningfully rather than relying on the convention of origin, pushing to each remote explicitly, and using the -u flag to set a default remote, which becomes the source of truth for both pushing and pulling. My typical setup treats Gogs as the source of truth, with manual pushes to GitHub when code needs to be shared...
I offer a beginner-oriented walkthrough of Go’s concurrency basics, built around a small demo program with a worker function that sleeps and reports. I introduce goroutines, then channels for passing values between the worker and the main program, explain why plain channel reads block, and show how a select statement with a default case enables non-blocking checks, finishing with closing the channel to release resources. The sample code is available on GitHub...
A walkthrough of my workflow for adding a new self-hosted service to my Proxmox homelab, using audiobookshelf—set up after abandoning Audible—as the worked example. It covers running the service as a Docker container inside an unprivileged Debian LXC, mounting NAS storage via fstab, Tailscale access, Ansible automation, monitoring with Uptime Kuma, and Proxmox backups...
ViewTube is a self-hosted YouTube front end that strips out ads and tracking, with local accounts for subscribing to channels and keeping video progress. I got it running in a VM with Docker Compose in about five minutes, along with a workaround of using MongoDB 4.4 because newer versions require AVX CPU support my VM didn’t expose...
This is a write-up of a small weekend project of mine: a Node.js/Express server that serves markdown files from a directory as HTML, using middleware to intercept requests for .md files and convert them with the Showdown library. I added a simple string-replacement template so the output is well-formed HTML with a proper page title. The code is on GitHub, with hardening and a possible Docker containerization left as future work...
My disk benchmark results for a few VPS providers, run with fio. Binary Lane performs well despite only advertising SSD storage, while I find the difference between Digital Ocean’s SSD and NVMe offerings disappointing, though contention on shared drives may explain some of that...
I give an overview of how nginx configuration files are arranged on apt-based distros like Debian and Ubuntu. I cover the main nginx.conf file including configs from the conf.d directory, a pattern that separates distro-maintained settings from local changes, and the sites-available/sites-enabled symlink setup for enabling and disabling individual site configs...
After Reddit’s treatment of its communities ahead of its IPO, I decide to leave the site and evaluate alternatives, settling on Lemmy as a federated, Reddit-like replacement. I also cover communities that moved to Discourse instead, the fragmentation of online discussion into smaller islands, and ChatGPT’s possible role in Stack Overflow’s decline, and close with a list of the Lemmy and Discourse communities where I now post...
A short YouTube video on building REST APIs with Node and Express prompts a plan to replace my existing weather data setup—a Python cron job on a VPS that writes API results to a text file served by NGINX—with a Node.js endpoint that fetches and caches fresh weather data on request. This would cut the up-to-ten-minute staleness of temperature data polled by homelab servers, and I break the work into small steps, starting with replicating the current text-file behaviour in Node behind NGINX...
A short walkthrough of replacing my dead hard drive with a 2.5-inch SSD in my 2012 Intel MacBook Pro that had sat in a drawer for three years. I cover removing the bottom cover, disconnecting the SATA plug, transferring the mounting lugs with a torx driver, and reassembling, along with a few practical notes like the angled case screws and a packing-tape fix for the pull tab...
I describe adding outdoor temperature readings to my homelab server temperature logs to account for ambient temperature changes, using OpenWeather’s free API. A bash script on a VPS polls the weather endpoint every five minutes, extracts the temperature and timestamp with awk and cut, and serves the result as a text file that each server fetches during its logging cycle; the server-side script also loads the drivetemp kernel module to read SSD temperatures. Graphs of 24 hours of data show how ambient temperature, workload, and a CPU stress test affected the three servers...
I experiment with lightweight Linux distros on an old HP Mini 110 netbook, motivated by wanting a low-cost machine for accessing Proxmox VMs outside the web GUI. I try three distros, antiX, Lubuntu, and Mint Xfce, with the main stumbling block being Broadcom wifi drivers: antiX runs the fastest but I never get wireless working on it, while Lubuntu and Mint both work once I install proprietary drivers over Ethernet. Mint Xfce ends up as the working option, despite its 32-bit version nearing end of life...
Setting up a backup strategy on a Synology NAS, I SSH in to locate volume and share mount points and do a dry-run rsync of a movies directory from the NAS to a USB drive. The first run surfaces thousands of @eaDir entries, which turn out to be Synology metadata files likely produced by the indexing service, and I end the post by excluding them via the –exclude option...
Setting up SSH key-based login on a Synology NAS running DSM 7.1.1 takes a couple of extra steps compared to a standard Linux distro: enabling the SSH service and enabling user home directories, since DSM doesn’t create them by default and ssh-copy-id needs one. I walk through both settings in the DSM web interface, and note that most Synology tasks are usually easier and safer done through its web UI or Package Center...
A Jim Hall video on the history of FreeDOS prompts me to look back at my own experiences with DOS 2.11 through 4.01, moving to Windows 3.1, and using the AsEasyAs shareware spreadsheet. I also muse about tracking down old executables to resurrect a Clipper programming environment and compile my first commercial software, and reflect on wishing I’d kept screenshots from years of computing, including long stretches in the WordPress editor...
While planning to move my applications from the cloud to self-hosting, I evaluate Synology NAS options for a roughly 12TB storage target, weighing RAID levels, second-hand versus new drives, cost per terabyte, and power consumption. I ultimately choose a new DS420j with four used 6TB drives in RAID 6 for production, plus a single-drive NAS for local backup and my existing unit with 14TB drives for remote backup...
In my homelab troubleshooting saga, Linux file permissions repeatedly foil my attempts to get Jellyfin working — first in an LXC container on Proxmox, then in a Debian VM, and finally via the official container version. Along the way Tailscale proves incompatible with the container, metadata posters vanish unexpectedly, and I conclude that on Linux, permission issues should be the first suspect whenever something breaks...