Vercel is great until your bill isn’t—or until a client asks why their app data is flowing through three US data centers they didn’t approve. Coolify is the open-source PaaS that’s been quietly picking up steam (59k stars and still trending), and it genuinely delivers on the “Vercel UX on your own server” promise —mostly. Here’s how to actually get a Next.js App Router project running on it, and where the sharp edges are.

Let’s go from zero to deployed.

1. What Coolify is and why it’s trending

Coolify is a self-hostable PaaS that sits in front of Docker on your server and gives you a UI for deployments, environment variables, domain management, SSL, and one-click services (Postgres, Redis, Minio, etc.). Think Heroku’s interface bolted onto your own Hetzner VPS.

It supports deploying directly from a Git repo (GitHub, GitLab, Bitbucket, or plain SSH), Dockerfiles, Docker Compose, or pre-built images. For Next.js specifically, it detects the framework and uses a sensible Nixpacks-based build by default—no Dockerfile required unless you want one.

Why is it trending right now? A few reasons converging:

  • Vercel’s pricing changes pushed a wave of teams toward self-hosting
  • EU data residency requirements are getting stricter—Coolify on a Frankfurt VPS solves that cleanly
  • The v4 release matured the UI and the first-party cloud tier gives teams an on-ramp
  • It handles full-stack apps (app + DB + queues) in one dashboard, which Vercel still doesn’t

At 59k stars and with Hetzner as a named sponsor, this isn’t a side project—it’s production-grade infrastructure software.

2. Installing Coolify on a VPS

You need one server for Coolify itself and ideally a second for the apps it deploys. A $6/month Hetzner CX22 (2 vCPU, 4 GB RAM) is the minimum comfortable Coolify host. Your app server size depends on the app.

SSH into your Coolify server and run the one-liner:


      curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
      

The installer handles Docker, the Coolify daemon, Traefik (for reverse proxying), and a self-signed cert for the dashboard. After two or three minutes you’ll see a URL like http://YOUR_SERVER_IP:8000—open it and create your admin account.

A few things to do immediately after setup:

  • Point a subdomain (e.g. coolify.yourdomain.com) at the server and enable the Let’s Encrypt cert in Settings → Instance → Domain
  • Add your app server under Servers → New Server (paste the SSH private key)
  • Enable automatic updates under Settings → Updates if you’re not tracking versions manually

3. Deploying a Next.js App Router project

In the Coolify dashboard: Projects → New Project → New Resource → Application → GitHub. Connect your GitHub account (it installs a GitHub App, not a PAT), pick the repo and branch, and Coolify will auto-detect Next.js via Nixpacks.

The default build command works for most App Router setups, but you should verify two things in the Build Config panel:

  • Build command: npm run build (or pnpm build—set the package manager Coolify uses under the Build Pack settings)
  • Start command: node .next/server/server.js via Nixpacks, or npm start if you’re using a standalone output

For App Router projects I almost always configure standalone output in next.config.ts. It produces a self-contained .next/standalone directory that doesn’t neednode_modules at runtime, which cuts image size significantly and makes Coolify’s container restarts faster.


      // next.config.ts
      import type { NextConfig } from 'next';

      const nextConfig: NextConfig = {
        output: 'standalone',
      };

      export default nextConfig;
      

With standalone output, set the start command in Coolify tonode .next/standalone/server.js. Set HOSTNAME=0.0.0.0 andPORT=3000 as environment variables (more on that below) so the server binds correctly inside Docker.

4. Environment variables, domains, and HTTPS

Coolify’s env var UI is solid. Under your application’s Environment Variablestab, you can add key/value pairs, mark them as “build-time” (available duringnext build) or “runtime” (injected into the container at start), or both.

A few Next.js-specific things to get right:

  • NEXT_PUBLIC_* variables must be marked as build-time. They’re inlined by the compiler at build time—setting them only at runtime does nothing.
  • Server-side secrets (database URLs, API keys) should be runtime-only. Don’t mark them as build-time unless you actually need them during next build.
  • Always add HOSTNAME=0.0.0.0 and PORT=3000 as runtime vars. Without HOSTNAME=0.0.0.0, Node will bind to localhost inside the container and Traefik can’t reach it—a silent failure that wastes 20 minutes.

For domains, go to Domains in your app settings, add your domain (e.g. https://app.yourdomain.com), and Coolify will automatically provision a Let’s Encrypt cert via Traefik. DNS just needs an A record pointing at your app server IP. HTTP → HTTPS redirect is on by default.

5. Production gotchas you’ll hit

Coolify is genuinely good, but there are enough rough edges in a real Next.js deployment that you should know about them before you’re debugging at midnight.

Image optimization (next/image):

The built-in Next.js image optimizer works fine, but it processes images at request time and caches them locally. On a single-server setup this is fine. If you’re behind Coolify’s Traefik and you scale to multiple replicas, the image cache isn’t shared between containers—use an external CDN or setimages.unoptimized: true and handle optimization upstream.

Persistent storage and the .next/cache directory:

By default, each deployment creates a fresh container, so the incremental build cache is gone. Coolify supports persistent volume mounts—mount your.next/cache directory to a named volume to keep ISR page caches and build caches across deploys. This is under Storages in the app settings.

Websockets and Server-Sent Events:

Traefik handles these fine, but you need to make sure sticky sessions aren’t accidentally enabled if you’re running multiple replicas. Check the Traefik labels Coolify generates under Advanced → Custom Labels if you see dropped WebSocket connections.

Health checks:

Coolify will mark your deploy as “running” before Next.js is actually ready to serve traffic if you don’t configure a health check. Add a simple /api/healthroute handler in your app and set it as the health check endpoint in Coolify’s Health Check settings. Otherwise zero-downtime deploys aren’t really zero-downtime.

Build memory limits:

next build on a large App Router project can easily use 2–3 GB of RAM. If your app server has less than 4 GB, builds will silently OOM and fail with a cryptic exit code. Set NODE_OPTIONS=--max-old-space-size=3072 as a build-time env var, or upgrade the server tier.

6. When I’d actually reach for Coolify on a client project

I’ve been watching Coolify mature for a couple of years, and I’d recommend it without hesitation in specific scenarios—but it’s not a blanket Vercel replacement.

Reach for Coolify when:

  • The client has a fixed budget and predictable traffic. A $12/month Hetzner box will serve a medium-traffic Next.js app that would cost $80+/month on Vercel’s Pro tier once you factor in function invocations and bandwidth.
  • You’re deploying a full-stack app that needs a database, Redis, and background workers alongside the Next.js app. Coolify handles all of that in one place with one-click Postgres/Redis provisioning and private networking between services.
  • Data residency matters. EU clients in regulated industries (finance, health) often can’t use Vercel’s US-edge network. Coolify on a Hetzner Frankfurt server solves this cleanly.
  • The team already has DevOps comfort. Coolify reduces ops overhead dramatically, but it doesn’t eliminate it. You still own the server, the backups, and the incident response.

Stick with Vercel when:

  • The project is a content/marketing site that leans on Vercel’s edge network and CDNfor global LCP. Routing static assets through a single-region VPS will hurt performance for geographically distributed audiences.
  • Preview deployments are non-negotiable for the client’s QA workflow. Coolify has preview deploy support now, but it’s not as polished as Vercel’s.
  • The team has zero ops experience and no one to call when the server goes down at 2am. The “it’s just a VPS” reality hits hard the first time you need to debug a disk-full container crash.

Coolify is the right call on probably 60% of the client Next.js projects I see—the ones that are real applications, not just content sites. The cost savings are real, the self-hosting story is solid, and v4 is genuinely stable. If you’re evaluating infrastructure for a new engagement, I’m happy to talk through the trade-offs— book a development consultation and we can figure out the right deployment stack for your specific constraints.

And if you want to see what full-stack Next.js projects actually look like in production, the case studies cover a few different infrastructure setups, including self-hosted deployments.