Deploying stable and dev to single VPS

I want to run both a production and a dev server on a single VPS that is running NixOS.

I have DNS pointing both

  1. my-thing.example.com
  2. dev.my-thing.example.com

at the same VPS.

I want my-thing.example.com to continue running uninterrupted while I push iterations on dev.my-thing.example.com.

Details:

  • development done inside a flake
  • web server implemented in Rocket (Rust)
  • backed by sqlite
  • GUI implemented in egui that uses the API provided by Rocket (originally deployed separately by trunk but I think I want this served by Rocket)

I’m looking for some flexible way of taking whatever I’ve got in my working tree on my local dev machine, and pushing it to the VPS to see how it behaves as dev.my-thing.example.com and let interested parties have a look, without interfering with the running production server. Then, when significant progress has been verified on dev, I want to be able to do a proper deployment of the new version to the production server, my-thing.example.com.

Can you help me crystallize my ideas? Suggest how this might be made to work?

Have your app listen on localhost on different ports and use a reverse proxy (e.g. traefik, caddy, nginx) to route both domains to different ports.

1 Like

I’m already using nginx to route the requests to the relevant server, according to domain name.

My question is more about how to get the current build artefacts for the dev version, onto the server without doing a full nixos-rebuild or similar.

It’s about stable and rollback-able evolution of the production version, versus flexible and lightweight deployment of the experimental version.

It’s about having two versions of the code which might not co-exist in any single VCS commit, to run simultaneously on the same NixOS server.

It’s about decoupling the deployment of production and dev (and, sandbox, beta, etc.). That is to say, I don’t want to have a single commit which contains the current implementation of each of prod, dev, sandbox, beta and more; rather I want to be able to have a single implementation per commit, check out whichever commit I want, and deploy it on the subdomain of my choice, without affecting the others.

Maybe this is a job for NixOS containers? About which I know almost nothing.

You probably want sth. like GitHub - erikarvstedt/extra-container: Run declarative NixOS containers without full system rebuilds or Intro - microvm.nix for better isolation.

I’m looking forward to your write-up/tutorial on this topic!

1 Like

There are many ways I can think of:

  • Do remote development on the server and just run the binary while working on it (e.g. use something like entr for automatic rebuilds
  • Change the route to your development work station and run the binary temporarily there
  • Create a systemd service that regularly checks a git repo on a given branch for changes, rebuilds and restarts another systemd service that runs the backend
  • Docker container

It really depends on your needs how much isolation you want, who needs to access your dev server, etc.