What Managed Hosting Doesn't Give You: A cPanel and Plesk Reality Check
Bought managed hosting and hit a wall trying to deploy Docker, Node, or anything modern? cPanel and Plesk are PHP products with a friendly UI. Here's what you actually get, what you don't, the workarounds nobody tells you about (manual Node install, static React builds, the cron-keepalive daemon trick), and how to glue a modern stack around it without buying the VPS upsell.

If you bought "managed hosting" recently and tried to deploy anything that wasn't a PHP application, you've already hit the wall. cPanel and Plesk hosting are pitched as "we handle the server, you handle the site." What they actually are: a PHP + MySQL + mail bundle with a friendly UI, and a hard wall around everything else.
This isn't a knock on managed hosting. For a WordPress site, a static brochure site, or a small e-commerce build, it's the right shape and the right price. The problem starts when "managed" gets translated as "modern" in marketing copy, and you discover only after buying that your Node API, your Postgres database, your Redis cache, and your Docker compose file have nowhere to live.
Here's what you actually get on a typical managed plan, what you don't, the workarounds that exist if you have any kind of shell access (more than the host's sales page admits), and how to glue a modern stack around it without buying the VPS upsell.
What you actually get
The standard managed hosting bundle, across both cPanel and Plesk, is:
- PHP with whatever versions the host has blessed (usually 7.4 through 8.3 these days)
- MySQL or MariaDB with phpMyAdmin
- Apache or LiteSpeed as the web server (you don't pick)
- File manager + FTP/SFTP access (usually jailed to your home directory)
- Email with IMAP/SMTP mailboxes on the same domain, plus a web mail UI like Roundcube
- Cron jobs scheduled as your jailed user
- DNS management for the domains attached to your account
- Let's Encrypt SSL auto-renewed
- A friendly admin UI (cPanel or Plesk)
If your needs end at this list, managed hosting is great. The host runs the OS, handles security patches, monitors uptime, and you don't think about any of it. $4-15/month gets you a solid PHP environment.
What you don't get (the wall of walls)
Where it falls apart is everything outside the PHP + MySQL + mail box.
No Docker. No containers, period. Plesk has a Docker extension but it's only available on Plesk Web Pro and Plesk Web Host tiers, which most "managed shared" plans are not. cPanel has nothing equivalent. If your IT company put you on a managed shared plan, "deploy this docker-compose.yml" is not an option.
Node.js, Python, Ruby are limited or absent. Plesk has a Node.js extension and a Python extension via Phusion Passenger. They work, with caveats: you can't run arbitrary background processes, you can't use systemd, and the Passenger worker model doesn't fit every app. cPanel has "Node.js App" on some hosts (LiteSpeed-flavored) and nothing on others. Your stack has to fit the host's model, not the other way around.
No persistent background workers. Cron gets you scheduled tasks. You don't get a queue daemon, a websocket server, a long-lived worker process, or anything that needs to stay alive between requests. Shared hosts reap processes that run too long. "I'll just run a Node script in tmux" doesn't work because there's no tmux, no SSH session that lasts past your logout, and your process is killed by the host's reaper.
SSH access varies, and it's the most important variable. A lot of managed plans give FTP/SFTP only, no shell. Some give a jailed SSH session with maybe 50 binaries available. A few give a real bash shell with most standard binaries, just no root and no sudo. Which tier you're on determines what workarounds are possible. If you only have FTP, you're locked to what the host installs. If you have any shell at all, you have options the host's sales page won't mention. We cover those below.
No iptables, no firewall control, no port binding outside 80/443. You can't run a service on port 3001 and expose it. The host's reverse proxy serves your account's home directory at the domain they assigned you. That's the only network surface you get.
Limited php.ini. Sometimes you get user-level overrides via .user.ini files. Often you don't. memory_limit, max_execution_time, upload_max_filesize are often capped well below what a heavy plugin or import needs.
Redis, Memcached, RabbitMQ are only what the host gives you. Some hosts ship Redis as a paid managed add-on. Most don't. You can't install and run your own.
Email is the host's mail server, not yours. You can use it. You can't replace it with Mailgun or Postfix. Outbound mail uses the host's IPs, which may or may not have a sender reputation you'd want for transactional email.
The SSH-but-no-Docker middle ground
If you've got any kind of shell access (even jailed), a surprising amount of "modern" stack will run on managed hosting without buying the upsell tier. The host's sales page won't tell you this because they want you to think the only option above shared-PHP is their VPS. Here's what actually works.
Build your React (or Vue, Svelte, Next.js static export) into plain HTML, JS, and CSS, and let the host serve it as static files. This is the cleanest workaround. You run npm run build on your laptop or in CI, upload the resulting dist/ or build/ folder to the public_html directory via FTP or rsync, and the host's Apache or LiteSpeed serves it like any other static site. No Node at runtime, no FPM, no extension required. The frontend "just works" because at the end of the day a React app is HTML, JS, and CSS. If you don't need server-side rendering, this is the path.
Install Node manually in your home directory. With shell access you don't need the host to provide a Node.js extension. Download a pre-built Node binary from nodejs.org (the Linux x64 tarball), extract it under ~/node, add ~/node/bin to your PATH in ~/.bashrc, and you have Node and npm. No root, no extension, no host involvement. You can then npm install your dependencies in your project directory and run a real Node app. This works on every shared host we've ever tried it on, because untar-ing a tarball and editing your own dotfile doesn't require any permission you don't already have.
Run a Node process and keep it alive with cron. This is the trick that surprises people. The host won't let you run a persistent daemon, but it will run a cron job. Write a small script that checks if your Node app's process is alive (pgrep -f 'node server.js') and restarts it if not, then schedule it to run every minute via cron. Your Node app is now effectively a long-running daemon, just with a 60-second worst-case respawn time. The cron-keepalive pattern is the manual equivalent of pm2 or systemd, and it predates both by decades.
Bind your Node app to a high port and reverse-proxy through `.htaccess` or the panel's domain settings. Your Node app listens on, say, port 30000 on localhost. In your public_html, add an .htaccess rule (Apache) or a Plesk/cPanel proxy rule that forwards requests to localhost:30000. Your visitors hit your domain normally, and the host's web server proxies through to your Node app. This works on most LiteSpeed and Apache shared hosts.
Limits of this approach. You're still capped by the host's process limits (often 25-50 concurrent processes per account), memory limits, and the reaper. Long-running daemons that get noticed by the host's monitoring sometimes get killed without warning. Outbound port 25 is usually blocked, so you can't run your own SMTP. Inbound traffic is limited to what the host's reverse proxy permits, so you can't expose arbitrary services.
The pattern that works most reliably: build the frontend to static, run a small Node backend via the cron-keepalive trick, use the host's bundled MySQL for storage, and call out to external services (Stripe, an email API, etc.) for anything that needs more than the shared box can provide. This is the budget version of the modern-stack pattern, and it runs on $5-15/month managed plans every day.
The upsell trap
When you hit any of these walls, the host's playbook is to pitch you their VPS tier. It's usually 2-5x the price of the managed plan, often poorly tuned, and you've now bought a server you didn't want to manage on top of the one you did.
The pitch frames it as "you've outgrown shared hosting." The reality is that you never had shared hosting for the stack you were trying to deploy in the first place. Managed cPanel and Plesk are PHP products. Your Node + Postgres + Redis app was always going to need somewhere else to live. The host just didn't tell you that on the sales page.
The strategy that actually works
The right move, almost every time: keep the managed plan for what it's good at, and put modern workloads on a separate provider that's actually built for them. Glue the two together via DNS.
The pattern is your main site stays on managed hosting. Your Node API runs on Railway, Fly.io, or a $5/month Hetzner box. You add an A record for api.yourdomain.com in the managed host's DNS, pointing at the modern provider's IP. Your visitors don't know or care; everything resolves correctly.
Cost-wise, this is usually cheaper than the host's VPS upsell. A $5/month Hetzner cx11 plus your existing $10/month managed plan is $15/month total, versus $30-60/month for the host's VPS tier. And the Hetzner box is yours to install whatever you want on, run docker compose, and treat as a proper modern server.
Specific scenarios
WordPress + a Node API. WordPress stays on managed hosting where it belongs. The Node API runs on a $5 Hetzner cx11 or a Railway hobby plan. Subdomain api.yourdomain.com gets an A record pointing at the Node host. The WP site calls the API by hostname; CORS gets configured once.
Static frontend + Express backend. Frontend goes to Cloudflare Pages (free tier includes a CDN, builds from your git repo on every push). Backend goes to Railway or a Hetzner box. Both subdomains route through the managed host's DNS. The managed plan effectively becomes a domain registrar and email host, nothing more.
Database needs more than MySQL. Supabase, Neon, and PlanetScale all give you serverless Postgres or MySQL with free tiers. Your app on managed hosting connects to the external DB by hostname. The managed host's bundled MySQL becomes secondary; your real DB lives elsewhere.
Background workers / queues. Managed hosting cron usually runs every minute at most, and on cheaper plans only every 15 minutes. For real queue work, run a worker process on a $5 Hetzner box. Your web app on managed hosting drops jobs into a Redis instance (also on the Hetzner box, or on Upstash's free tier), and the worker picks them up. Job latency goes from "next cron cycle" to milliseconds.
Needs more than 256MB PHP memory. Most managed hosts cap PHP memory_limit at 256MB. If your plugins need more (Elementor, WooCommerce, LearnDash often do), you've hit the wall. (We wrote up the actual WordPress RAM math separately.) The fix is either upgrading the plan, or moving the workload to a real server where you control php.ini.
Intermittent outages from stuck imports. Heavy inventory syncs or stuck cron jobs on managed hosting can pin your account's process pool and take the site down intermittently. (Separate writeup on the PHP-FPM pool starvation pattern.) The fix is the same as for VPS: get the long-running work off the web process and into a real worker, which usually means moving it to a separate box you control.
When to actually move off
The workarounds work up to a point. You've passed that point when:
- More than 2-3 subdomains are routed off-host (DNS complexity starts to bite)
- The PHP site itself is also bottlenecked on the managed plan
- You need fine control over caching rules, CDN behavior, or origin server config
- You're spending more time gluing pieces together than building features
At that point, the managed plan isn't saving you money or time anymore. Move the whole stack to a VPS (or Kubernetes, if you've already gone that far) and pay the operational tax for the control.
The thing managed hosts won't tell you
The shared-hosting business model assumes most customers will use 10% of what they could. They sell "unlimited storage" because they bet you'll use 5GB. They cap PHP memory because the per-customer ceiling is what makes overselling work. They lock down Docker because containers would let you do things they can't bill for. None of this is malicious. It's how the economics of $5-a-month hosting actually work.
You can play within those constraints and get a lot of value for the money. You just have to understand the constraints exist, and design around them instead of fighting them.
---
*If you're trying to make a modern stack work on managed hosting and keep hitting walls, the DNS-decoupling pattern usually saves the day. Free 30-minute audit at dino@helpwithweb.com if you want a second opinion on where things should actually live.*
Need Help With Your Website?
I fix these problems every day. Send me a message and I'll take a look.
Get Help Now