Back to Blog

Ultimate Remote Development Set-Up for the Modern SaaS

Published on: 2024-5-18 Ultimate Remote Development Set-Up for the Modern SaaS

There are so many development platforms, languages, and frameworks out there that starting, or even continuing, your software development journey can, and often does, feel overwhelming. Believe me, I know. I have been developing since 1998.

I tend to compare my work to my partner's business. Her toolset is limited to a low-power but reliable laptop, Excel and 2-3 industry-specific search and knowledge databases. Plus the immortal Outlook. Changing tools is a monumental event for her and her staff.

Whereas we, as software developers, switch between NPM, yarn, VS Code, vim, IntelliJ daily. One day, we might be building a front end in JavaScript, the next we might be adding a PHP WordPress plugin, the day after that we might be diving into Scala microservices. This hodgepodge of stacks, technologies, and editors can feel super overwhelming.

Is there a solution to this heterogeneity of our ecosystem? No. In fact, we made this happen on purpose. We are in a rare position. We are craftsman that can make our tools, to make our craft easier.

Your tool set and your choice of languages, IDEs and even colour themes is yours to make. And with that said, I want to show how I work.

This article is rather unusual for a Wide Angle Blog. Rather than sharing digestible privacy education or content for the marketing crowd, I would like to give you a sneak peek into how Wide Angle is being made. Specifically, what technology is being used and how I manage it on a daily basis.

Technology Stack

Wide Angle Analytics is built in a rather traditional, for SaaS, approach. There are backend services and a frontend. OK, multiple frontends.

Frontend, backend and cloud stack - Wide Angle Analytics

But here's where parallels with many other SaaS products end.

Wide Angle Analytics is solely responsible for the data it collects. There are no external APIs we send the data to. We are in control. This gives us toggles and levers around privacy and compliance. With this and other measures, we have confidence to say that we are a truly GDPR-compliant Google Analytics alternative.

As such, Wide Angle Analytics is not a typical CRUD web application. There is data ingestion, data processing pipeline, analytics engine, data and event backup, etc. Running all of these systems locally during development is hard, even for modern machines.

Here's how I do it… but first some background.

The Backend

The backend is written in Scala 2.13. I frequently wish I could rewrite it to a much nicer Scala 3, but as it stands, Scala 2.13 is still well maintained and there is a rich community around it. At this point, migration to Scala 3 is not a business priority. I often get asked why I chose Scala for a bootstrapped start-up. Why not Ruby on Rails, Laravel, etc? The answer boils down to three simple answers:

  1. I already knew Scala, so it was much faster to get the product out,
  2. Scala's strong type system is a wonderful safety net, which helps me focus on harder problems, like value adding features, rather than on some small minutia of runtime errors, and
  3. Functional Scala and http4s offer great performance.

As a true bootstrapper, with no time to faff around home-brewed stuff, I started with Kubernetes. Kubernetes has an incredibly low learning curve and is a major time saver for deployment and ongoing maintenance. Don't let DHH and his crowd convince you otherwise. Don't believe me? Imagine this, you can have deployment, autoscaling and rolling upgrades, all defined in a single YAML file. Yes, YAML files are an abomination that should be burned on altars of future generations, but that said, once you tame indentation hell, you will be good.

Wide Angle runs on OVH Public Cloud and their managed Kubernetes. The Kubernetes is actually free, you only have to pay for compute instances and block storage. When we started in 2021, their offering was still maturing and there were some teething issues. But we stuck around, and I must say, today we enjoy a good quality of service.

Due to these initial stability issues, especially regarding Persistent Volumes, some parts of our system, like Kafka, lives outside of Kubernetes. Its management is automated with Ansible.

Kubernetes files and Ansible play books are stored in git, giving us full control over infecture as a code. Compared to hodgepodge of bash scripts bonanza of the yesterdays, this gives Wide Angle a ton of flexibility, reliably and safety.

For instance, when new release of a service is ready, we push it to private repository as an image and restart the deployment.

> labs > jarek > ~ >
$ docker build .                                    # build
$ docker push ...                                   # push to repository
$ kubectl rollout restart deployment/<service name> # make it go vroom

Kubernetes does everything else. Makes sure the service gets enough resources that restarts keeps enough instances running to assure uninterrupted service. Pods (the instances) are deployed on different physical nodes (affinity) to assure high availability and fault tolerance, etc. All out of the box.

I didn't use Kubernetes before I started. It took me 1 week to get productive and another 2–3 weeks to get proficient. The official documentation is truly wonderful.

For Ansible, I watched Jeff Geerling's Ansible 101. Great resource that I highly recommend.

I already hear some folks screaming at the back: use Serverless or Lambda's from AWS or Azure, it will be easier.

Perhaps it is easier. But is also defying the point of building GDPR-compliant service. You can keep data in transit and at rest encrypted in both Azure and AWS, but at some point, to precess them, they have to be decrypted. Any thus exposed to US Cloud providers and all the compliance issues that stem from that.

Not to mention the cost of those services, being much higher than OVH Kubernetes style of deployment. A cost which we would have to move onto our customers in a form of higher fees.

The Frontend

Front ends, on the other hand, are different stories. I was always a massive fan of Elm Lang and even Ember.js. These two, extremely different technologies were shortlisted for the 1st iteration of Wide Angle. But then, in the early 2021 if tried Vue and immediately fell in love with it.

Why multiple front ends, though?

We maintain a landing page in Nuxt3 and the actual application in Vue3. These are deployed and maintained separately, with some shared parts. If you wonder why such a split, and why not use Nuxt across the board, then that's actually a good question.

The landing page is truly static. It runs of static files only and is predominantly delivered via CDN. The blog and documentation runs on the great Nuxt Content module, and the majority of content is authored in Markdown.

The app itself is much more dynamic, and it loads various JavaScript segments and parts dynamically. While it could have been a Nuxt application as well, the application started as Vue3 and there is little incentive right now to make the switch.

All in all, we are committed to the Vue ecosystem and enjoy being part of the community.

The Consequences

Scala, Vue, Nuxt, databases, messaging, caching, plus Docker and Kubernetes? That's a lot of resources to run end-to-end tests and local experiments. How do you build a developer workstation that doesn't require a large tower and 1000W power supply?

Personal Development Set-Up (the nerdy part)

Compiling Scala, running two Node.js processes, databases, and local Kubernetes is not a good experience on a laptop. A large tower/desktop workstation is a bit out of the question. I do want to the flexibility of the laptop.

Sitting on a couch, experimenting with design, is something I thoroughly enjoy. Plus, in true remote fashion, I want to go to places and still be able to support Wide Angle. This is, after all, a part of my job description.

So laptop it is. With external screen when available

Jarek's home office where he builds Wide Angle Analytics

But what laptop would support this? There are beefy laptops that would easily run this workload, but as I prefer a good screen and long battery, I settled on a slightly different approach.

My daily driver is a Lenovo Windows 11 Pro laptop which effectively acts as a thin/thick client connected to a bare-metal Xeon workstation in the OVH data centre.

  • Laptop: Intel Core Ultra 7 155H, 32 GB RAM, 1 TB disk and 3K screen resolution.
  • Workstation: Xeon E-2136, 32 GB ECC RAM and 500 GB of SSD storage.

My initial idea was to use the remote server/workstation with NoMachine. It works really well and provides an excellent experience for development. However, as I do quite a bit of office and graphics work with either Adobe or Affinity suite, I decided to employ a different set-up.

The workstation runs a headless Ubuntu, with tmux session, docker, minikube and other services.

If you don't yet know or use tmux, I highly recommend you check it out. There are several online tutorials that will help you get started.

I then use my laptop to develop using VS Code and a remarkable Remote Development extension pack. It offers an option to connect to remote folders either directly via SSH or with a Code Tunnel. When necessary, I use SSH client in PowerShell terminal and connect to the tmux session.

Example of tmux session on remote workstation - Wide Angle Analytics

This solution offers me a persistent, always on workspace, to which I can simply connect to and resume working where I left off. Should my laptop die, I can even use Raspberry Pi as a thin client and resume where I left.

VS Code Experience

The Remote support in VS Code is on the next level. Whether you use SSH or Remote Tunnel, it is smooth and feels local.

The connection between laptop and workstation does not have to be superfast, and because it is SSH/text based, even spikes in latency are not a major issue. This set-up allows me to work even on a flaky 4G connection if needed.

You can easily move files to a remote server using VS Code, just drag and drop the file to Explorer sidebar.

Testing It All Together

There is a small issue with the above set-up. As the local IDE and the server are on different networks, accessing local development services would require exposing them to the scary Internet.

That's where the VPN connection comes to the rescue. Setting up OpenVPN or Wireshark on Ubuntu is super simple these days.

One click in the client and your workstation network and local laptop are on the same network, making everything a seamless experience.

Remote workstation connected to local client via VPN each serving its function in development stack - Wide Angle Analytics

You might think this feels complex and involved. But actually, it is surprising easy to set up and then use. Just check this day-to-day workflow:

  1. Connect to VPN.
  2. Open VS Code and pick project from Remote Explorer.
  3. And then optionally:
    1. Open Windows Terminal.
    2. Start SSH session into Workstation.
    3. Launch tmux to restore long-running session.

Frequency Asked Question

Why a Windows laptop and not a Mac?

For my use case, Apple laptops deliver no extra value while costing more. As simple as that. The secondary reason is poor keyboard ergonomics, in my opinion. Lastly, compared to WSL2 or remote Linux, the macOS Unix like experience is sub-par.

Why VS Code and not IntelliJ IDEA?

The Scala Metals plugin for VS Code is from another world. It is spectacular, super reliable and fast. None of these attributes describe IntelliJ IDEA when it comes to Scala.

IntelliJ IDEA Ultimate pricing - Wide Angle Analytics

Additionally, for my remote set-up I would require IDEA Ultimate and support of front-end technologies, which for a business would cost €779 for a licence. It is like paying more for a worse experience.

What's a latency when working on a remote workstation via VPN?

Today, I am still running OpenVPN. With Wireshark transition looming. But even OpenVPN works great for my use case:

Pinging labs.vpn [] with 32 bytes of data: 
Reply from bytes=32 time=16ms TTL=64 
Reply from bytes=32 time=15ms TTL=64

15ms is not noticeable even with NoMachine graphical interface.

Why OVH and not AWS, Azure or GCP?

In 2021, we joined the OVH Start Up Program. We got €10k free credits and a support network. All that to build a service on open technology. We could easily redeploy Wide Angle on other managed Kubernetes, including AWS, Azure and GCP.

However, before June 2023, and probably not long from now, the US cloud is and will become unfit for processing EU data that can be considered Personal Data.

Wide Angle Analytics does accept personal data in default configuration, but we keep it as an option for businesses that hold appropriate consent.

To be able then and in the future to offer such a unique service and assure it future-proof compliance, we are sticking to EU cloud providers, especially the one that showed generosity and support in our early stage.

Why Vue and not React?

Technology wise, it probably as good as Vue. And so it comes to personal preferences.


Bootstrapped founders can cut down a lot of effort by using containers and orchestration like Kubernetes to accelerate development. 

Type safe, functional languages have mature and free tooling that makes building reliable, fast and correct software much easier.

We are almost always tethered to the Internet, and running a beefy cloud workstation to support our non-trivial application stack has become a relatively easy feat. 

Think about this, a cheap Lenovo laptop worth €1000 and 3 years of cloud dedicated machine for €40 per month will still be cheaper than a comparable MacBook Pro. And more reliable and resilient at that. 

Developers are spoiled for choice. Make yours. 

Looking for web analytics that do not require Cookie Banner and avoid Adblockers?
Try Wide Angle Analytics!
Jarek Rozanski
Author: Jarek Rozanski

Jarek Rozanski is the Founder of Wide Angle Analytics. After a successful career in investment banking and financial services, he decided to explore the world of start-ups and eventually start his own. Privacy, one of our basic human rights, needs strong protection according to Jarek.