DEV Community

Cover image for How to Deploy Next.js on a VPS with Coolify (Self-Hosted Vercel Alternative)
InterData
InterData

Posted on

How to Deploy Next.js on a VPS with Coolify (Self-Hosted Vercel Alternative)

Deploying Next.js on a VPS with Coolify is where a lot of developers land once their Vercel bill starts climbing with build minutes and bandwidth, or once they need to self-host infrastructure for multiple projects at once. Coolify gives you a dashboard experience close to Vercel's, but it runs on a server you fully control. This walkthrough goes step by step, including the errors you'll actually hit and how to fix them.

Table of Contents

What Is Coolify, and Why Use It Instead of Vercel?

Coolify is an open-source PaaS (Platform as a Service) that you install directly on your own VPS to build, deploy, and manage applications through a web UI — playing a similar role to Vercel or Heroku, but running on infrastructure you control, with no limits tied to a third-party pricing tier.

One distinction worth making upfront: this guide covers self-hosted Coolify, installed on your own VPS — open source, no license fee. Coolify Cloud is the managed SaaS version run by the Coolify team, billed monthly, where you don't manage a server yourself. The two are completely different deployment models even though the UI looks the same, and this article is only about self-hosting.

Coolify runs on top of Docker: every app you deploy gets packaged into its own isolated container on the same VPS. That's what lets Coolify run multiple Next.js apps, or a mix of apps and databases, on a single machine without environment conflicts.

Compared to Vercel, the most common reason developers switch to self-hosting is cost at scale: build minutes, bandwidth, and function invocations are all metered and billed by tier, and they scale up fast as traffic or the number of projects grows. The second reason is wanting control over infrastructure — choosing your own RAM, region, and scaling strategy instead of working within a platform's limits. None of this means Vercel is worse — it's a different cost/control trade-off depending on scale.

What You Need Before Deploying

Before opening the Coolify dashboard, get four things ready: a VPS with root access, a domain you can point at it, source code in Git, and a Next.js project correctly configured for a container environment. Skipping the Next.js configuration step is the single most common reason first-time deployments get stuck.

  • A VPS running Ubuntu with root access over SSH — Coolify installs directly into the OS and won't run on shared hosting.
  • A domain or subdomain with an A record ready to point at the VPS's IP (you can point it after installing Coolify, but setting it up beforehand saves you from waiting on DNS propagation at the SSL step).
  • Next.js source code pushed to a repository on GitHub or GitLab — Coolify pulls directly from there to build.
  • A project that already runs npm run build successfully locally. If the build fails locally, it will fail identically on Coolify — it's just harder to debug because you have to read logs inside a container.
  • If you plan to use the Dockerfile build pack (compared below), add output: 'standalone' to next.config.js so Next.js produces a lean build containing only what's needed at runtime.
  • A list of the environment variables your app needs, with a clear split between which ones are prefixed NEXT_PUBLIC_this distinction determines whether your app works correctly or silently breaks later.

Don't have a root-access VPS yet? InterData's VPS plans come with root access out of the box, which is a hard requirement for installing Coolify.

Installing Coolify on a VPS

Requirements Before Installing

Coolify installs Docker and its other dependencies itself as part of the setup script, so you don't need to install Docker manually beforehand. In practice you need a VPS running Ubuntu (LTS recommended), a stable internet connection to pull images, and enough RAM to run both Coolify and your app's build process at the same time — Next.js builds are typically heavier than the app at runtime, so on a low-spec VPS it's worth running a test build once rather than guessing a RAM number in advance.

Running the Install Script

SSH into your VPS as root, then run Coolify's official install script:

curl -fsSL https://cdn.coollabs.io/coolify/install.sh | sudo bash
Enter fullscreen mode Exit fullscreen mode

The script installs Docker, pulls the required images, and starts Coolify. This takes a few minutes depending on the VPS's network speed.

First Dashboard Login

Once the script finishes, open a browser and go to http://YOUR-VPS-IP:8000 to reach the Coolify dashboard. On first login you create an admin account, then Coolify walks you through configuring a "Server" — the VPS you just installed on — so Coolify knows where to deploy containers.

Pointing a Domain and Auto-Configuring SSL

Coolify uses Traefik as its default reverse proxy, not Nginx, which is what most manual VPS setup guides use. The role is the same — routing traffic from a domain to the right application container — but Traefik is built into Coolify, auto-detects new containers, and issues SSL certificates without you touching a config file.

To point your domain correctly, go to the domain's DNS settings and create an A record pointing at the VPS's IP. Once DNS has propagated (verify with ping yourdomain.com and check it resolves to the right IP), go to the Application in Coolify and assign the domain under Domains — Coolify will automatically call Let's Encrypt to issue a free SSL certificate through Traefik, with no manual Certbot configuration needed.

A common gotcha: SSL can only be issued if the domain actually resolves to the right IP at the moment Coolify calls Let's Encrypt. If you assign the domain too early, before DNS has finished propagating, Coolify will report a certificate issuance failure. The fix is simple: wait for DNS to settle, then retry certificate issuance in Coolify — no other configuration is needed.

Deploying Next.js from a Git Repository

Creating a New Application

In the dashboard, select a Project, then click "New Resource" > "Application". Coolify supports connecting directly to GitHub via a GitHub App (recommended, since it lets you grant access to just the repos you need instead of your whole account), or via a Deploy Key for private repos where you'd rather not install the App. After selecting the repo and branch, Coolify moves to the build pack selection step.

Step 1: Create a Project

Step 2: Add a Resource

Choosing a Build Pack: Nixpacks or Dockerfile?

This decision directly affects build speed, image size, and how much control you have.

Nixpacks auto-detects Next.js and builds it without you writing anything extra — a good fit if you want to deploy fast without deep optimization.

Dockerfile requires you to write your own multi-stage build, but produces a leaner image with granular control over every step, which pairs especially well with Next.js's output: 'standalone'.

Criteria Nixpacks Dockerfile (standalone)
Initial setup Nothing to write, auto-detects the framework You write a multi-stage Dockerfile yourself
Image size Usually larger — keeps the full node_modules Smaller — standalone output copies only what's needed
Build control Limited, depends on how Nixpacks infers your setup Full control: base image, layer caching, build steps
Best for Fast deploys, simple projects, getting started with Coolify Production traffic, lean images, long-term build stability

If you're just testing a deploy or running a small personal project, Nixpacks is enough and saves setup time. For real production apps — especially if you plan to run several apps on the same Coolify instance — Dockerfile with standalone output is worth the investment: a lighter image means faster deploys and less resource use per build.

Here's how Coolify stacks up against manually configuring your own infrastructure:

Criteria Coolify (self-hosted) Vercel Manual Nginx/PM2
Cost Only pay for the VPS, no build/bandwidth metering Free at small scale, scales with build minutes/bandwidth Only pay for the VPS, no software fee
SSL, domain Automatic via Traefik + Let's Encrypt Automatic, built-in Manual Certbot setup
Auto-deploy on push Yes, via built-in webhook Yes, by default Requires your own CI/CD script
Initial setup time Moderate — install Coolify, then connect a repo Very fast, almost no configuration Slowest, everything done by hand

Environment Variables: Build-Time vs Runtime

An empty NEXT_PUBLIC_* environment variable after deploying is the single most common issue when running Next.js on Coolify. The cause: Next.js bakes any variable prefixed NEXT_PUBLIC_ directly into the JavaScript bundle at next build time, not when the container starts at runtime.

In Coolify, Environment Variables come in two flavors: Runtime Variables (injected into the container only when it starts) and Build Variables (available during the image build). If you only declare NEXT_PUBLIC_API_URL as a Runtime Variable and forget to flag it as available at build time, the app still runs and throws no error — but the value baked into the client bundle will be an empty string, because it wasn't there during the build.

The fix in Coolify: when adding an environment variable for an Application, enable the option that marks it available at build time (shown as "Is Build Variable?" or "Available at Buildtime" depending on the Coolify v4 version). For every NEXT_PUBLIC_ variable, always enable this — otherwise, no matter how correctly you set it at runtime, the bundle never receives it.

If you're using a custom Dockerfile build pack instead of Nixpacks, there's one more step that's easy to miss: Nixpacks automatically forwards Coolify's Build Variables into the build process, but a custom Dockerfile does not do this automatically — you have to declare it explicitly:

ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL

RUN npm run build
Enter fullscreen mode Exit fullscreen mode

Without this ARG/ENV pair, setting the Build Variable correctly in Coolify's UI does nothing, because the Docker build stage has no way to receive that value. This is a real difference between the two build packs that a lot of guides don't mention.

For variables without the NEXT_PUBLIC_ prefix — like a server-side database connection string — declaring them as Runtime Variables is enough, since they're read at runtime inside Server Components or API Routes and never get hardcoded into the client bundle.

Setting Up Auto-Deploy on Push

Coolify can automatically redeploy every time your repository gets new code. Once a webhook is configured, every push to the branch your Application uses sends an event to Coolify, which then pulls the new code, builds it, and redeploys — no manual Deploy click needed.

To set this up, open the Application in Coolify and go to Webhooks. Under Manual Git webhooks → GitHub, Coolify provides two pieces of information:

  • Webhook URL: the address GitHub sends push events to.
  • Webhook secret: a secret string used to authenticate the webhook between GitHub and Coolify.

Next, open the corresponding repository on GitHub and go to Settings → Webhooks → Add webhook. Configure it as follows:

  • Payload URL: paste the Webhook URL from Coolify's Manual Git webhooks → GitHub section.
  • Content type: select application/json.
  • Secret: paste the exact Webhook secret provided by Coolify.
  • Events: choose Just the push event.
  • Active: enable it so the webhook starts working.

Click Add webhook to finish. From your next push to the configured branch, GitHub will send an event to the webhook endpoint and Coolify will automatically trigger a build and deploy the new version.

Note: don't use the URL under Deploy webhook as GitHub's Payload URL — that one is for triggering deployments directly via API or automation tools. For GitHub, use the URL under Manual Git webhooks → GitHub → Webhook URL.

After setup, verify the webhook under GitHub → Settings → Webhooks → Recent Deliveries. If the request returns a 2xx HTTP status and a new deployment shows up in Coolify's Deployment Logs, auto-deploy is working.

For projects with multiple environments like staging and production, create a separate Application per branch. This keeps environment variables, deployment history, and rollback for each environment isolated, and reduces the risk of accidentally deploying the wrong version to production.

Common Errors and How to Fix Them

Build Fails or the Process Dies Unexpectedly

Usually caused by the VPS not having enough RAM for the build. A Next.js build (especially with many routes, images, or a large codebase) consumes far more RAM than the app does at runtime. The fastest fix is to add swap to the VPS to cover the build's peak RAM usage, then monitor actual RAM consumption over a few builds to decide whether you need to upgrade the VPS — don't guess a fixed number in advance, since consumption depends directly on project size.

Domain Returns a 502 Bad Gateway

Most often caused by DNS not having propagated yet, or an A record pointing at the wrong IP. Check with ping yourdomain.com and confirm it matches the VPS IP. If DNS is correct and you're still seeing a 502, check whether the application container is actually running in Coolify — a 502 means Traefik received the request but couldn't reach the container behind it, usually because the container crashed or hasn't finished starting.

SSL Won't Auto-Issue

Let's Encrypt requires the domain to resolve to the correct IP at the exact moment of verification. If you assign a domain to the Application before DNS has finished propagating, Coolify will report a certificate issuance error. Wait for DNS to settle (this can take anywhere from a few minutes to a few hours depending on your domain provider), then retry SSL issuance in Coolify — no further configuration needed.

VPS or Cloud Server for Running Coolify?

If you're only running one or a few Next.js apps on a single Coolify instance, a starter VPS is enough — low cost, and it handles most personal projects, landing pages, or small agency work fine. Things get tight once you start running multiple apps at once, or traffic on one of them spikes: RAM and CPU become the first bottleneck, especially when several apps build in parallel.

Scenario Recommendation Why
One app, stable traffic VPS Low cost, enough resources for a fixed workload
Multiple apps/sites on the same Coolify instance Cloud Server Easier to scale RAM/CPU per app without migrating servers
Traffic that swings heavily over time Cloud Server Scale resources up or down quickly without over-provisioning by default

If you're just getting started with one app, InterData's VPS plans are a straightforward starting point before you need to think about scaling to a Cloud Server.

FAQ

Is Coolify free?
Self-hosted Coolify (installed on your own VPS) is fully open source and free, with no limit on the number of apps or servers you manage. Only Coolify Cloud — the managed SaaS run by the Coolify team — is billed monthly, and that's a different option from what this guide covers.

Will Coolify install on any VPS?
It installs on most Ubuntu VPS instances with root access over SSH. It won't work on shared hosting, since Coolify needs full control over Docker and the OS. If you're running multiple apps, choose a spec with enough RAM to avoid build interruptions.

Can Next.js run on a VPS, or do I need Vercel?
Next.js runs fine on a VPS, including features like Server Components and API Routes, as long as the environment has the right Node.js version. Vercel isn't required — it's a platform optimized specifically for Next.js, while self-hosting via Coolify is a viable alternative for most applications.

Does Coolify auto-deploy on push?
Yes, via webhook. If you connect the repo through a GitHub App, the webhook is registered automatically and you just enable Automatic Deployment. If you use a manual Deploy Key, you'll need to add the webhook yourself in the repository's settings on GitHub or GitLab.

Why does Coolify's build fail when it works fine locally?
Usually insufficient RAM during the build on the VPS, or missing environment variables that haven't been declared in Coolify. For NEXT_PUBLIC_* variables, make sure the build-time availability option is enabled, not just runtime — otherwise the value will be empty even though the build reports no error.

Wrapping Up

Deploying Next.js on a VPS with Coolify isn't much more work than Vercel in terms of steps — the difference is that you're responsible for the infrastructure behind it: installation, SSL, environment variables, and keeping an eye on resources as the number of apps grows. Three things worth remembering: enable Build Variable for every NEXT_PUBLIC_* variable, get DNS ready before issuing SSL, and watch RAM during builds to know when it's time to scale up.

This is an adapted, English-language version of an article originally published in Vietnamese.

Source: Hướng Dẫn Deploy Next.js Lên VPS Bằng Coolify - InterData

Top comments (0)