A developer uploads an Express app via FTP to shared PHP hosting. Nothing starts: no permanent node server.js, no exposed port 3000, no reverse proxy configured. Node is not "complicated" — it is Node hosted like PHP, where each request would spawn an interpreter that dies immediately.
Hosting your first Node.js app means accepting a different execution model. PHP-FPM handles short requests; Node.js keeps a living process that holds state in memory, listens on an HTTP port and waits for connections. Without a process manager, proxy and automatic restart, the first traffic spike — or the first abrupt process kill — ends your "production launch".
PHP vs Node: two execution models
| Aspect | Classic PHP (FPM) | Node.js |
|---|---|---|
| Process | Short, per request | Long-lived, persistent |
| Listen | Apache or nginx → FPM | Own HTTP port |
| In-memory state | Limited | Sessions, app cache possible |
| Deploy | Files + OPcache | npm ci, build, process restart |
| Scaling | More FPM workers | PM2 cluster, multiple instances |
Treating Node like PHP is asking a restaurant to reheat the oven for every order.
On shared PHP hosting, the web server knows how to run .php files. It does not know how to keep a Node.js process alive between requests. Even if you upload server.js, nobody starts it — and nobody restarts it if it crashes at 3 a.m.
Minimal stack for first production
1. CI build. npm ci, automated tests, npm run build if a frontend is compiled. Production receives a tested artefact, not an improvised git pull.
2. Process manager. PM2 ecosystem file or systemd unit with Restart=always. The process must survive uncaught errors and restart on server boot.
3. Reverse proxy. nginx with proxy_pass to 127.0.0.1:PORT. Node does not expose port 3000 directly to the internet — the proxy handles TLS, headers and compression.
4. TLS. Let's Encrypt on nginx, not in Node unless you have a specific constraint. Automated renewal and documented nginx reload.
5. Environment variables. NODE_ENV=production, secrets via env vars — never committed to the repo. A .env file on the server with restricted permissions.
6. Logs. Aggregated stdout/stderr; rotation if writing to disk. Without centralized logs, a night-time crash stays invisible until Monday morning.
7. Health check. /health route for monitoring and load balancer. Without it, a zombie process can stay "online" without serving requests.
Choosing the right host
| Option | For whom |
|---|---|
| Node PaaS (Railway, Clever Cloud, Heroku-like) | First app, little ops overhead |
| VPS + PM2 | Full control, predictable cost |
| Container (Docker, Kubernetes) | Already containerised team |
Avoid "unlimited PHP shared" offers with no explicit Node mention — wrong product. Compare PaaS and VPS offers in our directory and comparator. For long-running deploy culture, see Django in production and PM2 deployment — different stacks, same principles.
Classic first production mistakes
node_modulesuploaded from Windows to Linux without rebuilding native modules — bcrypt, sharp and sqlite3 fail silently.- App listening on
0.0.0.0with no firewall — Node port exposed directly, bypassing nginx. - No memory limit — a JavaScript leak kills the entire server after a few hours.
- WebSockets forgotten in nginx config — missing
UpgradeandConnectionheaders, realtime breaks. - Deploy = git pull without PM2 restart — old code still running in memory.
Every mistake is predictable. None is fatal if you test the full cycle before announcing go-live.
The summit: Node needs a host that lets a process live
Here is what "deploy in five minutes" tutorials forget to say.
Decide and move forward without blind spots
In one day you can lay foundations for real Node production:
- Validate a Node, PaaS or VPS offer with root access.
- Configure PM2 or systemd, then nginx as reverse proxy.
- Automate deploy with process restart on each release.
- Test crash recovery — kill the process manually and verify restart.
- Monitor memory and PM2 restart count.
Start by confirming your host allows a persistent process — that is the non-negotiable prerequisite. Then document who changes config, how to reload nginx after TLS renewal, and where to read logs during an incident. For memory leaks, see Node.js memory leak.
Frequently asked questions
Can you host Node.js on shared PHP hosting?
Rarely. Shared PHP hosting does not maintain a persistent Node process, expose a custom port or configure a reverse proxy to your app. Look for a dedicated Node offer, PaaS or VPS.
PM2 or systemd in production?
Both work. PM2 simplifies cluster mode and graceful reload; systemd integrates natively with the Linux system journal. In both cases, automatic restart after crash and on boot is mandatory.
Do you need nginx in front of Node?
In practice yes: nginx handles TLS, HTTP/2, static files and rate limiting. Node listens locally on an internal port; nginx routes public traffic to it.
How do you deploy without downtime?
Use PM2 reload, blue-green deployment or two instances behind a load balancer. Always build with npm ci in CI, never manually on the production server.
Node in production is not an uploaded file — it is a process someone must keep alive.