A Single Virtual Machine Is Not Automatically a Deployment

Putting software on a single VM is not automatically deployment. If the server depends on manual setup, hidden state, and one engineer’s memory, it is just a remote laptop. Real deployment is reproducible, observable, and disposable.

Moving an application from your laptop onto a virtual machine can feel like deployment, but often, it is just remote local development.

If an engineer SSHs into a long-lived server, installs dependencies manually, copies files across, starts a process, and fixes problems directly on the machine, the application may be publicly accessible, but there is still no reliable deployment system. The server has simply become another developer machine, except now users depend on it.

The problem is not the virtual machine itself. A single VM can be a perfectly legitimate production architecture. For many applications, it may be simpler, cheaper, and more reliable than a distributed platform. The problem is treating that machine as an irreplaceable artifact.

Real Deployments Are Reproducible

A real deployment should be reproducible. You should be able to take a clean machine and reconstruct the application from source code, configuration, and automation. You should know exactly which version is running, how it was built, how it receives secrets, how migrations are applied, how processes restart, and how a failed release is reversed.

If the production environment depends on changes that exist only in one server’s shell history, it is not meaningfully deployed. It is hand-maintained state.

The simplest test is destructive: if the virtual machine disappeared today, could the team recreate the service predictably without relying on the memory of the engineer who configured it?

If the answer is no, the system has been hosted, but the deployment path has not been engineered.

My Extremely Simplified Workflow

Generally, you want to rely on CI/CD (Continuous Integration, Continuous Deployment) to automatically deploy new versions of your application upon a push into your codebase.

My general workflow for deploying web apps and backend applications looks like this:

GitHub -> Vercel or Railway

It looks simple, because it is! Services such as Vercel or Railway handle all the CD pipelines for you. Deployment feels hard not because deployment itself is hard; instead it feels difficult because it forces people to have good archiecture.