Skip to main content

Command Palette

Search for a command to run...

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

Updated
6 min read
🛡️ Hands-On VPS Setup with CWP ⚙️ — From Install to Laravel Deployment
M

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: root

  • Password: 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 229443 (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 Domain

  • Subdomain: Domains → Subdomain → Add

  • SSL: Webserver Settings → SSL Certificates → AutoSSL → Install

📂 File Structure

  • Main domain → /home/USERNAME/public_html/

  • Addon domain → /home/USERNAME/public_html/example.com

  • Subdomain → /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:

  1. Go to: User Account → File Management → File Manager

  2. Navigate to your project directory (/public_html/…)

  3. Upload a .zip file of your project

  4. Extract 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.com

  • Password: (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 .env and DB settings

  • Assets missing → php artisan storage:link or /public misconfig

  • Permissions → 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.

More from this blog

I

Insaf’s Dev Journal

28 posts