How I Compute
After a few years of trial-and-error, I think I've finally hit a hardware and software setup that I'm satisfied with. This article exists to explain the benefits of the setup and document how it's put together. I'm not doing anything novel, but putting all of the information in one place will save me some sanity some day, I'm sure.
In Brief
At a high level, I have one stationary computer (the "brain") that's configured to be resilient, flexible, and powerful, both in terms of hardware and software. It holds everything that matters in a convenient, centralized location. Because I'm not always at home (and the stationary computer doesn't have a monitor), I own multiple laptops that are capable of connecting to this stationary computer from anywhere, assuming there's a stable internet connection. Any non-trivial task is done on the stationary computer by proxy of one of these laptops; the laptops do almost no "difficult thinking" themselves.
Why is it necessary?
Well, maybe not strictly necessary...
There are a lot of advantages to this approach if you ask your computer to do a lot of difficult things that aren't latency dependent, like compiling code. If you don't ask a lot of your computer, then there are still advantages to it, but you're not likely to be in a position where administering a system like this makes any sense.
-
You throw away less over time. If you expect a lot of your computer, you'll pay for a processor that's capable of doing a lot. If you're paying to have this processor put in a laptop, then you're tying its fate to the component that dies the fastest. That's a shame, since processors tend to have pretty long useful lives relative to the rest of a laptop. Even if you get a laptop with a chasis built to last, the processor won't be the fastest on the market for long, and you'll eventually have to shell out for a lot of new components that you don't need; you want a faster processor, but the screen, keyboard, and batteries were still doing just fine 1.
If you instead buy a passable laptop and outsource all of the thinking to a centralized "brain", everything becomes a lot more green. You can hold on to the laptop as long as it's able to run a browser and lightweight utilities (this is still true for many 2012 MacBooks at the time of writing). When the "brain" isn't up to muster anymore, it's easy to upgrade the components that need upgraded and little else 2.
Lastly, a lot of laptops just aren't cut out for long-running tasks. While some are thermally capable of handling long sustained loads, most of them aren't, and you're trading the lifetime of your portable computer in exchange for running them. And that's just the performance aspect - more on the performance / reliability aspect later.
-
Performance tends to be better. A laptop is working under a lot of physical constraints. It has to be portable, have decent performance, stay under a certain operating temperature, and have a decent battery life while managing all of that. It's a tall order, and puts you into a world of compromise.
Even if you did have a laptop that matched a centralized "brain" in specs, you probably don't have ready access to a reliable hardwired connection on your laptop everywhere you go, whereas it's table stakes for a stationary computer.
Laptops also just aren't the right form-factor for long-running tasks. I think back with annoyance on all of the times I decided that launching a long-running script on my laptop was a good idea: Check power settings to make sure it's not interrupted by sleep settings or closing the lid, don't close the lid because you don't trust the settings anyway, turn down display brightness so that you can sleep, and then throw the whole assembly into your kitchen because the fans are blaring anyway. Then, wake up the next morning to find out that your computer thought it was a great time to apply updates or something. On a centralized "brain" you can just run the command after a
screen -Sand be done with it. -
It makes you more resilient to adversity. If your primary computing device travels with you, you're not just coupling the hardware together, but the data as well. If the only copy of your PhD thesis is on your laptop and you lose it, you're in a pretty bad spot. This isn't the case if you're working on a copy located on a centralized server. Admittedly, the large players in operating systems have been getting pretty good about backing up user files.
The server doesn't just help you keep your data, though - it also keeps it from the prying eyes of others. If you're compelled to provide your laptop password, encryption doesn't help you, and suspicious encrypted volumes that you mount separately probably won't, either. If you mount a volume held on a private server that's only available when your network is configured in just the right way, though, there's not much to give away.
Moreover, if you're like me, you tend to lose things from time to time and/or are pretty clumsy. Losing, say, a sacrificial $300 Chromebook that you use to control a powerful server sucks, but it doesn't ruin your day like losing a MacBook that costs an order of magnitude more would.
-
Having an always-on computer has benefits. When you can pretty-consistently rely on a computer being active and connected to the internet, you can do all sorts of things with it:
- Run a VPN: tunnel all of your traffic through a trusted endpoint, giving you security (but certainly not anonymity) when running on unsecured networks. Also gives you access to home systems from outside of your home without forwarding ports.
- Host game servers: not applicable for me, but providing a game server for Minecraft, Terraria, or some other game isn't necessarily super-taxing on your system and is a great way to bring people together. It's nice to not have to ask someone to boot it up.
- Sky's the limit. Really, the point here is that you can host services on your computer when you can trust it to be up. Want to manage your own cloud storage a la Dropbox? Host a personal website? Have a remote desktop available at all times? All of this is possible, though I'd encourage you to keep security posture in mind before forwarding 10 different ports to the outside world - there are scripts continuously scanning for poorly configured computers.
The Nitty Gritty
Hardware
The hardware isn't anything too special:
- Intel i5 processor (6 cores@2.9 GHz)
- NVME SSD
- 4 spinning drives
- 32GiB RAM
The chasis is a Fractal Design Node 304, chosen because it has 6 3.5" drive bays, which is hard to find on any chasis, let alone a mini-ITX.
The processor has 6 cores; if you're running a diverse set of workloads, it's nice to have separate cores to avoid too much context switching. It does not support ECC RAM, which would be nice to have, but is hard to justify for a home server from a cost perspective.
The SSD is a boot drive for the operating system and holds data that must be accessible quickly, such as programs and the code they operate on.
The spinning drives provide storage for data that can afford to be accessed more slowly, such as general documents, archives, and virtual machine disks that don't change state frequently. These are arranged in a zfs-based RAID10, which means I'm sacrificing 50% of my storage in order to have redundant copies of all data in the case that one of my disks fail 3.
The 32GiB of RAM is just standard DDR4. When you're working with a lot of virtual machines and/or containers at once, you'll find that you run out fast. I'm definitely hitting the ceiling at 32GiB, but haven't felt any slowdowns yet - a lot of intensive programs will balloon up to use all of the RAM available to them, and that's a good thing.
The whole system is connected directly to a gigabit router, as you'd expect.
Software
Fundamentals
Proxmox Install
The "brain" runs a debian-based operating system called Proxmox VE. There is a paid-for enterprise version available, but you can use it for personal purposes for free.
After installing Proxmox, there's a convenient web portal available where you're able to manage the state of the server and any virtual machines / containers you need. I configure a DHCP reservation on my local router so that the web portal is at a predictable location on my home network, e.g. 192.168.1.100:8006. I strongly encourage users to never forward this port - there's too much damage that can be done with a compromised account. To wit, try to avoid using the root account and use a strong method of authentication.
Before calling configuration a success and disconnecting the peripherals you connected to the machine for installation, I'd advise enabling the Proxmox firewall through the web portal and making sure that the web portal remains accessible.
After this initial setup, you should not need to connect a monitor, keyboard, or mouse to the server again. The portal gives you full terminal access to all containers and the Proxmox operating system itself.
ZFS Pool Creation
ZFS is a cool filesystem technology that I don't know very intimately on a technical level. The short of it is that it allows you to mimic a RAID without specialized hardware, and Proxmox makes it very easy to use. From there, you can dole the capacity out to various virtual machines / containers and rest assured that whatever redundancy or striping you've configured is respected.
Initial setup is a good point in time to note the sequence of the disks and how they map to hardware. If you ever have to swap out a disk, it's awfully convenient to have disks marked with their ZFS ordering and/or Debian mount points.
Security
Again, use the Proxmox firewall and create sanely-scoped alternatives to the root user. It's tempting to rely on root for everything when you just want to get everything running, but it works against you in the long run, even if your network is airgapped. It's just not good organization.
Ideally, you should also disable password-based authentication and use ssh-copy-id to give yourself direct SSH access to the system. Direct SSH is nice because the web UI doesn't support copy/paste and some other nice things that you'd probably like (e.g. scp'ing things from the server to your local system).
Virtual Machines and Containers
It can sometimes be difficult choosing between a virtual machine and a container, and a lot of the "should I use this or that?" articles on the internet aren't very helpful in this context. Playing around with virtual machine /container networks and configurations isn't my passion, so I generally take the path of least resistance.
I find that while containers tend to be more performant, it's harder to get them to work for certain tasks, including:
- utilizing a VPN / proxy from within the container
- providing a VPN / proxy from within the container
- providing a development environment from within the container (with or without GUI)
- I imagine this is especially true where legacy distributions and kernels are concerned. Proxmox is based on ~latest Debian, but I might have projects that only build on an LTS version of Ubuntu, for example.
So default to containers, except where you expect one of the above to come into play. You'd also want a virtual machine in cases where you'd like to keep the environment as portable as possible. I like keeping my development environments in a virtual machine not only because they're hard to bootstrap as a container, but also because I'd like to be able to run it easily on a Windows machine if I found myself without a network.
My Virtual Machines / Containers
Dynamic DNS (Container)
A small container with the sole job of keeping a DNS record up to date using ddclient. Once every five minutes or so, a script runs to ensure that the DNS record that ought to reflect my server's IP address is accurate.
This is necessary because most home internet providers do not guarantee that you will keep a static IP, or upcharge for the privilege.
I want an up-to-date DNS record that points to my home server because I need to be able to refer to my server outside of my home network somehow. Using the IP would work, but if it changed, I would have no easy way to connect to the "brain" without going home.
I don't bother with offsite backups for this.
PiVPN + PiHole (Virtual Machine)
PiVPN is an easy-to-install package that sets up a WireGuard VPN. It works in conjunction with PiHole, which allows for the selective blocking of content based on domain name.
This component is critical because as long as I'm connected to PiVPN by way of WireGuard, I can act as though I'm on my home network. This means that I can access the Proxmox web UI, change my router settings, and generally access services that are on my network, but aren't exposed to the public.
Really, a properly configured WireGuard installation is the only service that you need to be forwarding out of your home network (and ideally on a non-standard port). This is only untrue if you plan on hosting a website (in which case you'd probably have to forward ports 80 and 443), but I'd argue it's a bad idea given how cheap hosting is: don't let strangers into your home.
I don't bother with offsite backups for this.
Seafile (Container)
Seafile is pretty much a self-hostable version of Dropbox. I prefer it over NextCloud because it does one thing well, and I don't need a lot of the features that NextCloud offers. In my experience, Seafile is also lighter on system resource usage, offers easy-to-use encrypted libraries, and has source code / configuration that is easier for me to grok.
Back in the day, I used to host NextCloud on a public domain, which is pretty terrifying in retrospect. I strongly recommend that you keep whatever file-syncing solution you use behind your home network and access it via WireGuard, unless you have a very compelling reason not to.
I keep offsite backups for Seafile in Backblaze B2. I do this in accordance with their documentation.
Development Environments (Mixed)
There has never been a better time to keep your development environment on a remote server. It no longer means using RDP to essentially send a compressed image of a desktop over the internet. For development, I use Visual Studio Code and JetBrains IDEs, both of which offer a fantastic interface for remote development that makes you forget that the code isn't on your local machine.
Visual Studio Code offers remote development over SSH.
JetBrains offers Gateway. Note that it unfortunately doesn't work for the community edition. If you're using this for personal projects, consider getting a year's subscription and falling back to a perpetual license when it's expired.
Both of these pages offer better and more up-to-date documentation on how they work than I'll bother to, so I'll just leave the links to speak for themselves.
I use a virtual machine for some of them because I require a VPN in some cases, and a legacy operating system in others. For cases where I'm able to use latest Ubuntu reliably (scripting, new projects), I just use a container. If you're uncertain, I'd just default to a virtual machine.
I do offsite backups on a case-by-case basis here. Generally, the valuable artifacts are in Git somewhere, so I'll deal with needing to rebuid a development environment if my central computer ever catches fire.
What I'd avoid
There are some things that I'd avoid leaning on having your "brain" do, even if it seems cool.
-
Email: This has always just seemed like a big can of worms to open. If my "brain" crashed today, I'd be alarmed, but I would have a path to recovery that I could follow at my own pace. I have backups for everything stored in Seafile, and most of my computers have a cached version of the files there, anyway. Adding email into the mix adds time pressure to the situation, meaning that I'd have to drop everything to address it if I don't want to start missing important correspondence. These days, it also means locking yourself out of a lot of your accounts given how common email-based 2FA is.
-
Websites: Exposing a part of your home network via a website to the world means you're on the hook for securing it and handling sudden spikes of traffic. It also means that something public you're presenting betrays something about the state of your home - if your website is down, are you in an area with a power outage? Extreme weather? It might be paranoid, but I'd rather not expose details like this.
Your self-hosted solution will almost certainly be slower, too. Just create a Git repo that gets fed into CloudFlare Pages or something and be done with it (it's what I use for this website). If it's not a simple static site, I'd recommend getting a hosting provider for production, while keeping your development or beta environments on the "brain" if you like.
-
Forwarding pretty much anything but WireGuard: Outside agents can't attack something that doesn't exist. WireGuard is pretty straightforward and sound, and it's a reasonable amount of attack surface to defend. If you expose your NextCloud to the world, now you have to worry about a brand new vector that could've been avoided.
This is pretty reductive, and I can think of a handful of reasons why I'd want to foward another port. I guess the message is just to default to "no", and make sure you have a very good reason to break protocol when you do.
That's it
This has been a high-level view of how I compute today, and I'm pretty happy with the situation. Happy to take any additional questions via my email posted on the home page.
Footnotes
Smart TVs and iMacs are bad purchases for the same reason. Coupling long-lasting components with relatively short-lived components is wasteful.
If you buy a decent processor, it's unlikely that you'll need to buy another one for some time. This means that when you do go to buy a replacement, the motherboard you're running on will almost certainly be incompatible with the new parts.
The usual disclaimer here is that having local redundancy in your system isn't the same thing as having a backup. It's better to think of it as improving your uptime. For a backup to be a backup, it should be in a different geographic location so that you're protected in the case of fires and what-have-you.