Complete VPS Setup Guide Bangla: Ubuntu VPS-এ PHP, Laravel, WordPress, Django, Node.js, Database, SSL, File Upload, phpMyAdmin ও Multi-Site Hosting
Beginner থেকে advanced level পর্যন্ত VPS setup, multi-site hosting, SSL, database import, permission fix, upload issue, Nginx rewrite এবং lightweight admin workflow—সব এক জায়গায়।
example.com, app.example.com, example_user, example_db ব্যবহার করা হয়েছে। অনুমতি ছাড়া সরকারি/ব্যাংক/তৃতীয় পক্ষের সাইটের মতো subdomain, layout, certificate, login বা data flow বানানো উচিত নয়।
Table of Contents
- VPS কী, SSH কী, VNC কী?
- Best Setup: Panel নাকি Terminal?
- Initial Server Update
- Sudo User তৈরি
- Basic Security
- Nginx Install
- PHP 8.3-FPM
- MySQL Setup
- Website Files কোথায় রাখবে?
- WinSCP Permission Problem
- Zip Upload ও Unzip
- Nginx Site Config
- PHP Download Problem
- Duplicate Location Error
- Domain Add
- SSL Install
- Certbot Error
- Cloudflare SSL
- Multi-Site Setup
- Subdomain Add
- Long Subdomain Error
- 403 Forbidden Fix
- Custom 403 Page
- .htaccess বনাম Nginx
- Nginx Rewrite Example
- SQL Import
- SQL Progress
- Table Already Exists
- Database Connection Error
- NO_AUTO_CREATE_USER Error
- বাংলা লেখা ???? Fix
- Mojibake Fix
- Bangla Font Problem
- PHP Upload Permission
- PHP Relative Path
- 413 Upload Error
- phpMyAdmin Install
- Hidden phpMyAdmin
- Nginx Include Error
- Laravel Setup
- WordPress Setup
- Django / Flask Setup
- Node.js Setup
- API / Automation
- Logs
- Upload Debug Checklist
- Mini cPanel Blueprint
- Mini cPanel Folder Structure
- Backup System
- Security Checklist
1. VPS কী, SSH কী, VNC কী, CMD/PowerShell কী?
VPS হলো তোমার নিজের ছোট cloud server। এখানে তুমি একাধিক ওয়েবসাইট চালাতে পারো, যেমন normal PHP website, WordPress, Laravel, Django/Flask, Node.js app, API, database-backed dashboard, file upload system এবং PDF processing system।
SSH হলো server manage করার সবচেয়ে ভালো পদ্ধতি। Windows CMD বা PowerShell থেকে SSH করা যায়:
ssh example_user@YOUR_SERVER_IP
VNC হলো emergency screen access। SSH কাজ না করলে বা firewall mistake করলে VNC দিয়ে ঢোকা যায়। Daily কাজের জন্য SSH ভালো।
WinSCP হলো Windows থেকে server-এ file upload/download/edit করার সহজ tool। তবে permission ঠিক না থাকলে WinSCP দিয়ে file edit/upload করা যায় না।
2. VPS-এর জন্য Best Setup: Panel নাকি Terminal?
ছোট VPS হলে heavy cPanel/GUI panel না দিয়ে light setup ভালো। Recommended stack:
Ubuntu 24.04
Nginx
PHP 8.3-FPM
MySQL 8
Certbot SSL
UFW Firewall
Fail2Ban
WinSCP for file upload
phpMyAdmin hidden/private path
Supervisor/PM2 for Python/Node
এই setup fast, secure, lightweight, multi-site friendly.
3. Initial Server Update
sudo apt update
sudo apt upgrade -y
Kernel update message এলে reboot করো:
sudo reboot
Reboot করার পর আবার SSH:
ssh example_user@YOUR_SERVER_IP
Check:
uname -r
4. Root User না, আলাদা Sudo User ব্যবহার করো
Root দিয়ে সব কাজ করলে mistake হলে server নষ্ট হতে পারে। আলাদা user তৈরি করো:
adduser example_user
usermod -aG sudo example_user
su - example_user
sudo whoami
যদি output হয় root, তাহলে sudo ঠিক আছে।
5. Basic Security Setup
sudo apt install ufw fail2ban unzip curl git nano -y
sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
sudo ufw status
sudo systemctl status fail2ban
6. Nginx Install ও Check
sudo apt install nginx -y
sudo systemctl status nginx
Browser-এ IP দিলে যদি “Welcome to nginx” আসে, তাহলে Nginx কাজ করছে।
7. PHP 8.3-FPM Install
sudo apt install php8.3-fpm php8.3-mysql php8.3-cli php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-bcmath php8.3-intl -y
php -v
sudo systemctl status php8.3-fpm
8. MySQL Install ও Secure Setup
sudo apt install mysql-server -y
sudo mysql_secure_installation
Recommended answers:
Set root password? N
Remove anonymous users? Y
Disallow root login remotely? Y
Remove test database? Y
Reload privilege tables? Y
sudo mysql
CREATE DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'StrongPasswordHere';
GRANT ALL PRIVILEGES ON example_db.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Important: প্রত্যেক SQL command-এর শেষে ; দিতে হবে।
9. Website Files কোথায় রাখবে?
/var/www/example-site
/var/www/app-one
/var/www/app-two
sudo mkdir -p /var/www/example-site
sudo chown -R example_user:www-data /var/www/example-site
sudo find /var/www/example-site -type d -exec chmod 775 {} \;
sudo find /var/www/example-site -type f -exec chmod 664 {} \;
sudo chmod g+s /var/www/example-site
এতে example_user WinSCP দিয়ে upload/edit করতে পারবে এবং www-data PHP/Nginx দিয়ে read/write করতে পারবে।
10. WinSCP Permission Problem কেন হয়?
যদি WinSCP বলে Permission denied, কারণ সাধারণত /var/www/... folder-এর owner root বা permission restricted.
sudo chown -R example_user:www-data /var/www/example-site
sudo find /var/www/example-site -type d -exec chmod 775 {} \;
sudo find /var/www/example-site -type f -exec chmod 664 {} \;
sudo chmod g+s /var/www/example-site
Upload folder-এর জন্য:
sudo mkdir -p /var/www/example-site/uploads
sudo chown -R www-data:www-data /var/www/example-site/uploads
sudo chmod -R 775 /var/www/example-site/uploads
11. Zip Upload করার পর Unzip
cd /var/www/example-site
unzip site.zip
অথবা absolute path:
sudo unzip /var/www/example-site/site.zip -d /var/www/example-site
যদি file not found হয়:
find / -name "site.zip" 2>/dev/null
12. Nginx Site Config কোথায় থাকে?
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/
sudo nano /etc/nginx/sites-available/example-site
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example-site;
index index.php index.html;
charset utf-8;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\. {
deny all;
}
autoindex off;
}
sudo ln -s /etc/nginx/sites-available/example-site /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
13. PHP File Download হয়ে যাচ্ছে কেন?
যদি .php file browser-এ download হয়, তাহলে Nginx PHP-FPM-এ পাঠাচ্ছে না। Fix:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart php8.3-fpm
14. Duplicate Location Error
একই server block-এর ভিতরে দুইবার location / থাকলে error হবে। ভুল:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location / {
try_files $uri $uri/ =404;
}
সঠিক:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
15. Domain Add করার Step
Type: A
Name: @
Value: YOUR_SERVER_IP
Proxy: DNS only or proxied depending on Cloudflare setup
Type: CNAME
Name: www
Value: example.com
ping example.com
16. SSL Install with Certbot
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem
17. Certbot Unauthorized / 404 Error কেন হয়?
কারণ হতে পারে domain server IP-তে point করেনি, Cloudflare proxy issue, Nginx config ভুল, port 80 বন্ধ, wrong root/server_name, বা AAAA record অন্য জায়গায় point করছে।
sudo ufw allow 80
sudo ufw allow 443
sudo nginx -t
sudo systemctl reload nginx
Cloudflare ব্যবহার করলে SSL mode: Full (strict).
18. Cloudflare SSL: VPS-এ SSL লাগবে কি?
হ্যাঁ, best practice হলো VPS-এও SSL লাগবে।
Flexible avoid
Full okay but less strict
Full Strict best
- VPS-এ Certbot দিয়ে SSL install।
- Cloudflare SSL/TLS mode: Full Strict।
- Always Use HTTPS: ON।
- Automatic HTTPS Rewrites: ON।
19. Multi-Site Setup কী?
example.com -> /var/www/example-main
app.example.com -> /var/www/example-app
blog.example.com -> /var/www/example-blog
client-one.example.com -> /var/www/client-one
প্রতিটি site-এর জন্য আলাদা folder, Nginx config, database, database user, SSL, upload folder permission রাখবে।
20. Subdomain Add করার Step
Type: A
Name: app
Value: YOUR_SERVER_IP
sudo mkdir -p /var/www/app-example
sudo chown -R example_user:www-data /var/www/app-example
sudo chmod -R 775 /var/www/app-example
server {
listen 80;
server_name app.example.com;
root /var/www/app-example;
index index.php index.html;
charset utf-8;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\. {
deny all;
}
autoindex off;
}
sudo ln -s /etc/nginx/sites-available/app-example /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d app.example.com
21. Long Subdomain দিলে Nginx Error
sudo nano /etc/nginx/nginx.conf
http { ... } block-এর ভিতরে add/update:
server_names_hash_bucket_size 128;
sudo nginx -t
sudo systemctl reload nginx
22. 403 Forbidden দেখালে কী করবে?
403 হয় সাধারণত index file নেই, permission ভুল, root path ভুল, PHP config ভুল, অথবা file owner wrong হলে।
ls -la /var/www/example-site
echo "Site Working" | sudo tee /var/www/example-site/index.html
sudo chown -R example_user:www-data /var/www/example-site
sudo find /var/www/example-site -type d -exec chmod 775 {} \;
sudo find /var/www/example-site -type f -exec chmod 664 {} \;
23. 403 Page নিজের মতো দেখাতে চাইলে
sudo nano /var/www/example-site/403.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Access Restricted</title>
</head>
<body>
<h1>Access Restricted</h1>
<p>This page is not publicly available.</p>
</body>
</html>
error_page 403 /403.html;
location = /403.html {
internal;
}
24. .htaccess Nginx-এ কাজ করে না
Apache-এ .htaccess কাজ করে। Nginx .htaccess পড়ে না। তাই rewrite rule Nginx config-এ দিতে হয়।
location ~ ^/verify/([A-Za-z0-9=_-]+)/?$ {
rewrite ^/verify/([A-Za-z0-9=_-]+)/?$ /verify.php?id=$1 last;
}
autoindex off;
add_header X-Robots-Tag "noindex, nofollow, noarchive, nosnippet, noimageindex" always;
25. Clean Nginx Rewrite Example
server {
listen 80;
server_name app.example.com;
root /var/www/app-example;
index index.php index.html;
charset utf-8;
client_max_body_size 100M;
autoindex off;
add_header X-Robots-Tag "noindex, nofollow, noarchive, nosnippet, noimageindex" always;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ ^/verify/([A-Za-z0-9=_-]+)/?$ {
rewrite ^/verify/([A-Za-z0-9=_-]+)/?$ /verify.php?id=$1 last;
}
location ~ ^/print/([A-Za-z0-9=_-]+)/?$ {
rewrite ^/print/([A-Za-z0-9=_-]+)/?$ /print.php?id=$1 last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\. {
deny all;
}
}
26. SQL File Upload ও Import
mysql -u example_user -p example_db < /var/www/example-site/example.sql
Password চাইবে। Password paste করলে screen-এ দেখা যাবে না—এটাই normal.
27. SQL Import Progress দেখা যায় না কেন?
sudo apt install pv -y
pv /var/www/example-site/example.sql | mysql -u example_user -p example_db
28. Table Already Exists Error
sudo mysql
DROP DATABASE example_db;
CREATE DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON example_db.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
mysql -u example_user -p example_db < /path/to/file.sql
Existing table রেখে import করতে চাইলে:
mysql -u example_user -p --force example_db < /path/to/file.sql
29. Database Connection Error Fix
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'example_user');
define('DB_PASS', 'StrongPasswordHere');
define('DB_NAME', 'example_db');
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$conn = new mysqli("localhost", "example_user", "StrongPasswordHere", "example_db");
if ($conn->connect_error) {
die("DB Failed: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
echo "Database Connected Successfully";
Test শেষে file delete করো।
30. MySQL NO_AUTO_CREATE_USER Error
MySQL 8-এ NO_AUTO_CREATE_USER removed। PHP code বা SQL file থেকে এটা remove করতে হবে।
$this->conn->query("SET SESSION sql_mode = 'STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO'");
sudo systemctl restart php8.3-fpm
31. বাংলা লেখা ???? দেখায় কেন?
- PHP file encoding UTF-8 নয়।
- HTML meta charset নেই।
- MySQL database/table/column charset wrong।
- MySQL connection charset set করা হয়নি।
- Font বাংলা support করে না।
- আগের server থেকে already corrupted text import হয়েছে।
- বা যখন মাইগ্রেশনের সময় ফাইল গুলো আপলোড দেয়া হচ্ছিল তখন কোনো একটা কারনে টেক্সট গুলো এমন হয়ে যেতে পারে।
<meta charset="UTF-8">
header('Content-Type: text/html; charset=utf-8');
$conn->set_charset("utf8mb4");
ALTER DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
32. Mojibake: দà§à¦ƒ... কেন হয়?
এটা সাধারণত UTF-8 text ভুল encoding হিসেবে read/write হলে হয়। যদি source file-এই এমন হয়ে থাকে, তাহলে server config দিয়ে পুরোপুরি ঠিক হবে না। Original UTF-8 source file লাগবে।
- VS Code / Notepad++ দিয়ে file open।
- Encoding: UTF-8।
- Save with UTF-8।
- Upload again।
- PHP header + HTML meta + DB utf8mb4 ensure করো।
33. Bangla Font Problem
CSS-এ @import সবসময় stylesheet-এর একদম উপরে রাখতে হবে।
@import url('font-url');
body {
margin: 0;
}
Better local font:
@font-face {
font-family: 'BanglaFont';
src: url('/fonts/NotoSansBengali.ttf') format('truetype');
}
body {
font-family: 'BanglaFont', sans-serif;
}
34. PHP Upload Permission Problem
sudo mkdir -p /var/www/example-site/uploads/pdf_temp
sudo chown -R www-data:www-data /var/www/example-site/uploads
sudo chmod -R 775 /var/www/example-site/uploads
Developer edit করতে চাইলে:
sudo usermod -aG www-data example_user
sudo chown -R example_user:www-data /var/www/example-site/uploads
sudo chmod -R 775 /var/www/example-site/uploads
sudo find /var/www/example-site/uploads -type d -exec chmod g+s {} \;
35. PHP Relative Path Problem
$uploadDir = __DIR__ . '/../uploads/pdf_temp/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0775, true);
}
move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $filename);
36. 413 Request Entity Too Large
client_max_body_size 100M;
sudo nano /etc/php/8.3/fpm/php.ini
upload_max_filesize = 100M
post_max_size = 120M
memory_limit = 256M
max_execution_time = 300
max_input_time = 300
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl restart php8.3-fpm
37. phpMyAdmin Install
sudo apt install phpmyadmin -y
Nginx-এ phpMyAdmin auto configure হয় না। তাই custom hidden path ভালো। কখনো common /phpmyadmin public রাখবে না।
38. phpMyAdmin Hidden Path Setup
sudo nano /etc/nginx/snippets/phpmyadmin-hidden.conf
location /secret-db-panel {
alias /usr/share/phpmyadmin/;
index index.php index.html;
location ~ ^/secret-db-panel/(.+\.php)$ {
alias /usr/share/phpmyadmin/$1;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME /usr/share/phpmyadmin/$1;
}
location ~* ^/secret-db-panel/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt|svg|woff|woff2|ttf))$ {
alias /usr/share/phpmyadmin/$1;
}
}
sudo nano /etc/nginx/sites-available/ip-default
server {
listen 80 default_server;
server_name _;
root /var/www/html;
index index.html;
include snippets/phpmyadmin-hidden.conf;
location / {
return 403;
}
}
sudo ln -s /etc/nginx/sites-available/ip-default /etc/nginx/sites-enabled/ip-default
sudo nginx -t
sudo systemctl reload nginx
39. Nginx include Command Not Found কেন?
include shell command না। এটা Nginx config-এর ভিতরে লিখতে হয়।
server {
...
include snippets/phpmyadmin-hidden.conf;
}
sudo nginx -t
sudo systemctl reload nginx
40. Laravel চালাতে কী লাগবে?
sudo apt install php8.3-fpm php8.3-cli php8.3-mysql php8.3-mbstring php8.3-xml php8.3-curl php8.3-zip php8.3-bcmath unzip git curl -y
cd ~
curl -sS https://getcomposer.org/installer -o composer-setup.php
php composer-setup.php
sudo mv composer.phar /usr/local/bin/composer
composer --version
Laravel project root হবে /var/www/laravel-app, কিন্তু Nginx root হবে /var/www/laravel-app/public।
server {
listen 80;
server_name laravel.example.com;
root /var/www/laravel-app/public;
index index.php;
charset utf-8;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\. {
deny all;
}
}
sudo chown -R example_user:www-data /var/www/laravel-app
sudo chmod -R 775 /var/www/laravel-app/storage
sudo chmod -R 775 /var/www/laravel-app/bootstrap/cache
cd /var/www/laravel-app
composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan config:cache
php artisan route:cache
php artisan view:cache
41. WordPress চালাতে কী লাগবে?
sudo mkdir -p /var/www/blog-example
sudo chown -R example_user:www-data /var/www/blog-example
CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'StrongPasswordHere';
GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'localhost';
FLUSH PRIVILEGES;
Nginx config normal PHP site-এর মতো হবে। WordPress file upload করে browser-এ setup run করো।
42. Django / Flask চালাতে কী লাগবে?
sudo apt install python3 python3-pip python3-venv supervisor -y
sudo mkdir -p /var/www/python-app
sudo chown -R example_user:www-data /var/www/python-app
cd /var/www/python-app
python3 -m venv venv
source venv/bin/activate
pip install django gunicorn
gunicorn --bind 127.0.0.1:8001 projectname.wsgi:application
[program:python-app]
directory=/var/www/python-app
command=/var/www/python-app/venv/bin/gunicorn --workers 2 --bind 127.0.0.1:8001 projectname.wsgi:application
user=www-data
autostart=true
autorestart=true
stderr_logfile=/var/log/python-app.err.log
stdout_logfile=/var/log/python-app.out.log
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status
server {
listen 80;
server_name py.example.com;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
43. Node.js App চালাতে কী লাগবে?
sudo apt install nodejs npm -y
sudo npm install -g pm2
cd /var/www/node-app
npm install
pm2 start app.js --name node-app
pm2 save
pm2 startup
server {
listen 80;
server_name node.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
44. PHP দিয়ে অন্য সাইটে Login Script / Data Send করলে কী লাগবে?
নিজের site/API হলে PHP cURL, Python requests, API token, webhook, cron job, secure credentials storage ব্যবহার করা যায়। কিন্তু অন্যের site-এ automation login, scraping, data push/pull করার আগে permission লাগে। Credentials collect করা, fake login page বানানো, সরকারি/ব্যাংক/তৃতীয় পক্ষের মতো domain/page বানানো risky এবং অনৈতিক/আইনগত সমস্যা হতে পারে।
$ch = curl_init("https://api.example.com/data");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"name" => "Test",
"status" => "active"
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Authorization: Bearer YOUR_API_TOKEN"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
45. Logs কীভাবে দেখবে?
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/php8.3-fpm.log
sudo systemctl status nginx
sudo journalctl -xeu nginx
php -l file.php
46. File Upload Debug Checklist
- Nginx size:
client_max_body_size 100M; - PHP size:
upload_max_filesize,post_max_size - Folder exists:
ls -la /var/www/example-site/uploads - Permission fix:
chown+chmod - PHP temp dir:
ls -ld /tmp - Error log:
sudo tail -f /var/log/nginx/error.log
47. Mini cPanel System — Safe Blueprint
Login system
Role: admin / developer / client
File manager
Zip upload
Auto extract
Database backup
Database import
Subdomain manager
Nginx config generator
SSL issue button
Service restart button
Logs viewer
Permission fixer
Upload folder fixer
Site status checker
Safe architecture:
Frontend: Laravel / PHP
Backend commands: restricted queue worker
No direct shell access from browser
Only predefined commands allowed
Audit log enabled
2FA recommended
IP allowlist recommended
Dangerous কাজ browser থেকে direct run করা যাবে না:
shell_exec($_GET['cmd']);
48. Mini cPanel Folder Structure
/var/www/mini-panel
├── public
├── app
├── storage
├── scripts
│ ├── create-site.sh
│ ├── fix-permission.sh
│ ├── backup-db.sh
│ ├── import-db.sh
│ └── issue-ssl.sh
└── .env
Panel নিজেই আলাদা subdomain-এ রাখা ভালো: panel.example.com
HTTPS only
Strong password
2FA
IP restriction
No public registration
No direct command input
49. Backup System
mkdir -p ~/backups/db
mysqldump -u example_user -p example_db > ~/backups/db/example_db_$(date +%F).sql
mkdir -p ~/backups/files
tar -czf ~/backups/files/example-site_$(date +%F).tar.gz /var/www/example-site
crontab -e
0 3 * * * mysqldump -u example_user -p'PASSWORD_HERE' example_db > /home/example_user/backups/db/example_db_$(date +\%F).sql
Better: password command-এ না রেখে .my.cnf ব্যবহার করো।
50. Security Checklist
Root SSH login disable
Password login disable if SSH key ready
UFW enabled
Fail2Ban enabled
Nginx server tokens off
PHP expose_php off
Database remote login off
phpMyAdmin hidden + protected
Daily backup
SSL auto renew
Upload file validation
No writable full site root
No public .env
No public SQL backup
No public zip backup
No public fake/impersonation domain
sudo nano /etc/nginx/nginx.conf
server_tokens off;
sudo nano /etc/php/8.3/fpm/php.ini
expose_php = Off
sudo systemctl reload nginx
sudo systemctl restart php8.3-fpm
Common Problems & Fast Fix Table
| Problem | Main Cause | Fast Fix |
|---|---|---|
| PHP download হচ্ছে | PHP-FPM block নেই | location ~ \.php$ add |
| 403 Forbidden | index নেই/permission ভুল | index file + permission fix |
| 413 Upload Error | Nginx/PHP upload limit কম | client_max_body_size, php.ini update |
| Permission denied WinSCP | folder owner root | chown example_user:www-data |
| PHP upload move failed | uploads folder writable নয় | chown www-data + chmod 775 |
| SQL import progress নেই | mysql silent | pv file.sql | mysql ... |
| Table exists | আগে import হয়েছে | Drop DB বা --force |
| DB connection fail | wrong user/pass/db | dbtest.php |
| Bangla ???? | charset/collation/font issue | utf8mb4 + UTF-8 file |
| .htaccess কাজ করছে না | Nginx .htaccess পড়ে না | Nginx rewrite |
| Certbot failed | DNS/Cloudflare/port issue | DNS + port 80 + config fix |
| duplicate location | same block repeated | duplicate remove |
| server_names_hash error | long subdomain | bucket size 128 |
Final Recommended Setup for Your VPS
/var/www/main-site
/var/www/client-one
/var/www/client-two
/var/www/laravel-app
/var/www/python-app
/var/www/node-app
Each site-এর জন্য separate folder, database, Nginx config, SSL এবং upload folder permission রাখবে।
Base stack: Nginx + PHP-FPM + MySQL + Certbot + WinSCP + hidden phpMyAdmin.
Advanced stack পরে: Laravel mini cPanel, file manager, DB backup/import UI, subdomain generator, SSL manager, auto deploy zip, permission fixer, log viewer.
সবচেয়ে গুরুত্বপূর্ণ কথা: VPS-এ কাজ করার সময় আগে nginx -t test করবে, তারপর reload করবে। File upload, DB import, SSL, subdomain—সব কাজের পর logs check করবে। আর কোনো production site edit করার আগে backup রাখবে।