Guide to Setting Up LEMP on a Bare Metal VPS

Here's a dynamic version of the Bash script that will interactively prompt you to set up multiple WordPress websites on your LEMP bare-metal VPS.

Script: dynamic-wordpress-setup.sh

#!/bin/bash

echo "๐Ÿ”ง WordPress Multi-Site Setup on LEMP Stack"
echo "==========================================="

read -p "๐Ÿ“Œ How many WordPress sites do you want to set up? " SITE_COUNT

# Install LEMP Stack (once)
echo "๐Ÿ”„ Installing NGINX, MySQL, PHP..."
apt update && apt upgrade -y
apt install -y nginx mysql-server php-fpm php-mysql php-cli php-curl php-gd php-mbstring php-xml php-zip unzip curl wget certbot python3-certbot-nginx

# Secure MySQL (minimal)
echo "๐Ÿ”’ Securing MySQL..."
mysql_secure_installation <<EOF

y
rootpass
rootpass
y
y
y
y
EOF

PHP_VERSION="8.2"
WEB_ROOT="/var/www"
WP_URL="https://wordpress.org/latest.tar.gz"

# Download WordPress once
wget -q ${WP_URL} -O /tmp/wordpress.tar.gz
tar -xzf /tmp/wordpress.tar.gz -C /tmp/

# Loop through site setup
for (( i=1; i<=SITE_COUNT; i++ ))
do
    echo ""
    echo "๐Ÿ”ง Configuring site #$i"

    read -p "Domain (e.g., example.com): " DOMAIN
    read -p "MySQL Database Name: " DB_NAME
    read -p "MySQL User: " DB_USER
    read -s -p "MySQL Password: " DB_PASS
    echo ""

    SITE_DIR=${WEB_ROOT}/${DOMAIN}

    # Create DB
    mysql -u root <<EOF
CREATE DATABASE ${DB_NAME};
CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
FLUSH PRIVILEGES;
EOF

    # Setup WordPress Files
    mkdir -p ${SITE_DIR}
    cp -r /tmp/wordpress/* ${SITE_DIR}
    cp ${SITE_DIR}/wp-config-sample.php ${SITE_DIR}/wp-config.php

    sed -i "s/database_name_here/${DB_NAME}/" ${SITE_DIR}/wp-config.php
    sed -i "s/username_here/${DB_USER}/" ${SITE_DIR}/wp-config.php
    sed -i "s/password_here/${DB_PASS}/" ${SITE_DIR}/wp-config.php

    chown -R www-data:www-data ${SITE_DIR}

    # NGINX Config
    NGINX_CONF="/etc/nginx/sites-available/${DOMAIN}"
    cat > ${NGINX_CONF} <<EOF
server {
    listen 80;
    server_name ${DOMAIN} www.${DOMAIN};

    root ${SITE_DIR};
    index index.php index.html;

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

    location ~ \.php\$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php${PHP_VERSION}-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}
EOF

    ln -s ${NGINX_CONF} /etc/nginx/sites-enabled/

    echo "โœ… ${DOMAIN} configured and enabled in NGINX."
done

# Finalize NGINX
echo "๐Ÿ” Reloading NGINX..."
nginx -t && systemctl reload nginx

# SSL
for (( i=1; i<=SITE_COUNT; i++ ))
do
    read -p "๐Ÿ” Enter domain #$i again for SSL (or leave blank to skip): " SSL_DOMAIN
    if [ ! -z "$SSL_DOMAIN" ]; then
        certbot --nginx -d ${SSL_DOMAIN} -d www.${SSL_DOMAIN} --non-interactive --agree-tos -m admin@${SSL_DOMAIN}
    fi
done

echo "๐Ÿš€ Setup complete! Visit each domain in your browser to finish WordPress installation."

How to Use

  1. Save the Script:

     nano dynamic-wordpress-setup.sh
    

    Paste the script above and save with CTRL+O, Enter, then CTRL+X.

  2. Make it Executable:

     chmod +x dynamic-wordpress-setup.sh
    
  3. Run the Script:

     sudo ./dynamic-wordpress-setup.sh
    

Example Interaction

๐Ÿ“Œ How many WordPress sites do you want to set up? 2

๐Ÿ”ง Configuring site #1
Domain (e.g., example.com): site1.com
MySQL Database Name: site1_db
MySQL User: site1_user
MySQL Password: ********

๐Ÿ”ง Configuring site #2
Domain (e.g., example.com): site2.com
MySQL Database Name: site2_db
MySQL User: site2_user
MySQL Password: ********

๐Ÿ” Enter domain #1 again for SSL: site1.com
๐Ÿ” Enter domain #2 again for SSL: site2.com

What It Handles

  • Fully automated LEMP stack installation

  • Dynamic input for unlimited domains

  • Individual WordPress + database setup

  • NGINX site configs

  • Let's Encrypt SSL

0
Subscribe to my newsletter

Read articles from LingarajTechhub All About Programming directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

LingarajTechhub All About Programming
LingarajTechhub All About Programming

Corporate Software Development Trainer with a demonstrated track record of success in the IT and Ed-tech industries for product development. I started my career as a software developer and have since taught C, C++, Java, and Python to hundreds of IT enthusiasts, including corporate professionals, throughout the years. I have been developing software for over 12 years.