🛡️ Hands-On VPS Setup with CWP ⚙️ — From Install to Laravel Deployment

I’m Insaf Nilam, a full-stack developer passionate about crafting clean, efficient, and future-ready software. I love solving complex problems, exploring new tech stacks, and sharing my learnings through blogs. When I’m not coding, I’m probably tweaking deployments, experimenting with microservices, or geeking out over cloud architecture.
If you’ve ever used cPanel, you know how easy hosting can be. The problem? It’s expensive — often $15–45/month. That’s where CWP (Control Web Panel) comes in: a free, powerful alternative that gives you nearly all the features of cPanel without the price tag. Perfect for developers, startups, or anyone hosting modern web apps.
In this guide, we’ll go hands-on:
✅ Set up a fresh VPS
✅ Install and secure CWP
✅ Configure domains and SSL
✅ Deploy a Laravel + React app with GitHub Actions 🚀
🖥️ What You’ll Need
A fresh VPS (CentOS 7/8/9, AlmaLinux, or Rocky Linux)
Root SSH access
A registered domain (e.g., from Namecheap, Cloudflare, or GoDaddy)
1. Preparing the Server
Log into your VPS via SSH:
ssh root@<your-server-ip>
Set a hostname:
hostname cwp.example.com
Install required packages:
yum -y install wget
Fix repo mirrors (CentOS 7 only):
curl http://centos-webpanel.com/centos7_fix_repository | sh
For CentOS 8/AlmaLinux/Rocky:
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install wget -y
Update and reboot:
yum -y update
reboot
2. Set Hostname
Edit /etc/hostname:
nano /etc/hostname
Example:
cwp.example.com
Reboot again to apply:
reboot
3. Install CWP
Choose the script for your OS version:
CentOS 7
cd /usr/local/src
wget http://centos-webpanel.com/cwp-el7-latest
sh cwp-el7-latest
CentOS 8 / AlmaLinux 8 / Rocky 8
cd /usr/local/src
wget http://centos-webpanel.com/cwp-el8-latest
sh cwp-el8-latest
CentOS 9 / AlmaLinux 9 / Rocky 9
cd /usr/local/src
wget http://centos-webpanel.com/cwp-el9-latest
sh cwp-el9-latest
After install:
Copy your login details.
Reboot the server.
shutdown -r now
4. Access the CWP Dashboard
Open in browser:
https://<your-server-ip>:2031/
Username:
rootPassword: root password
5. Secure & Optimize CWP
🔐 Security
Enable ModSecurity:
Security → Mod Security → Install → Restart web server
Enable Firewall (CSF + LFD):
Security → Firewall Manager → Enable
Hide Processes:
Security → Secure Processes → Enable
Note: you may need to create a new, non-root user account to manage these secure processes
Set Notification Alerts:
Email Alerts:
<admin-email>Sender Email:
notifications@<example.com>Type: info/warning/danger
Set Monit Monitoring (pro):
Services Config → Monit Monitoring
Set CSF/LFD Firewall Alerts:
csf/lfd alerts:
<admin-email>Admin Email:
notifications@<example.com>
Change SSH Port (Optional but Recommended):
nano /etc/ssh/sshd_config
Change Port 22 → 9443 (or any unused port).
Update CSF Firewall rules:
Security → CSF Firewall → Firewall Configuration
TCP_IN "...,9443"
TCP_OUT "...,9443"
Restart firewall and SSH server:
Security → CSF Firewall → Restart
Dashboard → Restart SSH
⚙️ Server Settings
- Change hostname:
Server Settings → Change Hostname → cwp.example.com
(💡 Note: The hostname must already point to your VPS public IP)
🛠️ Stack & PHP
Webserver Stack: Nginx + Varnish + Apache (recommended)
PHP: Switch to 8.2 or 8.3 via PHP Version Switcher
6. Add Domain & SSL
🏷️ Create a New Account
User Accounts → New Account
Domain (must point to your VPS IP)
Username & Password
This creates:
/home/USERNAME/public_html/
You can manage accounts later via:
User Accounts → List Accounts → (select account)
🌐 DNS Records
Update DNS via Cloudflare, Namecheap, or GoDaddy:
@ → VPS IP
www → VPS IP
cwp → VPS IP
➕ Add Domains & Subdomains
Addon Domain:
Domains → Add DomainSubdomain:
Domains → Subdomain → AddSSL:
Webserver Settings → SSL Certificates → AutoSSL → Install
📂 File Structure
Main domain →
/home/USERNAME/public_html/Addon domain →
/home/USERNAME/public_html/example.comSubdomain →
/home/USERNAME/public_html/sub.example.com
7. Deployment Options
You can deploy your project in two ways:
Option 1: Manual Upload (Quick & Simple)
If you’re not using CI/CD:
Go to:
User Account → File Management → File ManagerNavigate to your project directory (
/public_html/…)Upload a
.zipfile of your projectExtract directly in File Manager (like Windows zip-extract)
Option 2: FTP for CI/CD (Automated)
If you’re using GitHub Actions or any CI/CD:
Go to:
File Management → FTP Accounts → Create
Fill in:
Username:
sub@example.comPassword: (strong password)
Path:
/public_html/<sub>.<example.com>
These credentials (FTP_USER, FTP_PASSWORD) are what you’ll add to GitHub Secrets for automated deployments.
8. CI/CD with GitHub Actions
Here’s a deploy.yml for Laravel + React:
name: 🚀 Deploy website
on:
push:
branches:
- main
jobs:
web-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with: { php-version: "8.2" }
- run: composer install --no-interaction --prefer-dist --optimize-autoloader
- run: php artisan storage:link
- uses: actions/setup-node@v4
with: { node-version: "21" }
- run: npm install
- run: npm run build
- uses: SamKirkland/FTP-Deploy-Action@v4.3.4
with:
server: ${{ secrets.FTP_SERVER }}
port: ${{ secrets.FTP_PORT }} # usually 21
username: ${{ secrets.FTP_USER }}
password: ${{ secrets.FTP_PASSWORD }}
server-dir: /
👉 Store FTP credentials in GitHub Secrets.
⚠️ Laravel’s Public Directory Issue
By default, Apache (on CWP) serves from:
/home/USERNAME/public_html/
But Laravel expects traffic to go through /public.
If you just deploy as-is, your app may break (CSS/JS not loading, routes failing).
To fix this, you have two options:
✅ Option 1: .htaccess Redirect (Quick Fix)
Inside /home/USERNAME/public_html/, create or edit .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
# Redirect all requests to /public
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]
# Laravel routing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ public/index.php [L]
</IfModule>
This forces Apache to serve your Laravel app correctly from /public.
✅ Option 2: Change Document Root (Cleaner)
In CWP:
WebServer Settings → WebServers Domain Conf → Select Domain → Edit Virtual Host
Update DocumentRoot:
DocumentRoot /home/USERNAME/public_html/public
Then restart Apache/Nginx.
This way, you don’t need a .htaccess redirect.
🔍 Troubleshooting Tips:
White page / 500 error → check
.envand DB settingsAssets missing →
php artisan storage:linkor /public misconfigPermissions →
chown -R USERNAME:USERNAME /home/USERNAME/public_html/
✅ Now, every push to main auto-deploys your Laravel + React app.
9. Why Consider CWPpro?
While the free version is powerful, CWPpro unlocks:
Advanced monitoring
Faster updates
More security features
If your VPS has enough resources, it’s worth it.
🎯 Final Thoughts
CWP isn’t the easiest control panel to set up, but once configured:
✅ Free alternative to cPanel
✅ Built-in firewall, SSL, ModSecurity
✅ Multiple PHP versions & webserver stacks
✅ Works great for Laravel, React, and modern apps
It’s the closest you’ll get to cPanel features — without the cPanel price tag.




