Deploying Next.js on a VPS with Coolify or Dokploy
TL;DR: Self-hosted platform tools like Coolify and Dokploy give you push-to-deploy, automatic TLS and container management on your own VPS, which covers most of what managed platforms provide at a fraction of the recurring cost once you have real traffic.
What people underestimate is build memory and rendering modes. A Next.js production build routinely needs more memory than the app does at runtime, so a 2GB VPS that runs the app fine will fail during the build. And features that managed platforms provide invisibly — image optimisation, incremental regeneration, edge middleware — behave differently or need explicit configuration when self-hosted, which is where most "it worked in development" failures come from.
Why self-host a Next.js app at all
Managed platforms are excellent and the free tiers are genuinely generous. The case for moving is specific rather than universal.
Cost at scale. Managed platform pricing is usage-based, and bandwidth and function invocations add up. A VPS costs the same whether it serves ten thousand requests a month or ten million, within its capacity. The crossover point arrives faster than people expect on media-heavy sites.
Long-running work. Serverless functions have execution time limits. If your application needs background jobs, long-running processes, WebSocket connections or scheduled work beyond those limits, a persistent server is the natural fit.
Colocated services. Running your database, cache and application on the same machine removes network latency between them. For an India-focused application, having everything in an Indian region rather than split across a platform's regions and a separate database provider is a real latency improvement.
Data location control. You choose where the data physically sits, and you reduce the number of third parties processing it, which simplifies your vendor register under India's data protection framework, as covered in the DPA checklist.
No cold starts. A persistent Node process does not cold start.
The counter-case is real. Managed platforms handle scaling, global distribution, DDoS absorption and zero-downtime deploys without you thinking about them. Self-hosting means you own uptime, patching, monitoring and recovery. If your traffic is modest and your budget allows the managed tier, the time cost of self-hosting may exceed what you save.
What a self-hosted PaaS gives you
Deploying Next.js manually means writing a Dockerfile, configuring a reverse proxy, provisioning certificates, setting up a process manager and building your own deploy pipeline. Workable, and a lot of moving parts to maintain.
A self-hosted platform layer handles that.
Git-based deployment. Connect a repository, push, and the platform builds and deploys. This is the feature that makes the workflow feel like a managed platform.
Automatic TLS. Certificates issued and renewed without configuration, which removes the most common self-hosted outage: an expired certificate nobody was monitoring.
Container orchestration. Applications, databases and caches as managed services with sensible defaults, rather than hand-written Compose files.
Environment variable management through a UI rather than files scattered across the server.
Log aggregation and basic metrics, so you are not tailing files over SSH to find out why a deploy failed.
Preview deployments on branches, in the tools that support it.
Backups for managed databases, scheduled and configurable.
Rollback. Reverting to a previous deployment as an action rather than a git operation and rebuild.
What you still own: the server itself, the operating system, security patching, capacity planning, and the platform tool's own updates. It removes the deployment plumbing, not the system administration.
Coolify and Dokploy compared
Both are open source, self-hosted, Docker-based platform layers with similar goals. Choosing between them is mostly about maturity versus simplicity.
Coolify is the more established of the two, with a larger community, a broader catalogue of one-click services, and more features generally. It supports multi-server deployments, has a more developed ecosystem, and you will find more community answers when something goes wrong.
The cost of that breadth is complexity and a slightly heavier footprint. There is more surface area to understand, and more that can behave unexpectedly.
Dokploy is newer and deliberately simpler, with a cleaner interface and a smaller feature set covering the common cases well. Lighter on resources, faster to understand, fewer moving parts.
The cost is a smaller community, fewer prebuilt integrations, and less material to consult when you hit something unusual.
Practical selection: if you want breadth, multi-server capability and the best chance of finding an answer when stuck, Coolify. If you are deploying a handful of applications and value simplicity, Dokploy.
Either way, understand what is underneath. Both are orchestrating Docker containers and a reverse proxy. When something breaks, debugging happens at the Docker level, so knowing what containers are running and how to read their logs is not optional. A platform tool abstracts the workflow, not the system.
Budget 500MB to 1GB of RAM for the platform tool itself, separate from your application.
Sizing, and the build memory trap
The single most common failure when moving from a managed platform to a VPS.
Build memory exceeds runtime memory. A Next.js production build compiles TypeScript, bundles JavaScript, generates static pages and optimises assets, and peak memory during that process is frequently several times what the running application needs.
An application that serves traffic happily in 400MB can fail to build in 2GB. The build gets killed by the out-of-memory killer, and the error is often unhelpful — a process terminated without explanation, or a generic build failure.
Why it surprises people: managed platforms build on their own infrastructure with generous memory, then deploy a small runtime artifact. Self-hosting means the same machine does both.
Practical sizing:
2 vCPU, 4GB is the realistic minimum for building and running a modest Next.js application alongside a platform tool and a small database. A 2GB instance will run the app and struggle to build it.
4 vCPU, 8GB for a larger application, multiple applications, or a build with many static pages.
Mitigations if you are memory constrained: add swap so a spike degrades rather than kills, which is worth doing regardless as covered in the new VPS checklist. Raise Node's heap limit explicitly if the default is the constraint. Or build elsewhere — in CI — and deploy the resulting image, which is the cleanest answer and removes build memory from your server sizing entirely.
Also account for the database. PostgreSQL alongside the application on the same box needs its own allocation, and defaults are often tuned for a dedicated machine.
Rendering modes and what changes when self-hosted
Next.js supports several rendering strategies, and their behaviour differs when self-hosted in ways that cause confusing failures.
Static generation. Pages built at build time and served as static files. This works identically self-hosted and is the simplest case.
Server-side rendering. Pages rendered per request by the Node process. Works fine, and the consideration is capacity: every request consumes CPU, so you are sizing for concurrent rendering rather than static file serving.
Incremental static regeneration. Pages regenerated in the background after a revalidation interval. This works self-hosted, with an important caveat: the regenerated pages are written to the local filesystem, so running multiple instances means each has its own cache and they diverge. Single-instance deployments are unaffected; multi-instance needs shared cache configuration.
Image optimisation. Managed platforms provide this as an invisible service. Self-hosted, the optimisation runs in your Node process, consuming CPU and memory per image and caching results locally. This is the most common source of unexpected resource consumption after builds.
Options: leave it enabled and size for it, configure an external image optimisation service, or disable the built-in optimiser and serve pre-optimised images.
Middleware. Designed to run at the edge on managed platforms. Self-hosted it runs in your Node process, so latency characteristics differ and heavy middleware affects every request.
The general principle: the more your application depends on platform-provided services rather than the Next.js runtime itself, the more you need to replace explicitly when self-hosting. Applications that are mostly static generation and server-side rendering migrate cleanly. Applications leaning heavily on edge features and platform image handling need more work.
| Factor | Managed platform | Self-hosted VPS + PaaS |
|---|---|---|
| Cost model | Usage-based | Fixed server cost |
| Cost at low traffic | Often free | ₹999+ monthly |
| Cost at high traffic | Scales up sharply | Flat within capacity |
| Setup time | Minutes | A few hours |
| Build infrastructure | Theirs, generous memory | Yours, size for it |
| Global distribution | Built in | CDN needed separately |
| Scaling | Automatic | Manual resize |
| Long-running processes | Limited by execution caps | Unrestricted |
| Image optimisation | Provided | Runs on your server |
| Edge middleware | Real edge | Runs in your Node process |
| Zero-downtime deploys | Standard | Depends on configuration |
| Uptime responsibility | Theirs | Yours |
| Data location control | Region selection | Full control |
Setting up the deployment
The sequence, assuming a hardened VPS.
Harden the server first. Updates, non-root user, SSH keys, firewall permitting only 22, 80 and 443, fail2ban. This is a machine that will hold your application and probably your database.
Point DNS. An A record for your application hostname and one for the platform tool's own interface, before installation, so certificate issuance succeeds on first attempt.
Install the platform tool. Both Coolify and Dokploy install via a single script that sets up Docker and their control plane. It takes a few minutes.
Secure the control panel immediately. It can deploy code and read your environment variables, which makes it one of the most sensitive interfaces you run. Strong credentials, two-factor if supported, and consider restricting access to a VPN interface rather than exposing it publicly — the WireGuard guide covers that pattern.
Connect your repository via the platform's git integration, granting only the access it needs.
Configure the build. Most tools detect Next.js automatically. Check the build command, the output mode and the Node version match what your project expects. Next.js standalone output mode produces a substantially smaller runtime image and is worth enabling.
Set environment variables through the platform UI. Remember the distinction between build-time and runtime variables in Next.js, since variables needed during the build must be available then, not only at runtime. This trips people up regularly.
Provision the database as a managed service in the platform if you need one, and note the internal connection string.
Deploy and watch the build log. The first build is where memory problems and missing environment variables surface.
Verify TLS issued correctly and the site loads over HTTPS.
Configure backups for the database. The platform's scheduled backups are a start; push copies offsite as well, following the 3-2-1 pattern.
Things that break and how to avoid them
Build killed by out of memory. The most common first failure. Add swap, raise Node's heap limit, or build in CI and deploy the image.
Missing build-time environment variables. Variables inlined at build time must be present during the build. A variable set only for runtime produces an application that builds successfully and misbehaves at runtime, which is harder to diagnose than a clean failure.
Deploys that briefly drop traffic. Naive container replacement means a gap between stopping the old container and the new one becoming ready. Configure health checks so the proxy only routes to a ready container.
Disk filling with old images. Every build produces Docker images and layers, and without pruning the disk fills, which takes down everything on the server. Schedule cleanup and alert on disk usage at 80%. This is one of the most common self-hosted PaaS outages and it is entirely predictable.
Image optimisation consuming resources. A traffic spike on an image-heavy page can saturate CPU. Decide deliberately whether to optimise on the server, offload to a service, or pre-optimise.
Database connection exhaustion. Serverless deployments needed connection pooling for a specific reason; a persistent server has different characteristics, but a misconfigured pool still exhausts connections under load.
Filesystem writes assumed to persist. Anything written into the container disappears on redeploy. Uploads and generated files need a mounted volume or object storage.
Platform tool updates breaking things. These are actively developed projects. Read release notes, and back up before updating the platform itself.
No staging environment. Deploying straight to production because the workflow makes it easy. Use a separate application or branch deployment for testing.
Operating it in production
Monitor from outside, hitting a route that exercises the application rather than a static asset, so you detect a Node process that has died while the proxy still answers.
Alert on disk usage at 80%. Docker image accumulation is the leading cause of self-hosted PaaS outages.
Alert on memory. Approaching the limit is actionable; hitting it is an outage.
Watch application logs through the platform's aggregation rather than SSHing to tail files.
Keep the server patched with automatic security updates, and update the platform tool deliberately after reading release notes.
Test a database restore quarterly. Scheduled backups you have never restored are a hypothesis.
Know your rollback path before you need it. Both tools support reverting to a previous deployment; confirm it works once, on a low-stakes deploy, rather than discovering its quirks during an incident.
Plan capacity. A VPS does not scale automatically. Know your headroom and know how long a resize takes, since some providers require a reboot. If you have predictable traffic events, provision ahead rather than reacting.
Consider a CDN for static assets if your audience is geographically spread, since a single VPS serves from one location.
Document the setup. Which server, which platform tool, where the backups go, how to roll back, who has access. Self-hosted infrastructure that only one person understands is a risk to the business, not just to the application.
FAQs
Can I run Next.js on a normal VPS?
Yes. Next.js runs as a Node process and needs nothing exotic. A self-hosted platform tool such as Coolify or Dokploy adds git-based deployment, automatic TLS and container management, giving you a workflow close to a managed platform on infrastructure you control.
What VPS size do I need for Next.js?
2 vCPU and 4GB of RAM is the realistic minimum for building and running a modest application alongside a platform tool and a small database. A 2GB instance will typically run the application fine and fail during the build, because a Next.js production build consumes considerably more memory than the running application does.
Why does my Next.js build fail on the VPS but work locally?
Almost always memory. The build compiles, bundles and generates pages, with peak memory several times the runtime requirement, and the out-of-memory killer terminates it with an unhelpful error. Add swap, raise Node's heap limit explicitly, or build in CI and deploy the resulting image.
Should I use Coolify or Dokploy?
Coolify if you want breadth, multi-server support and a larger community to consult when something breaks. Dokploy if you are deploying a handful of applications and prefer a simpler, lighter tool. Both orchestrate Docker underneath, so debugging happens at the container level either way.
Does incremental static regeneration work when self-hosted?
Yes, with a caveat. Regenerated pages are written to the local filesystem, so a single instance works normally while multiple instances each maintain their own cache and diverge. Multi-instance deployments need shared cache configuration; single-instance deployments are unaffected.
What happens to Next.js image optimisation on a VPS?
It runs in your Node process rather than as a platform service, consuming CPU and memory per image and caching results locally. This is a common source of unexpected resource use on image-heavy sites. You can size for it, offload to an external optimisation service, or disable the built-in optimiser and serve pre-optimised images.
Does Next.js middleware work the same self-hosted?
It runs, but in your Node process rather than at a real edge location, so latency characteristics differ and heavy middleware adds cost to every request. Applications leaning heavily on edge features need more consideration when migrating than those built mostly on static generation and server-side rendering.
Is self-hosting cheaper than a managed platform?
At low traffic, usually not, since managed free tiers are generous and a VPS costs from around ₹999 a month. At higher traffic, particularly media-heavy applications where bandwidth dominates, self-hosting becomes clearly cheaper because the cost is flat within capacity rather than scaling with usage.
How do I avoid downtime during deployments?
Configure health checks so the reverse proxy only routes traffic to a container that reports ready, rather than replacing containers naively. Both Coolify and Dokploy support this, but it usually needs configuring rather than being on by default, and it is worth verifying with a test deploy.
Why is my server disk filling up?
Docker images and build layers accumulating from every deployment. This is the most common self-hosted PaaS outage and it is entirely predictable. Schedule image pruning and set a disk usage alert at 80%, because a full disk takes down every service on the machine at once.
Where do file uploads go on a self-hosted Next.js app?
Not into the container, since anything written there disappears on redeploy. Use a mounted volume that persists across deployments, or object storage, which is the better answer if you may ever run more than one instance or want backups handled separately.
How do I secure the Coolify or Dokploy control panel?
Treat it as one of your most sensitive interfaces, since it can deploy code and read every environment variable. Use strong credentials and two-factor if supported, and consider binding it to a VPN interface rather than exposing it publicly so it is unreachable from the internet entirely.
Conclusion
Self-hosting a Next.js application is more approachable than it was, and a platform tool on a VPS genuinely delivers most of the managed workflow: push to deploy, TLS handled, logs in one place, rollback as a button.
The decision is economic rather than technical for most teams. Below meaningful traffic, managed platforms are cheaper once you price your own time. Above it, particularly with heavy bandwidth, a fixed server cost wins clearly and keeps winning as you grow.
Size for the build, not the runtime. This is the mistake that catches almost everyone moving off a managed platform, because those platforms build on their own generous infrastructure and hand you a small artifact. On your own server, the same machine does both, and a 2GB instance that runs your app comfortably will fail to compile it.
Then be deliberate about the platform-provided features you are replacing. Static generation and server-side rendering migrate cleanly. Image optimisation and edge middleware move into your Node process and become your CPU problem, which is fine once you have decided it consciously rather than discovering it under load.
And schedule disk cleanup on day one. Docker image accumulation is the single most predictable way a self-hosted deployment falls over, and an alert at 80% costs nothing.
HostCloud runs Linux VPS plans from ₹999 a month on NVMe with full root access and Indian data centres, which keeps latency low for India-focused applications and colocates your database with your app. Details at https://hostcloud.in.
