The StartingUp Summer continues. The season serves as our lookout point: rereading a dense year and delivering an honest account of it. We've told you why step-by-step tutorials no longer survive their publication date; so here's everything a tutorial won't tell you before you host a Next.js application on your own VPS.
Vercel has done the Next.js ecosystem an immense service: deploy by pushing a commit, preview every branch, never think about servers. Then one day, the question shows up, asked by a CFO, a DPO or a public-sector client: "where do our applications run, and how much will it cost next year?". That day, autonomy stops being a developer's whim.
Hosting a Next.js application on a VPS comes down to three decisions: containerize the application with Docker (standalone mode), push the image to a registry, then let a panel like Plesk manage the nginx proxy and the TLS certificate. The cost becomes fixed and known in advance, and your data stays wherever you decided it should. The rest of this article details these decisions, and the traps they hide.
This article is deliberately not a step-by-step guide: that kind of content goes stale faster than it can be written, and an AI agent generates an up-to-date one on demand. What doesn't get generated is the logic behind the decisions. We host our own Next.js projects in Docker containers on our own servers: here's what we wish we'd read before starting.
Why leave Vercel (or never sign up in the first place)
Four reasons keep coming up in conversations with companies who want to leave Vercel, and none of them is a technical whim.
- Cost predictability. Usage-based billing (bandwidth, function invocations, image optimization) is comfortable at first and hard to budget for later: a traffic spike, a crawler going haywire, and the bill follows.
- Data sovereignty. A US PaaS remains subject to US law, whatever its datacenters. For healthcare, legal or the public sector, the requirement of fully controlled European hosting is not negotiable.
- European latency. Server-side rendering runs by default in a North American region (this can be configured, but you have to know to do it). A server in Paris, Strasbourg or Frankfurt puts that rendering a few milliseconds from your users.
- Consolidation. Many companies already pay for a Plesk VPS for their other sites. Adding a Next.js application to it has a marginal cost close to zero.
Let's be honest: if none of these reasons apply to you, staying on a PaaS is a perfectly defensible choice. The developer experience there is unmatched, and autonomy has a price we detail further below.
What a Docker container really changes
A Docker image is a frozen artifact: same code, same dependencies, same Node version, everywhere and forever. Your server no longer runs "some Node someone installed one day", it runs a versioned image that can be rebuilt identically, audited, and rolled back to if something goes wrong. It's this reproducibility, far more than fashion, that justifies the container.
Next.js planned for this with its output: standalone mode: at build time, the framework traces the dependencies actually used and produces a self-contained bundle, without the dead weight of the full node_modules folder. Combined with a two-stage build, you get a final image of a few hundred megabytes instead of several gigabytes, which starts with a single command.
About fifteen lines, given here for the principle: your project will have its own. The essential idea splits in two: the heavy build stage stays confined to an intermediate image discarded afterward; the final image contains only what's needed to serve, and runs with no privileges.
And where does Plesk fit in?
Plesk carries a reputation of old-school PHP hosting. It's outdated: its Docker extension, provided by the vendor, drives a standard Docker install on the server. From the interface, you pull an image from Docker Hub or a private registry, set environment variables and volumes, enable automatic restart. Nothing exotic: it's ordinary Docker, with an admin interface layered on top.
The most elegant part is the web hookup. You map the application's port to a local port on the server, then the domain's Docker proxy rules ask Plesk to write the matching nginx configuration itself, essentially this:
The TLS certificate, meanwhile, stays managed at the domain level, with the one-click Let's Encrypt that Plesk offers for any site: the container doesn't even know HTTPS exists, and that's exactly right.
The limits deserve mentioning too: Plesk manages containers, it doesn't orchestrate anything. No build on the server (the image is built in continuous integration or on a workstation, then pushed to a registry), no rolling deployment, no automatic scaling. To host one application or ten, it's exactly the right tool; for a cluster, it isn't.
The four traps of a self-hosted Next.js
1. Environment variables: build or runtime?
The classic migration trap. Next.js bakes variables prefixed with NEXT_PUBLIC_ into the JavaScript at build time: changing them afterward in Plesk does nothing, the image is already frozen. Only server-side variables get passed to the container at runtime. The practical consequence: either you build one image per environment, or you strictly limit your public variables. Discovering this in production costs an evening; knowing it beforehand costs this paragraph.
2. ISR and disk cache
Incremental static regeneration writes its cache to the container's disk, which is ephemeral by nature: every redeploy starts from zero, with cold pages and a regeneration spike. The fix is simple, mount a persistent volume on the cache folder from Plesk, provided you thought of it. And if you ever aim for several instances of the application, that cache will need to become shared: better to bake that constraint into the architecture from the start.
3. Updates no longer happen on their own
On a PaaS, every commit triggers a build and a release. That pipeline now has to be built: continuous integration produces the image and pushes it to the registry, then Plesk recreates the container, either by hand in the interface or via a script. Recreation imposes a few seconds of downtime, acceptable for most sites, to work around otherwise. On top of that come updates to the server itself: the OS, Docker, Plesk. This is the real price of autonomy, and it's paid in discipline more than money.
4. The healthcheck nobody hands you
A running container isn't a responding application. Add a HEALTHCHECK instruction to the image, a restart policy on the container, and above all external monitoring that alerts you when the site stops responding: on a PaaS, someone was watching on your behalf; here, nobody will unless you decided so. Nothing tricky, but nothing automatic either.
Vercel or VPS: the real cost, without romanticizing it
| PaaS (Vercel-style) | Container on a Plesk VPS | |
|---|---|---|
| Monthly bill | Usage-based, can surprise you | Fixed, known in advance |
| Going live | A single commit is enough | A pipeline to build once |
| Traffic spike | Absorbed, and billed | Sized by you |
| Maintenance | Included and invisible | Your responsibility (OS, Docker, monitoring) |
| Data location | US provider | Chosen, contractual, European if you decide so |
On maintenance, our experience holds no mystery: once the deployment pipeline is in place, upkeep runs to hours per month, not days, but it never drops to zero. On the other side, usage-based billing follows your traffic, including the traffic you don't choose: at a time when generative engines' robots crawl the web more than ever (we noted this while defining GEO), bandwidth billed by volume is a variable you only half control.
An architectural choice, not a dogma
If your constraints talk about sovereignty, a budget to control, or a server already in place, containerizing on your own VPS is today a mature path, and Plesk makes accessible what used to require a live-in devops profile. If they don't, a PaaS remains an excellent choice, and there's no particular glory in administering a server.
The real good news lies elsewhere: a properly containerized Next.js application belongs to no host. The same image runs on your VPS, at another provider, in a European cloud tomorrow if the context demands it. That's perhaps the most concrete definition of sovereignty: not where you host, but the freedom to change without rewriting a single line.






