Managed Website Hosting

Shulker Website Hosting v6.0.0

Production-ready managed hosting for PHP, WordPress, and Node.js applications. A full control panel with file manager, one-click MariaDB databases, custom domains, free SSL, environment variables, a debug shell, and global edge routing — all from a single dashboard.

Updated recently 25 min read Production Ready

What is Website Hosting?

Shulker Website Hosting gives you a fully managed container that runs your website — PHP, WordPress, or Node.js — behind a global edge network with automatic HTTPS. Every plan includes a full control panel, one-click databases, and a debug shell.

Multi-Runtime
PHP 8.4, WordPress, and Node.js 20 — switch between them anytime from the dashboard.
Global Edge
Anycast edge network with automatic TLS termination and DDoS protection.
One-Click Databases
Spin up a dedicated MariaDB server for your website in a single click.
Free SSL
Every connected domain gets HTTPS automatically — no certificates to manage.
File Manager
Browse, upload, edit, and delete files with a built-in Monaco code editor.
Debug Shell
Run commands directly inside your container as root — npm install, composer, wp-cli, and more.

🌐 Every plan is a real container — You get root access, persistent storage, environment variables, and full control over the runtime. It's not shared hosting and there are no artificial limits on what you can install.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────────────────────┐
│                       Shulker Global Edge (Anycast Network)                         │
│                                                                                     │
│      web-proxy-global.shulker.in  ·  Automatic TLS  ·  DDoS Mitigation              │
│                                                                                     │
│     ┌────────────┐    ┌────────────┐    ┌────────────┐    ┌────────────┐            │
│     │  Frankfurt │    │   Mumbai   │    │  Virginia  │    │   + more   │            │
│     └──────┬─────┘    └──────┬─────┘    └──────┬─────┘    └──────┬─────┘            │
│            └─────────────────┴──────┬──────────┴─────────────────┘                  │
│                                     │                                               │
│                                     ▼                                               │
│                    ┌───────────────────────────────────┐                            │
│                    │      Website Container            │                            │
│                    │  ┌───────────┐  ┌───────────┐     │                            │
│                    │  │  Apache   │  │  Node.js  │     │                            │
│                    │  │  + PHP    │  │           │     │                            │
│                    │  └───────────┘  └───────────┘     │                            │
│                    │   Port 80 · Persistent Volume     │                            │
│                    └────────────────┬──────────────────┘                            │
│                                     │                                               │
│                                     ▼  (private mesh network)                       │
│                    ┌───────────────────────────────────┐                            │
│                    │      Database Node (optional)     │                            │
│                    │  ┌───────────┐                    │                            │
│                    │  │  MariaDB  │  Port 3306         │                            │
│                    │  └───────────┘                    │                            │
│                    │   Dedicated node · Own public IP  │                            │
│                    └───────────────────────────────────┘                            │
└─────────────────────────────────────────────────────────────────────────────────────┘

Your domain points to our global edge. The edge proxies traffic to your container over a private network.

Quick Start

Get a website live in under five minutes.

1
Purchase a Hosting Plan
Choose from Starter, Premium, Max, or Unlimited. Each plan defines how many domains and ports you can connect. Go to Dashboard → Orders.
2
Open your Website Panel
From your dashboard, click on your website's name to open the control panel. Everything is managed from here — files, domains, databases, and more.
3
Choose Server Type
Pick PHP, WordPress, or Node.js from the Server Type tab. WordPress setups automatically provision a MariaDB database for you.
4
Upload Your Files
Open the File Manager and upload your application into /var/www/html (PHP/WordPress) or /app (Node.js).
5
Connect a Domain
Add your domain in the Domains tab, then follow the DNS wizard to point a CNAME at web-proxy-global.shulker.in.
6
Verify
Once DNS propagates, visit your domain. You'll see your site over HTTPS, with the free SSL certificate issued automatically.

✅ Free SSL is automatic — The moment a domain resolves to our edge, we issue an SSL certificate for it. There is nothing to configure, renew, or install.

The Dashboard

Your website panel is organised into tabs, each covering a specific area of the hosting stack. Every tab works in real time — changes apply immediately.

TabWhat it does
DashboardOverview: plan status, domain count, node info, backups, and quick actions.
FilesFull file manager with upload, edit, download, rename, and delete.
DomainsConnect custom domains, manage DNS, view SSL status.
PortsView public ports mapped to your container's HTTP port.
PerformanceLive CPU, memory, disk, and uptime metrics.
LogsStream container logs — stdout and stderr.
EnvironmentAdd, edit, and delete environment variables.
DatabasesCreate and manage a dedicated MariaDB server.
Server TypeSwitch between PHP, WordPress, and Node.js.
ShellInteractive debug shell running inside your container.
DangerReinstall or delete the server. Destructive actions live here.

💡 Tip — Bookmark your website's panel URL. It's unique per server: /panel/dashboard/server/<server-id>.

File Manager

A complete web-based file manager for your website's files, with a Monaco-powered code editor built in.

Upload
Drag and drop multiple files, or click to browse. Large files are chunked automatically.
Built-in Editor
Monaco editor with syntax highlighting for PHP, JS, HTML, CSS, JSON, SQL, and more.
Create Files & Folders
Right-click empty space or use the New menu to create files and directories.
Download
Download any file directly from the browser.
Delete / Rename
Full context menu — rename, delete (recursive for folders), or copy path.
Grid & List Views
Toggle between grid and list layouts, and search within the current folder.

Default Web Root Paths

Server TypeWeb Root
PHP/var/www/html
WordPress/var/www/html
Node.js/app

⌨️ Keyboard shortcut — Press Ctrl + S (or ⌘ + S on Mac) inside the editor to save the active file.

Uploading Large Files

Files larger than 1.5 MB are automatically split into 1.5 MB chunks and uploaded in parallel. This means you can upload files of any size without hitting PHP upload limits.

Domains

Connect your own domain (or subdomain) to your website. Every domain is routed through our global edge with automatic SSL.

Adding a Domain

1
Enter your domain
Type the domain or subdomain you want to connect (e.g. example.com or blog.example.com).
2
Add the CNAME record
In your DNS provider, add a CNAME record pointing to web-proxy-global.shulker.in.
3
Wait for propagation
DNS usually resolves in 2–3 minutes. Some providers can take up to an hour.
4
SSL is issued automatically
Once DNS resolves, we issue a certificate and your site is live over HTTPS.

Required DNS Records

TypeNameValue / Target
CNAME@ or subdomainweb-proxy-global.shulker.in

⚠️ Cloudflare users — set SSL/TLS mode to Flexible — If you proxy through Cloudflare (orange cloud), you must set SSL/TLS mode to Flexible. Any other mode (Full, Full Strict, Off) will cause redirect loops or 525/526 errors.

DNS Configuration via Cloudflare

Cloudflare DNS + SSL Checklist
# 1. In Cloudflare DNS settings
Type      : CNAME
Name      : @  (or subdomain)
Target    : web-proxy-global.shulker.in
Proxy     : Proxied (orange cloud)  # ← must be ON

# 2. In Cloudflare SSL/TLS → Overview
Encryption mode : Flexible  # ← must be Flexible

# 3. Wait 2–3 minutes, then visit your domain
https://yourdomain.com

Removing a Domain

Click the trash icon on any connected domain to disconnect it. The DNS record at your provider is not automatically removed — you'll want to clean it up on their side.

💡 Plan limits — Your plan determines how many domains you can connect. Starter: 1, Premium: 3, Max: 5, Unlimited: 999.

Ports

Your container listens on a fixed internal port (usually 80). The Ports tab shows the public port mapped to it and gives you a direct URL for testing before DNS is set up.

Public Port
Auto-assigned public port that forwards to your container.
Direct URL
Access your site via IP:port — useful before DNS is configured.
Edge Routing
Once a domain is connected, traffic flows through the edge instead.

💡 Tip — Use the direct URL to test your site immediately after uploading files, before you've configured DNS. This makes debugging much faster.

Environment Variables

Manage runtime configuration without touching code. Environment variables are passed to your container and picked up on restart.

ActionDescription
AddSet a new key/value pair. Keys must be uppercase letters, numbers, and underscores.
EditChange an existing value. Triggers a container rebuild for it to take effect.
DeleteRemove the variable. Container restart required.

Common Environment Variables

WordPress (auto-set on switch)
WORDPRESS_DB_HOST=172.17.0.1:3306
WORDPRESS_DB_USER=root
WORDPRESS_DB_PASSWORD=<auto-generated>
WORDPRESS_DB_NAME=wordpress
Node.js (typical)
NODE_ENV=production
PORT=80
DATABASE_URL=mysql://root:pass@host:3306/dbname

⚠️ Changes require a rebuild — Some environment variables only take effect after the container is rebuilt. WordPress and Node.js switching handles this automatically, but individual env edits may need a manual restart from the Databases tab.

Databases

Every website can have its own dedicated MariaDB server, running on a separate node with its own public host and port. Creating one is a single click.

Creating a Database Server

1
Open the Databases tab
Click Create Database Server. The system picks the best available node automatically.
2
Choose a root password
Enter a password of at least 8 characters. This becomes the MYSQL_ROOT_PASSWORD.
3
Wait for installation
The MariaDB container is built, started, and warmed up. This takes 30–90 seconds.
4
Copy connection details
You'll see host, port, username (root), and password — all copyable with a single click.
Connecting from your application
# Example: MySQL CLI
mysql -h <public-host> -P <public-port> -u root -p

# Example: PHP (wp-config.php)
define('DB_HOST', '<public-host>:<public-port>');
define('DB_USER', 'root');
define('DB_PASSWORD', '<your-password>');
define('DB_NAME', 'wordpress');

Database Controls

ActionDescription
Start / Stop / RestartControl the MariaDB container lifecycle.
Change passwordUpdate the root password. Rebuilds the container to apply.
Show / hide passwordToggle password visibility in the connection panel.
RefreshRe-fetch connection details and running state.

✅ Automatic WordPress database — When you switch to WordPress, a database server is created automatically (if one doesn't exist), the wordpress database is created, and the environment variables are wired up for you.

Server Types

Switch between PHP, WordPress, and Node.js at any time. The switch rebuilds your container with the new image.

TypeImageWeb RootBest for
PHPphp:8.4-apache/var/www/htmlLaravel, Symfony, custom PHP, static sites
WordPresswordpress:php8.4-apache/var/www/htmlWordPress blogs, WooCommerce, agency sites
Node.jsnode:20-alpine/appExpress, Next.js, Fastify, custom APIs

⚠️ Data loss warning — Switching server type wipes the web root. Environment variables, port mappings, mounted volumes, and the database server are all preserved. But files inside the active web root are permanently deleted. Back up first.

Switching to Node.js — next steps

In the Debug Shell after switching
# 1. Upload your project to /app via File Manager
#    (package.json must be present)

# 2. Install dependencies and start your app
cd /app && npm install && npm start

# 3. Or use PM2 for process management
npm install -g pm2
pm2 start app.js --name my-app
pm2 save

Debug Shell

A live interactive shell running inside your container as root. Use it for installing dependencies, running migrations, debugging, and anything else you'd do over SSH.

Root access
Full privileges inside the container. Install any package.
Command history
Navigate with the up/down arrow keys.
ANSI colours
Full colour support — output looks exactly like a real terminal.
Common shell commands
# PHP / WordPress
composer install
wp core update
wp plugin update --all

# Node.js
cd /app && npm install
cd /app && npm run build

# General
ls -la /var/www/html
df -h
free -m
htop
curl http://localhost

⚠️ Advanced users only — The shell runs as root inside your container. Mistakes here can break your website, delete files, or expose your data. There is no undo.

Logs

The Logs tab streams the last 500 lines of stdout and stderr from your container. Useful for debugging PHP warnings, Apache errors, Node.js crashes, and application output.

💡 Tip — If Apache or Node.js output isn't appearing, check that your application logs to stdout/stderr. Files written to disk are not captured by the log viewer.

Performance

Live metrics for your container, refreshed every 6 seconds.

MetricWhat it shows
CPUCurrent CPU usage as a percentage of your container's limit.
MemoryRAM used by the container relative to its allocation.
DiskPersistent volume usage.
UptimeTime since the container last started.

💡 Persistent volumes — Your web root and database data live on persistent volumes. Restarting the container or switching server type does not delete them (except for the web root when switching types).

SSL & HTTPS

Every connected domain gets a free SSL certificate automatically. Certificates are issued by our edge network when DNS resolves, and renewed without any action on your part.

Automatic issuance
Certificates are issued as soon as DNS resolves to our edge.
Auto-renewal
Renewed 30 days before expiry — no action required.
Edge termination
TLS terminates at our edge — your container receives plain HTTP on port 80.

⚠️ Behind Cloudflare — When using Cloudflare's proxy, our edge receives HTTP from Cloudflare. This is why Flexible mode is required: Cloudflare handles client-side HTTPS, and forwards plain HTTP to us.

Troubleshooting

Domain not working

⏱️ Wait 3–4 minutes first — DNS propagation is not instant. Refresh your browser and try again after a few minutes.

⏳ Still not working? Wait up to 1 hour — Some DNS providers cache records aggressively. Intermittent access on different networks during this window is normal.

🔍 After 1 hour, re-verify your configs — Check that the record type is CNAME, the name matches exactly, the target is web-proxy-global.shulker.in (no trailing dot), no conflicting A/AAAA records exist, and the record is enabled.

☁️ Using Cloudflare proxy? — Set SSL/TLS mode to Flexible. Any other mode will break your site. Revisit Cloudflare → SSL/TLS → Overview.

SSL errors / redirect loop

🔄 Redirect loop or 525/526 — Almost always a Cloudflare SSL/TLS mode issue. Set it to Flexible and clear your browser cache.

Database not connecting

🔌 Check the connection details — Host and port come from the Databases tab. If you set them as WORDPRESS_DB_HOST or similar, make sure the value is host:port (with port).

♻️ Restart the database — Use the Databases tab → Restart button. MariaDB sometimes needs a warm-up after a fresh install.

Files not uploading

📁 Large files — Files over 1.5 MB are automatically chunked. If uploads stall, try again — the chunked uploader resumes from the last successful chunk.

Server type switch failed

🔄 Try again — The switch involves several API calls. Network hiccups can leave the operation half-finished. Retry from the Server Type tab.

Still stuck?

💬 Contact support — Provide your server name and a screenshot of the issue. Reach us at shulker.in/contact or on Discord.

Best Practices

📦 Back up before switching — Server type changes wipe the web root. Download a copy of your files first via File Manager or the debug shell.

🔑 Use environment variables — Never hard-code credentials in your source. Store them as environment variables and read them at runtime.

🧪 Test with the direct URL — Before DNS is configured, use the IP:port URL from the Ports tab to test your site. Faster iteration, no DNS waiting.

🗄️ Use a separate database server — For anything production, always create a dedicated database server. It isolates load and can be scaled independently.

📊 Monitor performance — Check the Performance tab regularly. If CPU or memory is consistently high, upgrade your plan.

🔒 Enable Cloudflare proxy for production — Orange cloud protects your origin, adds caching, and speeds up global delivery. Just remember to set SSL/TLS to Flexible.

🧹 Keep the web root clean — Delete unused plugins, themes, and packages. Smaller web roots mean faster deployments and fewer vulnerabilities.

Quick Reference

Key paths & targets
# DNS target
web-proxy-global.shulker.in

# Web roots
/var/www/html     # PHP & WordPress
/app              # Node.js

# Default ports
Container HTTP port : 80
Database port       : 3306

# Panel URL format
https://shulker.in/panel/dashboard/server/<server-id>

# Support
https://shulker.in/contact
https://discord.gg/shulker
Common shell commands
# PHP
composer install
composer update

# WordPress
wp core update
wp plugin update --all
wp theme update --all
wp db export backup.sql

# Node.js
cd /app && npm install
cd /app && npm run build
pm2 restart all

# System
ls -la /var/www/html
df -h
free -m
curl http://localhost
Diagnostic checklist
# Is the container running?
curl -I http://localhost

# Are DNS records correct?
dig +short yourdomain.com

# Is MariaDB reachable?
mysql -h <db-host> -P <db-port> -u root -p -e "SELECT 1"

# Disk usage
du -sh /var/www/html/*

# Recent logs
tail -n 100 /var/log/apache2/error.log