I’ve set up a new system for Rust development work.
I work on quite a few crates in the Rust ecosystem. Since I started taking Rust seriously back in 2021, I’ve been using the same laptop that I’ve used since high school.
It’s actually a pretty beefy laptop, all things considered. It has an i5 CPU and 16 GB of RAM. It ran Ubuntu for the majority of its life but now runs Alpine Linux. These stats were definitely overkill for a high schooler playing around with Python. Even now, it still works with smaller codebases. Honestly, it’s an exceptionally first world problem to even be complaining about.
However, I’ve started to hit the limits of this computer. 16 gigabytes of RAM is a lot when you’re dealing with codebases like
smol. Even if you put all of
smol’s subcrates together,
rust-analyzer barely uses up four gigabytes.
However, lately I’ve been working on codebases that overflow my limits.
winit is a medium-sized codebase at around 25KB lines, but with all of the dependencies it makes
rust-analyzer slow to a crawl.
x11rb has a lot of automatically generated code; I’ve actually experienced a kernel panic because
rust-analyzer took up all of my memory processing
x11rb, including an additional 16 gigabytes of swap space.
Not to mention, once my laptop touches swap space, it might as well be over. Memory access slows to a crawl, and the latency between my thoughts and my applications might as well be dial-up.
Time for an Upgrade
Since I started this blog in March of this year, I’ve managed to trick a company into giving me money in exchange for writing code for them. Around Prime Day, I decided to burn a paycheck on an upgrade.
My goal was to build a server that I can access remotely. I move around a lot; I like to write code at various hackerspaces and coffee shops around the city. It’s a nice, social environment where I can talk to (or at least be around) people while I code. I’m already an introvert, so I don’t want to be cooped up inside if I want access to serious computing power.
The remaining goal was absolute overkill. I don’t want to have to upgrade this machine for the forseeable future. Therefore, I’m going all-out on hardware and software.
The Hardware Specs Section
I built this computer around the AMD Ryzen 9 5950x processor. It was half-off for Prime Day, which is what prompted this entire process. It has 32 cores and is reasonably fast. I’m aware I could go higher, but I don’t want to break my bank account for something I’m not being paid for.
Don’t get me wrong; my laptop’s CPU was already good enough for my use case. With Rust’s incremental builds, I very rarely spend more than a few seconds waiting for feedback from
rust-analyzer. Still, from-scratch compiles took a few minutes, especially for larger crates.
With 32 cores, I can easily parallelize crate builds.
cargo install ripgrep completes in less than a minute. Combined with an absolutely overkill 128 gigabytes of RAM, I can build any crate I want to in record time.
My workload isn’t GPU intensive, so I grabbed an AMD Radeon 570x to use as a GPU to tie the build together. I combined this with an ASRock motherboard, a CoolerMaster chassis and liquid-cooling system, and a 4TB SSD to tie the rest of the computer together. The end result is a system that I don’t intend to use directly, but will be very nice to use remotely.
Putting It All Together
I’d like to muse briefly on putting this computer together. I’ve never actually built a computer before. Usually, when I’m in need of a new computer, I don’t have time to go through the process of figuring out which parts go where. So I’ve only used prebuilt systems until now.
I’ve heard from some people that putting together a PC is like building Legos. While this is true in some respects, keep in mind that these are 2000 dollar legos, where in some cases it might be unclear what part goes where. This leads to a lot of stress; especially around installing the CPU. One bent pin means that you have to throw out the CPU.
Thankfully, on attempt number three, my friend and I successfully managed to put the CPU in the socket and install the liquid-cooling system. Everything else screwed into place relatively easily. The motherboard goes into the chassis, and everything hooks into the motherboard from there.
However, I made two crucial mistakes. First, I ordered a 3U chassis where I actually needed a 4U chassis. I also needed a 750W power supply instead of the 500 W one I originally calculated I needed. Amazon has a decent return policy, so I was able to return those parts and get the ones I actually need.
Finally, after putting it all together, it refused to boot! We thought we’d installed the CPU wrong. After crawling over the manuals and forums for the motherboard a few times, we figured out that e needed to plug in a keybard. Weird. Anyways, one Alpine Linux install later, I had a working PC.
Utilizing the System
I’ve set up this PC in the attic. Thankfully, the liquid cooling is quiet enough so that I don’t hear it when I’m trying to sleep.
Now, I want to be able to access this from anywhere. Like I said, I want to be able to use this computer like I’m sitting down at it, even if I might be across the country. Originally, I was going to set up an SSH tunnel between my laptop and this server, using an AWS Lightsail instance as an intermediary.
However, then I found out about Tailscale (not sponsored), which fit my use case much better.
So, I’ve scaled my tail. I’ve hooked up my new server, my phone and my laptop to a tailnet. SSH is a breeze and setting up other services is a cinch as well.
I’ve been getting used to
code-server. In fact, I’m writing this in there right now! I’ve tried to get used to Neovim and Emacs and other editors like that. However, I’m just too used to the VS Code workflow at this point, especially since using it for work. Generally, I don’t notice a difference between
code-server’s interface and VS-Code.
However, there is one cinch. When testing out
winit, I need direct GUI access. Remote X11 just won’t cut it, especially for rendering.
I’ve installed a VNC server on my server, and I can just tab over to my VNC client whenever I need to run a GUI application. Still, it’s a somewhat awkward workflow. I’m open to new ideas.
There isn’t a moral to this story, I just wanted to talk about my new remote workflow. I hope this overview inspires similar remote flows in the future.