Initial System Update

Update package list & upgrade
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.
Add PHP repository
add-apt-repository ppa:ondrej/php -y && apt update
Install PHP 8.3 + Apache module + extensions
apt install -y php8.3 libapache2-mod-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
Enable PHP in Apache
a2enmod php8.3 && systemctl restart apache2
Verify PHP version
php -v

UFW Firewall

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

Port Summary

PortProtocolService
22TCPSSH
80TCPHTTP
443TCPHTTPS
10000TCPWebmin
1198UDPWireGuard
Check UFW status
ufw status verbose

WireGuard VPN (Port 1198)

Ensure UDP port 1198 is open in your firewall & VPS panel!
Install WireGuard
apt install -y wireguard wireguard-tools
Generate server 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 server config (listen 1198)
cat > /etc/wireguard/wg0.conf << EOF [Interface] Address = 10.0.0.1/24 ListenPort = 1198 PrivateKey = $(cat /etc/wireguard/server_private.key) EOF
Enable php write and read Wireguard config
chown -R root:www-data /etc/wireguard && chmod -R 770 /etc/wireguard
Start & enable WireGuard
systemctl enable wg-quick@wg0 && systemctl start wg-quick@wg0
Check status
wg show

MySQL Installation

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

phpMyAdmin

Install phpMyAdmin
apt install -y phpmyadmin
Link to web root (Apache)
ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin && systemctl restart apache2

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
Enable & restart Webmin
systemctl enable webmin && systemctl restart webmin

Root User Creation

Replace 'admin' with your desired username.
Create user
adduser admin
Add to sudo group
usermod -aG sudo admin
Give full sudo privileges (no password)
echo "admin ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/admin

SSL / Let's Encrypt (Certbot)

Requires a valid domain name pointing to your server IP.
Install Certbot (official method)
sudo apt update sudo apt install certbot python3-certbot-apache
Obtain certificate (Apache plugin)
certbot --apache -d yourdomain.com -d www.yourdomain.com
Test auto-renewal (dry run)
certbot renew --dry-run
Add daily renewal cron (with Apache reload)
(crontab -l 2>/dev/null; echo "0 0 * * * /usr/bin/certbot renew --quiet --post-hook 'systemctl reload apache2'") | crontab -
Check certificate expiry
certbot certificates
With daily cron and post-hook, SSL certificates auto-renew without manual intervention.

Webmin GUI: Add Domain & SSL

Access Webmin

https://your-server-ip:10000 — login with root or your new user.

Create Website Directory

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

Add Virtual Host (HTTP port 80)

  1. Servers → Apache Webserver → Create Virtual Host
  2. Port: 80
  3. Document Root: /var/www/yourdomain.com
  4. Server Name: yourdomain.com
  5. Server Aliases: www.yourdomain.com
  6. Under Directory Options: check FollowSymLinks and Indexes
  7. Under Access Control: set Accessible to everyone
  8. Click Create Now

Add HTTPS (port 443) after SSL certificate exists

  1. Click Create Virtual Host again
  2. Port: 443
  3. Same Document Root, Server Name, Aliases
  4. Scroll to SSL Options:
    • Enable SSL: Yes
    • Private key: /etc/letsencrypt/live/yourdomain.com/privkey.pem
    • Certificate: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    • CA file: /etc/letsencrypt/live/yourdomain.com/chain.pem
  5. Reject SSLv2, SSLv3, TLSv1.0, TLSv1.1
  6. Click Create Now then Apply Changes

Bonus Commands

System overview
htop && df -h && free -h && uptime
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 2>/dev/null || true