Skip to main content

Command Palette

Search for a command to run...

🚀 Effortless Laravel + Filament Deployment: Mastering CloudPanel for Seamless App Hosting

Published
5 min read
🚀 Effortless Laravel + Filament Deployment: Mastering CloudPanel for Seamless App Hosting
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 been following this series, you already know we explored CWP (CentOS Web Panel) in detail:

👉 Hands-on VPS Setup with CWP — From Installation to Laravel Deployment

CWP works well — but it requires CentOS / AlmaLinux / Rocky Linux.
Not ideal if you're running Ubuntu or Debian.

This is where CloudPanel shines. A modern, lightweight, performance-focused panel that supports:

  • Ubuntu 22.04 / 24.04

  • Debian 11 / 12

And we already covered these distros in:

👉 VPS Control Panel Showdown — Which One Should You Trust?

Now let’s get hands-on and deploy a real Laravel + Filament application with CloudPanel.


🛡️ Step 1 — Secure Your Server

Before deploying anything, harden your VPS.

If you haven’t done this yet, follow my full guide:

👉 Fortify Your DigitalOcean Droplet — A Step-by-Step Security Guide for Ubuntu 24.04

Once the essentials are done, SSH into your machine:

ssh root@your_server_ip

⚙️ Step 2 — Install CloudPanel on Server

CloudPanel’s installation is unbelievably simple.

Official docs:

Run the installer:

curl -sSL https://installer.cloudpanel.io/ce/v2/install.sh | sudo bash

The script sets up:

  • NGINX

  • PHP

  • MariaDB/MySQL

  • Redis

  • CloudPanel Dashboard

Once done:

  • Access CloudPanel Dashboard: https://your-server-ip:8443

  • Then reboot:

sudo reboot

Messed something up or want a clean restart? No worries — CloudPanel’s uninstall guide lets you reset everything quickly.


🌐 Step 3 — Set Up Your Site

Once inside CloudPanel:

  1. Create an admin account

  2. Go to Sites → Create Site

  3. Choose:

    • Application: Laravel 11

    • Your domain name

    • A site user (auto-generated or custom)

Finally, set your DNS A record to the server’s IP.
Your domain should now show CloudPanel’s default PHP page.


💻 Step 4 — Install Node.js via NVM

Filament uses Vite, so you need Node.js.

Follow this guide:

👉 FreeCodeCamp — Complete NVM (Node Version Manager) Setup Guide

Then:

nvm install --lts

📂 Step 5 — Upload & Setup Project

For this example, I used the official demo:

👉 Filament PHP — Official Demo Repository (GitHub)

Inside CloudPanel:

  1. Open File Manager

  2. Go to:

/home/<username>/htdocs/<domain>/public
  1. Upload your project ZIP

  2. Extract it

If needed, update the Root Directory from:

Site → Settings → Root Directory

This ensures CloudPanel serves the correct public/ folder.


🗄️ Step 6 — Database & Configuration

In CloudPanel:

  1. Go to Databases

  2. Create a new DB + user

Update .env:

DB_HOST=localhost
DB_DATABASE=your_db_name
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_pass

Then inside your site directory:

composer install
npm install
npm run build

If the repo includes a setup script (e.g., composer setup), run that too.

Don’t forget to enable SSL from CloudPanel — one click via Let's Encrypt.


❗ Step 7 — Resolve Filament Issues

After logging in, you probably saw:

  • No dashboard redirection

  • Missing Filament assets

This is a known NGINX quirk on CloudPanel.

I fixed it using these references:

Final vhost configuration (replace with your own) looked like this:

server {
  listen 80;
  listen [::]:80;
  listen 443 quic;
  listen 443 ssl;
  listen [::]:443 quic;
  listen [::]:443 ssl;
  http2 on;
  http3 off;
  ssl_stapling off;
  ssl_stapling_verify off;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name invo.<example.com>;
  {{root}}

  {{nginx_access_log}}
  {{nginx_error_log}}

  if ($scheme != "https") {
    rewrite ^ https://$host$request_uri permanent;
  }

  location ~ /.well-known {
    auth_basic off;
    allow all;
  }

  {{settings}}

  include /etc/nginx/global_settings;

  location / {
    {{varnish_proxy_pass}}
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_hide_header X-Varnish;
    proxy_redirect off;
    proxy_max_temp_file_size 0;
    proxy_connect_timeout      720;
    proxy_send_timeout         720;
    proxy_read_timeout         720;
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    proxy_temp_file_write_size 256k;
  }

  location ^~ /livewire/ {
    {{varnish_proxy_pass}}
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_hide_header X-Varnish;
    proxy_redirect off;
  }

  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    add_header alt-svc 'h3=":443"; ma=86400';
    expires max;
    access_log off;
  }

  if (-f $request_filename) {
    break;
  }
}

server {
  listen 8080;
  listen [::]:8080;
  server_name invo.<example.com>;
  {{root}}

  index index.php index.html;

  charset utf-8;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ^~ /filament {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location = /favicon.ico { access_log off; log_not_found off; }
  location = /robots.txt  { access_log off; log_not_found off; }

  error_page 404 /index.php;

  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
  }

  location ^~ /livewire/ {
    try_files $uri /index.php?$query_string;
  }

  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    expires max;
    access_log off;
  }

  if (-f $request_filename) {
    break;
  }
}

After updating:

sudo nginx -t
sudo systemctl restart nginx

Boom — Filament dashboard working perfectly.


🎉 Final Thoughts

CloudPanel makes Laravel + Filament deployments smooth and efficient.
But as with any real-world setup, you may have to tweak NGINX for advanced frameworks like Filament.

Why CloudPanel is still my favorite for Laravel deployments:

✔ Zero manual LEMP configuration
✔ PHP-FPM & NGINX are auto-optimized
✔ User isolation per website
✔ Super easy SSL
✔ UI is clean and fast
✔ Works great on lightweight VPS servers

If you're deploying Laravel or Filament apps regularly, CloudPanel hits the sweet spot between simplicity, performance, and production readiness.

More from this blog

I

Insaf’s Dev Journal

28 posts