TL;DR — Which Button Should I Click?
| Goal | Use This Button | Don't Use |
|---|---|---|
| Apply code changes | Restart App | "Run NPM Script → start" |
| Apply code changes (new dependencies) | Run NPM Install then Restart App | Just "Restart" |
| Stop the app temporarily | Stop App | Killing processes via SSH |
| Build production assets (Next.js, Nuxt, etc.) | Run NPM Script → build then Restart App | "Run NPM Script → start" |
| Test if the app starts at all | Restart App and check logs | "Run NPM Script → start" |
Golden rule: for any long-running server (Next.js, Express, Fastify, NestJS, Nuxt, etc.) use the dedicated app buttons (Start / Stop / Restart) — never use "Run Script: start".
Why "Run NPM Script: start" Hangs Forever
When you click Run NPM Script → start, cPanel literally runs npm run start and waits for it to finish before returning control.
But for a Next.js / Express / Node server, the start script is a long-running process that never exits on its own — it's supposed to keep listening for HTTP requests forever.
So:
- cPanel waits forever
- The "Working…" spinner spins forever
- A lock file is created in
nodevenv/<app>/.lock - Every subsequent button click fails with: "Can't acquire lock for app XXX"
Symptoms You Hit This Bug
- "Can't acquire lock for app
<your_app>" error - "Operation already in progress" message
- Restart button does nothing
- Logs show nothing new even though you clicked Restart
Self-Service Fix
- Verify your site is still up by visiting it in a browser. In 99% of cases it stays up because the actual web server keeps serving traffic independently of the cPanel UI.
- Open a support ticket so we can clear the lock (it requires server-side access).
- Once cleared, click Restart App (NOT "Run Script").
- If your code changes don't appear: visit your site in incognito mode (cache).
How Node.js Apps Actually Run on Our Servers
Two separate things keep your Node.js app alive on cPanel:
LiteSpeed Web Server ← receives HTTP from internet
↓
lsnode workers ← actually run your Node.js code
↑
These are spawned + managed by LiteSpeed,
NOT by cPanel UI buttons.
Separately:
cPanel Node.js Selector UI
= Configuration tool (env vars, version, restart trigger)
≠ The thing actually running your app
So when "Restart App" is broken in the UI, your site is still up. The button just rebuilds config and tells LiteSpeed to spawn fresh workers.
Recommended package.json Setup
{
"scripts": {
"build": "next build",
"start": "next start",
"dev": "next dev"
}
}
Don't put long-running commands in scripts named anything OTHER than start. cPanel's "Restart App" knows how to handle start correctly. It will not run other script names properly for long-running servers.
When To Open a Support Ticket
- "Can't acquire lock" error appears
- Site is actually DOWN (not just management UI broken)
- Restart App button works but app crashes immediately
- Module not found / dependency errors
Include in your ticket:
- App name
- Domain
- The exact error message from the UI
- What button you clicked
- Last working time
