Hacker News new | ask | show | jobs
by q3k 2025 days ago
How do you handle multiple versions of the same project/software/deployment on the same machine?
7 comments

You can for example have many SQL databases on the same db server, or many web sites on a www server. So you solve it with configuration. If you need different kernels you have to use virtual servers anyway.
The simple answer is you can choose not to. In many ways, a VM is a better abstraction than a container due to the simplicity of virtualising the hardware interface, as opposed to creating another abstraction layer in the kernel dealing with process isolation, permissions and system controls.
On the other hand, VMs are wasteful resource-wise (and $$$-wise) and have a much larger operational overhead (suddenly for every deployment you have a different Linux installation, with its own root /, with its own configuration drift, which you have to manage separately via CM).
To be fair, containers often end up being its own Linux installation with its own configuration drift. So many dockerfiles mindlessly pull in an entire Ubuntu system just to run a simple app.
But the image [1], once built, is still idempotent. You can deploy it and it will always contain the same configuration and code.

Meanwhile, a month-long Ubuntu VM that has received regular CM pushes (including system updates) will likely vastly differ from a branch new Ubuntu VM and a single CM push. To the point, where you can't be sure anymore that your current CM config will even work on a brand new machine, unless you're regularly testing that.

[1] - Yes, Dockerfiles do not make for reproducible builds - but once an OCI image is built, its deployment going to be reproducible. And there's more ways to build images than via Dockerfiles - some of which solve this problem (using Nix or Bazel, for example).

> But the image [1], once built, is still idempotent. You can deploy it and it will always contain the same configuration and code.

VMs can be idempotent too. It's just that traditionally people attach storage to it. But VM snapshots are a thing.

> To the point, where you can't be sure anymore that your current CM config will even work on a brand new machine, unless you're regularly testing that.

The same can be argued about attached storage to a container.

By idempotent do you mean immutable?
That same issues exists with docker containers. You can also build a pipeline to deploy very barebones VMs that contain the kernel, a barebones userland and the application. Use KSM to minimise memory usage. What you get with containers is a shared page cache and reduced context switching.

Once upon a time in tech, the thinking was hardware is cheap, technical staff is expensive, hence we moved on to systems and programming languages that saved us time at the expense of efficiency on the hardware.

20 years on, the cost equation hasn't changed. In fact, its probably shifted drastically towards the extremes. We'd likely save more energy by eliminating crypto mining than moving all VMs onto containers.

On my development laptop: a mix of VMs, docker containers, language/package managers. It's a per project choice, either mandated by my customers or advised by me. To name a few technologies I'm using right now in three different projects open in different virtual desktops:

docker

vagrant

VirtualBox (even some scripts to mimic EC2's spawning of machines with VBoxManage)

asdf (really, my fingers didn't slip on the keyboard)

npm

rvm

python's virtualenvs

I never had the need to do that and I'm not sure in what kind of situation I would.

For updates I just install the new version of the software, then perform a restart (new version starts, once it's ready, old version stops).

each version of the project gets a directory and contains everything the project needs. put all of those into a parent directory. use a symlink to point to the currently active version. E.g.:

    /usr/local/thing/versions/thing-v1.3.7
    /usr/local/thing/versions/thing-v1.4.2
    /usr/local/thing/current -> /usr/local/thing/versions/thing-v1.3.7
I mean, sure, I've done this too with a handful of scripts. But is this something you do via .debs? I'm asking specifically about how to handle this with plain Debian/Ubuntu packaging.
I do it similarly. I run multiple versions of a service at once with systemd service files. It gives me the same stuff as containers - cgroups, isolation, logging, service definitions and automation with ansible, but its easier on my feeble psyche.
Why would you want to do that?
For development, for example. Or for some kinds of shared hosting.
Isn't that a sign of technical debt? Not OP, but for development/testing: in a VM.
How is it technical debt? How else do you handle software rollout and rollback, or canarying? Do you have a VM for every single version of your software?
Uhhh... backups?! Not all companies release daily, weekly, and sometimes not even monthly. Stage the rollout, do your testing, get your evidence, get your plan, perform the release.
So if you deploy a new release which turns out to be buggy, your only recourse is doing a full backup restore?
No there are snapshots for that.
q3k, I can't reply to you at this depth. But yes. You're saying a "full backup / restore" but it's not the entire system.

Let's say you have an app, in a folder, that reads config files from 3 other locations on the machine. It talks to two databases. You back up two databases and 4 total folders. That's your backup. It's simple and straight forward to me.

(you have to wait until you can reply after a certain depth - this is HN's anti-flamewar system kicking in)

I understand you can restore from backups, but this doesn't seem simple to me - especially when you deal with situations where there's more than just one person deploying to production.

In comparison, my rollbacks are performed the same way rollouts/rollforwards are - by editing a single line in Git (ie. changing the OCI image string) and running `kubecfg update`. No need to access backups, no need for special procedures.

I look at it this way. I think it's simpler to do this kind of backup in case things go wrong (which, honestly, is not that often. Twice in 5 years that I can think of off the top of my head) than it is to set up kubernetes, manage kubernetes, and convert our applications to work correctly in kubernetes. All of that is required so that your single line edit becomes a possibility. That's a lot of work to enable that workflow versus copying 5 directories to one location, zipping it, slapping a version tag on the zip file, storing it in a couple of places.
I think it’s flawed to think that you can safely have multiple versions of the same app running (or even installed) simultaneously in the same “universe.” Whether you use jails, VMs, containers, or whatever you should not count on “I didn’t change anything between these two versions that would corrupt the other instance” to help you.
What? Deploying new software is technical debt?
In a real sense, yes. Once it's deployed, it incurs costs, like a debt.

Reminds me of:

> My point today is that, if we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger.

-- Edsger W. Dijkstra