My Next.js Build Was Killing My Server. Here's How I Fixed It for Free.
For months, my production server went dark every time I deployed. 400% CPU. Dashboard users locked out. All because I was building a Next.js app on the same machine that served it. The fix was embarrassingly simple and completely free.
For months, my production server would go dark every time I hit deploy. Not "slow." Dark. 400% CPU. Dashboard users locked out. Client sites unresponsive. All because I was building a Next.js app on the same machine that was serving it.
If you're self-hosting with Coolify on Hetzner and still building directly on your server, this one's for you. Because I was doing the same thing, and the fix was embarrassingly simple.
The Setup
I run my projects on a Hetzner VPS with Coolify as the deployment layer. When I first set things up, I used Nixpacks as the build pack. Coolify's default. You push code, Nixpacks figures out your framework, builds the image, runs it. Zero config. It just works.
And for a while, it did.
When "Just Works" Stopped Working
The app grew. More pages, more routes, more dependencies. Nixpacks builds started taking longer. Not dramatically, but enough to notice. I switched to a Dockerfile as the build pack, which gave me more control over the build process and shaved off some build time.
That helped. For a while.
Then I added a dashboard. Clients started using it daily. People were logged in, clicking around, doing their thing. And every time I pushed a deployment, the server would choke.
400% CPU utilization. The build process was eating everything the server had. The dashboard became unresponsive. Client-facing pages timed out. For 5 to 10 minutes, nothing worked.
I was essentially DDOSing my own server every time I deployed.
The Problem I Didn't Know I Had
Here's the thing nobody told me when I started self-hosting: building and serving should not happen on the same machine.
It seems obvious in hindsight. A Next.js production build is CPU-intensive. It's compiling TypeScript, optimizing images, generating static pages, tree-shaking, bundling. That's a lot of compute. And when your 4-core VPS is also serving live traffic, handling database queries, and running a CMS... something has to give.
I just didn't know there was a better way inside Coolify. I assumed "Dockerfile build pack" meant "builds happen here." I didn't realize Coolify supports pulling pre-built Docker images instead of building them on the server.
The Fix: Let GitHub Build It
The solution was to move the build step off the server entirely. GitHub Actions handles the build, pushes the image to GitHub Container Registry (ghcr.io), and Coolify just pulls the finished image and runs it.
No build on the server. No CPU spike. No downtime.
Here's roughly what the workflow looks like:
- Code gets pushed to main
- GitHub Actions spins up a runner
- The runner builds the Docker image (using your Dockerfile)
- The image gets pushed to ghcr.io
- Coolify gets notified via webhook
- Coolify pulls the new image and deploys it
The server never breaks a sweat. It just swaps one running container for another.
What It Costs: Nothing
GitHub's free plan includes 2,000 Actions minutes per month for private repositories. Public repos get unlimited minutes.
My Next.js build takes about 3 to 4 minutes. Even if I deploy 10 times a day (I don't), that's 40 minutes. Out of 2,000. I'm using roughly 2% of my free quota on a busy day.
For context, a Hetzner VPS upgrade to handle builds without choking would cost me an extra 10 to 20 euros per month. GitHub Actions costs me zero.
The GitHub Actions Workflow
Here's what a successful build-and-deploy run looks like on GitHub:
The entire pipeline runs in under 3 minutes. Set up job, checkout code, login to GHCR, build and push the image, trigger the Coolify deploy via webhook. Done.
The Coolify Side
Switching Coolify from "build it yourself" to "pull a pre-built image" is straightforward. You change the build pack from Dockerfile to Docker Image, point it at your ghcr.io image, set up a webhook so Coolify knows when a new image is available, and you're done.
The key insight: Coolify doesn't care how the image was built. It just needs a valid Docker image to run. Whether that image was built on your server, on GitHub, or on your laptop doesn't matter. Same result, wildly different server impact.
All green. All under 30 seconds. Because there's no build step anymore, just a container swap.
The Result
Here's the CPU graph after moving to GitHub Actions builds:
Flat. Calm. Boring. Exactly what you want from a production server.
No more spikes. No more dashboard freezes. No more clients messaging me asking why the site is slow.
What I'd Tell You If You're Starting Out
If your app is small and you're the only user, Nixpacks on Coolify is perfectly fine. Don't over-engineer it.
But the moment you have real users on your server, or the moment your build starts taking more than a minute or two, move your builds off the server. Don't wait until your clients can't access their dashboard because you pushed a CSS fix.
The setup takes about 30 minutes:
- Write a GitHub Actions workflow that builds and pushes your Docker image
- Set up a GitHub personal access token for container registry access
- Configure Coolify to pull from ghcr.io instead of building locally
- Add the webhook URL so deployments trigger automatically
That's it. 30 minutes of setup for zero-downtime deployments forever.
The Bigger Lesson
Self-hosting gives you control. But control means you're responsible for decisions that managed platforms make for you automatically. Vercel doesn't build your app on the same server that serves it. Neither does Netlify. When you self-host, you have to figure that out yourself.
I lost a few hours of uptime before I figured this out. You don't have to.
If you're running into similar issues with your deployment setup, or you're thinking about self-hosting but want to avoid these kinds of pitfalls, reach out. I've been through the painful parts so you can skip them.
About the Author
Kemal Esensoy
Kemal Esensoy, founder of Wunderlandmedia, started his journey as a freelance web developer and designer. He conducted web design courses with over 3,000 students. Today, he leads an award-winning full-stack agency specializing in web development, SEO, and digital marketing.