🚀 Complete VPS Setup Master Guide

PHP 8.3 • WireGuard • Webmin • MySQL • phpMyAdmin • UFW • SSL Auto-Renewal

🔥 100+ Commands 📋 Copy Ready 🛡️ Security Focused 🎨 Webmin GUI Guide

📦 Initial System Update

Update package list and upgrade system
apt update && apt upgrade -y
Install essential tools
apt install -y curl wget git nano unzip software-properties-common gnupg2 ca-certificates lsb-release ubuntu-keyring

🐘 PHP 8.3 Installation

PHP 8.3 is the latest stable version with performance improvements and new features.
Add PHP repository
add-apt-repository ppa:ondrej/php -y && apt update
Install PHP 8.3 with common extensions
apt install -y php8.3 php8.3-cli php8.3-common php8.3-mysql php8.3-zip php8.3-gd php8.3-mbstring php8.3-curl php8.3-xml php8.3-bcmath php8.3-json php8.3-tokenizer php8.3-fpm
Verify PHP installation
php -v

🔒 WireGuard VPN Setup (Port 1198)

Ensure UDP port 1198 is open in your firewall and VPS provider panel!
Install WireGuard
apt install -y wireguard wireguard-tools
Generate server private and public keys
mkdir -p /etc/wireguard && cd /etc/wireguard && wg genkey | tee server_private.key | wg pubkey > server_public.key && chmod 600 server_private.key
Create WireGuard server configuration (listen port 1198)
cat > /etc/wireguard/wg0.conf << 'EOF' [Interface] Address = 10.0.0.1/24 ListenPort = 1198 PrivateKey = $(cat /etc/wireguard/server_private.key) SaveConfig = true EOF

🔓 Make WireGuard Contents Accessible Everywhere

This allows easy access to client configurations for download
Create web-accessible directory for WireGuard configs
mkdir -p /var/www/html/wireguard && ln -s /etc/wireguard /var/www/html/wireguard/configs && chmod -R 755 /etc/wireguard /var/www/html/wireguard
Or use Apache alias (if Apache installed)
echo "Alias /wireguard /etc/wireguard" > /etc/apache2/conf-available/wireguard.conf && a2enconf wireguard && systemctl reload apache2
✅ Now access configs at: http://your-server-ip/wireguard/ or http://your-domain.com/wireguard/
Start and enable WireGuard
systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
Check WireGuard status
wg show

🗄️ MySQL Installation

Install MySQL server
apt install -y mysql-server
Secure MySQL installation
mysql_secure_installation
Check MySQL status
systemctl status mysql

📊 phpMyAdmin Installation

Install phpMyAdmin
apt install -y phpmyadmin
Configure phpMyAdmin for Apache (if using Apache)
ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin && systemctl restart apache2

🛡️ UFW Firewall Configuration

⚠️ NEVER close port 22 until you've tested new SSH connection!
Install and enable UFW
apt install -y ufw && ufw --force enable
Allow all required ports PERMANENTLY
ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw allow 10000/tcp && ufw allow 20000/tcp && ufw allow 1198/udp

📋 Port Summary

PortProtocolService
22TCPSSH (Secure Shell)
80TCPHTTP (Web)
443TCPHTTPS (Secure Web)
10000TCPWebmin
20000TCPUsermin (optional)
1198UDPWireGuard VPN
Verify UFW status
ufw status verbose

🌐 Webmin Installation

Add Webmin repository
curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh && sh setup-repos.sh
Install Webmin
apt install -y webmin
Restart and enable Webmin
systemctl restart webmin && systemctl enable webmin

👤 Creating User with Root Permissions

Replace 'admin' with your desired username
Create new user
adduser admin
Add user to sudo group
usermod -aG sudo admin
Give full root privileges (edit sudoers)
echo "admin ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/admin
Allow Webmin access for new user
echo "admin:x:$(id -u admin):$(id -g admin):Admin:/home/admin:/bin/bash" >> /etc/webmin/webmin-users
Test user access
su - admin && sudo whoami

🎨 Webmin GUI: Adding Domains & SSL

📌 Step 1: Access Webmin

Open browser and navigate to: https://your-server-ip:10000

Login with root or the new user you created.

📁 Step 2: Create the Website Directory

Create directory, set owner and permissions
mkdir -p /var/www/yourdomain.com && chown -R www-data:www-data /var/www/yourdomain.com && chmod -R 755 /var/www/yourdomain.com

🌍 Step 3: Add Virtual Host (Domain)

  1. Go to Servers → Apache Webserver
  2. Click Create Virtual Host tab
  3. Fill in:
    • Port: 80
    • Document Root: /var/www/yourdomain.com
    • Server Name: yourdomain.com
    • Server Aliases: www.yourdomain.com
  4. Under Directory Options: Check FollowSymLinks and Indexes
  5. Under Access Control: Set Accessible to everyone
  6. Click Create Now

🔐 Step 4: Add SSL/HTTPS (Port 443)

  1. Click Create Virtual Host again
  2. Port: 443 (manual entry)
  3. Same Document Root, Server Name, Aliases as HTTP
  4. Scroll to SSL Options:
    • Enable SSL: Yes
    • Private key file: /etc/letsencrypt/live/yourdomain.com/privkey.pem
    • Certificate file: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    • CA file: /etc/letsencrypt/live/yourdomain.com/chain.pem
  5. Set SSL protocols: Reject SSLv2, SSLv3, TLSv1.0, TLSv1.1
  6. Click Create Now
  7. Click Apply Changes at top of Apache page

📝 Step 5: Get SSL Certificate (Let's Encrypt)

  1. In Webmin, go to Webmin → Webmin Configuration → SSL Encryption
  2. Scroll to Let's Encrypt section
  3. Enter your domain: yourdomain.com
  4. Enter contact email
  5. Click Request Certificate
This creates the certificate files needed in Step 3

🔄 SSL Auto-Renewal Commands

Test auto-renewal (dry run)
certbot renew --dry-run
Check crontab for auto-renewal
crontab -l | grep certbot
Add daily renewal cron (if missing)
(crontab -l 2>/dev/null; echo "0 0 * * * /usr/bin/certbot renew --quiet --post-hook 'systemctl reload apache2'") | crontab -
Check certificate expiry dates
certbot certificates
✅ With daily cron and post-hook, SSL certificates auto-renew without any manual intervention!

🎁 Bonus Commands

System info overview
htop && df -h && free -h && uptime
Check all listening ports
netstat -tulpn | grep LISTEN
Monitor logs in real-time
tail -f /var/log/syslog /var/log/apache2/error.log /var/log/mysql/error.log
Backup important configs
tar -czf backup-$(date +%Y%m%d).tar.gz /etc/nginx /etc/apache2 /etc/mysql /etc/wireguard /var/www