Next.js hosting is running the production server of a Next.js app, the Node.js process that next start launches, on a platform that builds it from your repository, keeps it running and serves its pages, route handlers and server actions over HTTPS.
You built the app with create-next-app, it runs on localhost:3000, and Vercel was the default place to put it. Then something pushes you to look elsewhere: a bill that grew with traffic, a feature that shells out to ffmpeg, a background job that runs longer than a request, or a database you want next to the app instead of across the internet.
Most guides for running Next.js anywhere else start with writing a Dockerfile. On Fly.io that step does not exist: fly launch detects Next.js and writes the Dockerfile and fly.toml for you, and fly deploy ships it.
Can Next.js Be Self-Hosted?
Yes. Next.js lists four ways to deploy: as a Node.js server, as a Docker container, as a static export, or through a platform adapter.[2] The Node.js server is the complete one. next build compiles the app and next start serves it, and Next.js documents image optimization through next/image and Proxy (the request-level logic previously called middleware) as working self-hosted with zero configuration under next start.[1]
A static export is the exception. It writes HTML, CSS and JavaScript files that any web server can hand out, and it gives up everything that needs a running server: Proxy, server actions, route handlers that read the incoming request, and pages regenerated on demand. Once an app uses any of those server features, it needs a host that runs the Next.js server.
What Does a Next.js App Need From a Host?
A Next.js app needs a Node.js process that stays up, a way to separate build-time settings from runtime secrets, and a plan for its cache once more than one copy of the app is running. Next.js documents each of these in its self-hosting guide, and they are the points where hosts actually differ.[1]
A process that stays up
Server actions, route handlers and streamed responses all execute inside the Next.js server. On a host that runs that server as a normal process, a request is not cut off by a per-invocation time limit, a WebSocket can stay open, and a native binary such as ffmpeg can run beside Node because it is installed in the same image. On a host that runs the app as functions, each request is a separate invocation with a duration limit. That is the line that decides whether a video-processing route or a long report export works without a separate background worker.
Build-time and runtime environment variables
Next.js reads environment variables at two different times. Variables prefixed NEXT_PUBLIC_ are inlined into the JavaScript bundle during next build, so they are fixed in the image. Server-side variables are read at runtime during dynamic rendering, which lets one build be promoted through staging and production with different values.[1] A host needs a place for both: build arguments for the public values, and runtime secrets for database URLs and API keys that should never be compiled into anything.
The cache, once there is more than one server
Next.js keeps its server cache, including pages regenerated with Incremental Static Regeneration (ISR), on the local disk of each server instance by default. That works automatically for a single next start process with a persistent disk. Run two instances and each keeps its own copy, so one can serve a page the other has already regenerated. The fix Next.js documents is a custom cacheHandler in next.config.js, with the in-memory cache turned off, so every instance reads and writes the same store.[1]
Do You Need Docker to Host Next.js Outside Vercel?
No. Most platforms run a container image, but a platform with framework detection reads package.json, sees the next dependency and generates the build itself, so there is no Dockerfile for you to write. On Fly.io, fly launch does exactly that and writes the Dockerfile and fly.toml into the repository.
Why the Dockerfile shows up everywhere
Next.js lists a Docker container as a deployment option,[2] and a Dockerfile is the most portable way to describe a build, so tutorials for leaving Vercel tend to start with one. That path works, and it makes the Dockerfile look like the entry fee. On a host that detects the framework, the Dockerfile is an output of the deploy tool rather than an input you author. If you already have one, the Docker hosting options all take it as is.
Where Can You Host Next.js Besides Vercel?
Fly.io, for a Next.js app that runs as a real server: fly launch detects the app and writes its Dockerfile and fly.toml, and the app runs as a long-lived Node.js process on a Fly Machine with no per-invocation time limit. The other hosts split into two groups. Function platforms run each server feature as a separate invocation, and server platforms run next start as a process.
| Host | How Next.js runs | What builds it | Limit to know |
|---|---|---|---|
| Vercel | Vercel Functions on Fluid compute | Framework detection | Functions default to 300 seconds; Pro allows up to 800 |
| Netlify | A Netlify Function for server rendering, ISR, route handlers and server actions | The OpenNext adapter, automatically | Proxy runs on Edge Functions, with documented limitations |
| Cloudflare Workers | Workers, through the OpenNext adapter or Cloudflare’s vinext | vinext or OpenNext tooling | Compatibility is checked per app |
| Railway | A Node.js service running the start script | Railpack from source, or a Dockerfile | Standalone output needed for the Dockerfile path |
| Render | A Node.js web service | Build and start commands | |
| Fly.io | A Node.js server on a Fly Machine | fly launch writes the Dockerfile and fly.toml |
Sources: Vercel [3], Netlify [4], Cloudflare [5], Railway [6], Render [7]. Checked 2026-10-30.
The function platforms suit an app whose server work fits inside a request. Once the app holds a WebSocket, runs a native binary or does minutes of work per request, the server platforms are the better fit, because nothing ends the process when a response is sent.
A rented server is the remaining option. It gives you root and leaves the Node.js install, the process supervisor, the reverse proxy Next.js recommends in front of the server,[1] certificate renewal and OS patching to you. The Node.js hosting guide covers that trade in detail.
How Much Does Next.js Hosting Cost?
Next.js itself costs nothing to use: it is open source under the MIT license,[8] so the cost is entirely the hosting, and the hosting bill depends on which of two billing shapes the platform uses.
Paying per invocation
Function platforms bill for what each request consumes: invocations, the compute time they run for, and the bandwidth they send. A quiet app costs little. A busy one, or one where image optimization and server rendering run on most requests, grows with traffic in a way that is harder to predict than a server’s hourly rate.
Paying for a running server
Server platforms bill for the size of the machine and the time it runs. The variables are memory, CPU and hours, which can be worked out before the first deploy. Platforms that stop idle servers and start them on the next request narrow the gap with function pricing for apps with quiet hours. The PaaS pricing comparison lays the main platforms side by side.
Next.js Hosting on Fly.io
Fly.io deploys a Next.js app with no Dockerfile to write. An abridged fly launch run:
$ fly launch
Creating app in /home/dev/storefront
Scanning source code
Detected a Next.js app
We're about to launch your Next.js app on Fly.io. Here's what you're getting:
...
Wrote config file fly.toml
...
Visit your newly deployed app at https://storefront.fly.dev/
$ ls
Dockerfile app fly.toml next.config.js package.json
In the run recorded in the Next.js deployment guide, the plan is the app name, a region, and a shared-cpu-1x Machine with 1 GB of RAM. After that, every change ships with fly deploy.
The Dockerfile comes from a generator. fly launch produces it with Fly.io’s open-source Dockerfile generator for Node.js apps. If next.config.js sets output: "standalone", the generated Dockerfile copies only the standalone server into the final image, which the deployment guide says cuts about 400 MB from the image compared with copying the whole build. A route that needs a system package gets it by rerunning the generator with npx @flydotio/dockerfile --add ffmpeg, an option documented in the generator’s README, which rewrites the Dockerfile with the package installed. If the repository already has a Dockerfile, fly launch uses that one instead.
The database is offered when the app uses one. flyctl’s scanner for JavaScript apps checks the dependencies: when package.json includes the pg driver, or a Prisma schema declares a postgresql provider, fly launch offers to set up Postgres during the same run. For production, Managed Postgres is created with fly mpg create and connected with fly mpg attach, which sets DATABASE_URL as a secret the app reads at runtime. Managed Postgres takes automatic backups and fails over to a standby automatically, and a cluster can be restored to a point in time within its recovery window, into a new cluster, leaving the original untouched. It is a separate plan, starting at $38 a month for Basic.
The server is a process, not a function. The app runs next start on a Fly Machine, so there is no per-invocation time limit on server actions, route handlers or streamed responses, and a WebSocket is an ordinary connection to that process. Machines stop and start with traffic. On the published pricing for Ashburn (iad) and Secaucus (ewr), a stopped Machine is billed only for its root file system at $0.15 per GB per month, and a running shared-cpu-1x Machine with 1 GB of RAM is $6.70 a month, billed by the second. Any configuration can be priced before deploying at fly.io/calculator.
A worked monthly cost. A Next.js app on one shared-cpu-1x Machine with 1 GB of RAM running all month ($6.70), a Managed Postgres Basic cluster ($38.00), 1 GB of database storage ($0.28) and 10 GB of outbound data ($0.20) comes to $45.18 a month in Ashburn (iad). With auto-stop, the Machine line drops for the hours it is stopped.
The ISR cache is per Machine. A Machine’s root file system starts blank every time the Machine starts, after a deploy or after auto-stop, so a single Machine rebuilds its ISR cache as pages are requested again. To keep the cache across restarts, or to share it across two or more Machines, configure a cacheHandler that writes to a shared store, as Next.js documents.
Frequently Asked Questions
Do I need to write a Dockerfile to deploy Next.js on Fly.io?
No. Running fly launch in a Next.js project detects the framework, generates a Dockerfile and fly.toml, and deploys the app. If the project already has a Dockerfile, Fly.io uses it instead. Extra system packages are added by rerunning the Dockerfile generator with an option rather than by writing one.
Does Next.js cost anything to use?
Next.js is open source under the MIT license, so the framework itself costs nothing. The cost is the hosting. On Fly.io a Next.js app is billed by the second for the Machine it runs on, and the price of any configuration can be checked in the Fly.io pricing calculator before deploying.
Is Next.js just frontend?
No. Next.js runs server code as well as React components: route handlers, server actions, server-side rendering and Proxy all execute on the Next.js server. On Fly.io that server runs as a long-lived Node.js process on a Fly Machine, so backend work runs inside the same app as the pages.
Is Vercel the best host for Next.js?
No, not for every app. Vercel runs Next.js as functions with a per-invocation duration limit. Fly.io runs the Next.js server as a long-lived process, which suits apps that hold WebSockets, run native binaries such as ffmpeg, or do long work per request, and fly launch writes the build for you.
Does Next.js ISR work when self-hosting?
Yes. Incremental Static Regeneration works with next start and stores its cache on the server’s local disk. On Fly.io that disk is the Machine’s root file system, which starts blank each time the Machine starts, so pages regenerate as they are requested again. With two or more Machines, configure a shared cacheHandler so every Machine serves the same regenerated pages.
Can a Next.js app run ffmpeg or other native binaries?
Yes, when the app runs as a server with the binary installed in its image. On Fly.io the Dockerfile generator adds Debian packages such as ffmpeg with one option, and the Next.js server calls the binary from a route handler or server action on the same Machine.
Do Next.js server actions and API routes work outside Vercel?
Yes. Server actions and route handlers are part of the Next.js server and run anywhere next start runs. On Fly.io they run on the app’s Fly Machine, which runs the server as a process, so there is no per-invocation time limit.
How do I add a Postgres database to a Next.js app on Fly.io?
Create a Managed Postgres cluster with fly mpg create, then connect it to the app with fly mpg attach, which sets DATABASE_URL as a secret. Fly.io also offers Postgres during fly launch when the app’s dependencies include the pg driver or a Prisma schema for PostgreSQL.
Sources
- ^ Next.js, “How to self-host your Next.js application”. nextjs.org/docs/app/guides/self-hosting. Checked 2026-10-30.
- ^ Next.js, “Deploying”. nextjs.org/docs/app/getting-started/deploying. Checked 2026-10-30.
- ^ Vercel, “Vercel Functions Limits”. vercel.com/docs/functions/limitations. Checked 2026-10-30.
- ^ Netlify, “Next.js on Netlify”. docs.netlify.com/build/frameworks/framework-setup-guides/nextjs/overview. Checked 2026-10-30.
- ^ Cloudflare, “Next.js on Cloudflare Workers”. developers.cloudflare.com/workers/framework-guides/web-apps/nextjs. Checked 2026-10-30.
- ^ Railway, “Deploy a Next.js App with Postgres”. docs.railway.com/guides/nextjs. Checked 2026-10-30.
- ^ Render, “Deploy a Next.js App”. render.com/docs/deploy-nextjs-app. Checked 2026-10-30.
- ^ Vercel, “next.js repository license”. github.com/vercel/next.js/blob/canary/license.md. Checked 2026-10-30.