Deploy and run your backend with confidence
Practical guides on deploying and running a backend in production, plus plain-English fixes for the errors you hit along the way — real causes, copy-paste commands, and how to stop them recurring.
Prefer to paste your error and get an instant fix? Try the interactive Deploy Error Decoder →
Backend guides
Broader, practical guides on deploying and running a backend in production — each links down to the specific errors below.
Deploy a backend without Kubernetes
You don't need Kubernetes. The five pieces that actually keep a backend running in production.
Read the fixSelf-host Next.js (leave Vercel)
Next.js is a Node app. Build standalone, reverse proxy + SSL, systemd, CI deploy. What you gain, what you handle yourself.
Read the guideCI/CD to your own server
Push-to-deploy without a PaaS: build, test, SSH-deploy, health-check, auto-rollback - on infrastructure you own.
Read the guideWho can touch production?
Least privilege, just-in-time access, and a human gate for destructive actions - especially for AI agents.
Read the guideProduction is down: what to do
A calm sequence: confirm scope, stop the bleeding (roll back), communicate, diagnose, fix, postmortem. Service first, root cause second.
Read the guideZero-downtime migrations
The expand-contract pattern, avoiding table locks, backwards-compatible deploys, and always having a rollback.
Read the guideProtect against abuse & bots
Layered defense without Cloudflare: firewall, rate limiting, fail2ban, and app-level throttles on sensitive routes.
Read the guideSecrets without a vault
Manage env secrets for a self-hosted app without HashiCorp Vault: out of git, injected at runtime, restricted, rotated, scanned.
Read the guideMonitor your own backend
Health checks, metrics, and alerting without a heavyweight SaaS. What to watch, and how to alert on symptoms not noise.
Read the guideSet up HTTPS (free)
Free, auto-renewing TLS with Caddy or nginx+certbot. Point DNS, open 80/443, and confirm renewal - the step people forget.
Read the guideAutomated database backups
A complete backup pipeline for a DB you run yourself: dump, compress, encrypt, offsite, prune, schedule - and test the restore.
Read the guideZero-downtime deployment strategies
Blue-green, canary, rolling — how each works, when to use it, and what keeps a deploy from dropping requests.
Read the fixDeploy without dropping requests
Every deploy stops your old process. Draining, SIGTERM handling, and readiness flips keep requests alive.
Read the fixReadiness vs liveness health checks
One gates traffic, one restarts a hung process. Confusing them causes downtime and crash loops.
Read the fixReverse proxy in front of your app
TLS, routing, buffering, and limits in front of your app. A minimal nginx config and the settings that matter.
Read the fixSelf-hosted vs cloud hosting
The real tradeoffs in cost, control, compliance, and effort — and when running your own servers makes sense.
Read the fixDeploy Error Decoder
Paste your error into Google and you land here. Real causes, copy-paste commands, and how to stop each one from recurring.
EADDRINUSE: address already in use
Another process is already on your port. Find it, free it, and stop it recurring on every deploy.
Read the fix502 Bad Gateway after deploy
Your proxy can't reach the app. Diagnose the crash, port, or readiness race — and gate it for good.
Read the fixCrashLoopBackOff
Why a container restarts forever, how to read the exit code, and how to break the loop.
Read the fixSIGTERM & graceful shutdown
What SIGTERM means, why requests get dropped on deploy, and how to drain cleanly before exit.
Read the fixECONNREFUSED: connection refused
Your app reached the host but nothing was listening. Down service, wrong host/port, or Docker networking.
Read the fixCannot find module (MODULE_NOT_FOUND)
Works locally, fails in prod. Missing deps, a devDependency at runtime, or case-sensitive paths on Linux.
Read the fixECONNRESET / socket hang up
The other side dropped the TCP connection mid-request. Idle keep-alive, an upstream restart, or a proxy timeout.
Read the fixExit code 137 (OOMKilled)
Your container hit its memory limit and was killed. Confirm OOM, find the ceiling, and fix the leak or raise it.
Read the fixJavaScript heap out of memory
Node hit its V8 heap ceiling. Raise it for big builds, or find the leak if it grows forever.
Read the fixPermission denied (publickey)
The server rejected your SSH key. Check it's loaded, added to the host, and matched to the right account.
Read the fix413 Request Entity Too Large
The request body hit a size limit — nginx client_max_body_size or your body parser. Raise both, sanely.
Read the fixBlocked by CORS policy
The browser blocked a cross-origin response. It's a server-side header fix, not a client one.
Read the fix504 Gateway Timeout
The proxy waited for the app and gave up. The app is reachable but too slow — find and fix the slow path.
Read the fixENOSPC: no space left on device
A write failed because something filled up — disk, inodes, or the inotify watch limit. Find it and reclaim.
Read the fixEACCES: permission denied
The OS refused access — a low port, a file you don't own, or broken npm perms. Fix it without chmod 777.
Read the fixnpm ERR! code ELIFECYCLE
Not the real error — an npm script exited non-zero. The actual failure is in the lines above it.
Read the fixEMFILE: too many open files
Your process hit its file-descriptor limit. Raise the ulimit for real load, or fix the descriptor leak.
Read the fixSSL/TLS handshake failed
Client and server couldn't agree on a secure connection. Expired cert, missing chain, wrong host, or protocol.
Read the fixCannot use import statement outside a module
Node parsed your file as CommonJS but it uses ESM import syntax. Pick one module system and commit to it.
Read the fixPostgres: too many clients already
Postgres hit max_connections. The real fix is a connection pooler and sane pool sizes — not just raising the limit.
Read the fixDocker: exec format error
An architecture mismatch — arm64 image on an amd64 host (or vice versa). Build for the target platform.
Read the fixconnect ETIMEDOUT
No answer at all before timing out — usually a firewall/security group, wrong host, or overloaded upstream.
Read the fixHost key verification failed
SSH won't trust the server's key — first connection, rebuilt server, or empty CI known_hosts. Add it safely.
Read the fixSelf signed certificate in chain
Node doesn't trust the cert chain — corporate proxy, private CA, or missing intermediate. Trust the CA, don't disable TLS.
Read the fixPassword authentication was removed
GitHub no longer accepts your password over HTTPS. Use a Personal Access Token, or switch the remote to SSH.
Read the fixgetaddrinfo ENOTFOUND
A hostname didn't resolve. A typo, a missing env var, or a Docker service name used as localhost. Check resolution.
Read the fixUnexpected token < in JSON
You parsed HTML as JSON - the API returned an error page, wrong URL, or login redirect. Find what actually came back.
Read the fixTypeError: fetch failed
Node 18+ native fetch hides the real cause in error.cause - DNS, refused connection, timeout, or TLS. Read it and fix the right thing.
Read the fixImagePullBackOff
Kubernetes could not pull the image. Wrong tag, a private registry without imagePullSecrets, or a rate-limited registry.
Read the fixCannot connect to Docker daemon
dockerd not running, or your user is not in the docker group (permission denied). Start it, grant access deliberately - docker group is root.
Read the fixnpm ERESOLVE dependency tree
A peer-dependency conflict npm 7+ enforces (react@17 vs 18). Upgrade the lagging package, override, or the --legacy-peer-deps stopgap.
Read the fixMixed Content blocked
An HTTPS page requested an http:// resource and the browser blocked it. Use https URLs, trust X-Forwarded-Proto, add upgrade-insecure-requests.
Read the fixRedis connection refused
ECONNREFUSED, NOAUTH, or TLS. Redis not running, localhost in Docker, a missing password, or a managed host that needs rediss://.
Read the fixupstream prematurely closed
The 502 where your app dropped the connection before responding. Crash, OOM kill, timeout, or a keepalive race - find which.
Read the fixModule not found: Can't resolve
Webpack could not resolve an import. Wrong or case-mismatched path, a missing dependency, or a Node built-in in browser code.
Read the fixMongooseServerSelectionError
The driver could not reach MongoDB. Not running, wrong host, localhost in Docker, or an Atlas IP allowlist missing your server.
Read the fixPostgres password auth failed
Postgres rejected the credentials. Wrong password, special chars not URL-encoded, or an env var that did not load. The exact fix.
Read the fixPrisma cant reach database
P1001 / PrismaClientInitializationError: DATABASE_URL, SSL, IP allowlist, or serverless connection exhaustion. Fix each.
Read the fixno pg_hba.conf entry for host
Postgres rejected the connection before the password - it needs SSL (sslmode=require) or your IP allowlisted. Not a password problem.
Read the fixERR_REQUIRE_ESM
require() of an ESM-only package (node-fetch 3, chalk 5). Pin the CommonJS version, convert to ESM, or dynamic import.
Read the fixJWT expired / malformed / invalid
Each jsonwebtoken verify error has a distinct cause. Bearer prefix, expiry, and secret mismatch - the exact fix for each.
Read the fixENOENT: no such file
The path does not exist from where the process runs. A relative path against the wrong cwd, or a file not copied into the deploy. Use absolute paths.
Read the fixnpm ci lock file out of sync
npm ci needs a package-lock.json that matches package.json. Missing, gitignored, or stale lock files break the build. Commit a synced lock.
Read the fixCannot set headers after sent
ERR_HTTP_HEADERS_SENT means you responded twice. A missing return after res.send, or next() after responding. One response per request.
Read the fixERR_OSSL_EVP_UNSUPPORTED
Node 17+ OpenSSL 3 refused the legacy hash your build tool (usually Webpack 4) needs. The real fix and the one-line stopgap.
Read the fixStop fixing these by hand
Infraveil is a backend operations control plane you run on your own servers. It supervises your services, gates every deploy behind your approval and a health check, and recovers from failures with a one-click rollback — so most of these errors never reach your users.
New backend-ops guides, free tools, and control-plane updates — no spam, unsubscribe anytime.