#!/usr/bin/env bash
# ==============================================================================
# NourishGlobal - VPS Subdomain Setup for https://food.jackpilot.co
# ==============================================================================
# Target OS: Ubuntu 20.04 / 22.04 / 24.04 or Debian 11 / 12
# Subdomain: food.jackpilot.co
#
# Run this script directly on your VPS as root:
# sudo bash setup-subdomain-vps.sh
# Or run it remotely from your local computer via SSH:
# ssh root@YOUR_VPS_IP "bash -s" < setup-subdomain-vps.sh
# ==============================================================================
set -euo pipefail
# Text formatting
BOLD="\033[1m"
GREEN="\033[0;32m"
BLUE="\033[0;34m"
YELLOW="\033[1;33m"
RED="\033[0;31m"
CYAN="\033[0;36m"
RESET="\033[0m"
SUBDOMAIN="food.jackpilot.co"
WEB_ROOT="/var/www/${SUBDOMAIN}"
SSL_EMAIL="mehedy870@gmail.com"
echo -e "${CYAN}${BOLD}"
echo "================================================================================"
echo " 🚀 Setting up VPS Subdomain: https://${SUBDOMAIN}"
echo "================================================================================"
echo -e "${RESET}"
# Require root
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}✘ Error: This script must be run as root or with sudo.${RESET}"
exit 1
fi
# 1. Update APT & Install Core Stacks
echo -e "${BLUE}[1/6] Updating APT repositories and installing Nginx + PHP-FPM + Certbot...${RESET}"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
# Install Nginx, PHP-FPM, core extensions, Certbot, and utilities
apt-get install -y \
nginx \
php-fpm \
php-cli \
php-curl \
php-json \
php-mbstring \
php-xml \
php-zip \
php-opcache \
certbot \
python3-certbot-nginx \
rsync \
curl \
tar \
unzip \
ufw \
ca-certificates
echo -e "${GREEN}✓ Core packages installed successfully.${RESET}"
# 2. Detect PHP-FPM Socket
echo ""
echo -e "${BLUE}[2/6] Detecting PHP-FPM version and UNIX socket...${RESET}"
PHP_SOCK=$(ls -1 /var/run/php/php*-fpm.sock 2>/dev/null | head -n 1 || true)
if [ -z "$PHP_SOCK" ]; then
# Start php-fpm if socket not found
systemctl start php*-fpm 2>/dev/null || true
PHP_SOCK=$(ls -1 /var/run/php/php*-fpm.sock 2>/dev/null | head -n 1 || true)
fi
if [ -z "$PHP_SOCK" ]; then
# Fallback to standard 8.2 or default socket
PHP_SOCK="/var/run/php/php8.2-fpm.sock"
fi
echo -e " → Detected PHP-FPM Socket: ${BOLD}${PHP_SOCK}${RESET}"
# 3. Create Web Root Directory
echo ""
echo -e "${BLUE}[3/6] Creating web root directory at ${WEB_ROOT}...${RESET}"
mkdir -p "${WEB_ROOT}"
mkdir -p "${WEB_ROOT}/data_storage"
# Create a temporary index file if folder is empty
if [ ! -f "${WEB_ROOT}/index.php" ]; then
cat << 'EOF' > "${WEB_ROOT}/index.php"
food.jackpilot.co Setup🎉 food.jackpilot.co is Ready!
Nginx and PHP-FPM are successfully provisioned.
Deploy your full application files using bash deploy.sh.
";
EOF
fi
# Set proper ownership and permissions
chown -R www-data:www-data "${WEB_ROOT}"
chmod -R 755 "${WEB_ROOT}"
chmod -R 775 "${WEB_ROOT}/data_storage"
echo -e "${GREEN}✓ Web root configured with www-data permissions.${RESET}"
# 4. Generate Nginx VirtualHost Configuration
echo ""
echo -e "${BLUE}[4/6] Generating Nginx VirtualHost for ${SUBDOMAIN}...${RESET}"
NGINX_CONF="/etc/nginx/sites-available/${SUBDOMAIN}"
cat << EOF > "${NGINX_CONF}"
server {
listen 80;
listen [::]:80;
server_name ${SUBDOMAIN};
root ${WEB_ROOT};
index index.php index.html index.htm;
# Performance & Upload limits
client_max_body_size 64M;
charset utf-8;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
# Security Headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Clean routing for Admin Panel
location = /admin {
try_files /admin.php /admin.php?\$query_string;
}
# Clean routing for REST API
location /api {
try_files /api.php /api.php?\$query_string;
}
# Main storefront routing
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
# PHP-FPM FastCGI Handler
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:${PHP_SOCK};
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 180;
}
# Static file asset caching
location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|css|js|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
try_files \$uri =404;
}
# Deny access to hidden files (.env, .git, etc.)
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Protect data storage files from direct HTTP browser execution
location ^~ /data_storage/ {
deny all;
}
access_log /var/log/nginx/${SUBDOMAIN}_access.log;
error_log /var/log/nginx/${SUBDOMAIN}_error.log;
}
EOF
# Enable the Nginx site
ln -sf "${NGINX_CONF}" "/etc/nginx/sites-enabled/${SUBDOMAIN}"
# Remove default site if present
rm -f /etc/nginx/sites-enabled/default
# Test Nginx syntax
nginx -t
systemctl reload nginx
echo -e "${GREEN}✓ Nginx configuration created and reloaded.${RESET}"
# 5. Configure Firewall (UFW)
echo ""
echo -e "${BLUE}[5/6] Configuring firewall rules (Ports 80, 443, 22)...${RESET}"
if command -v ufw >/dev/null 2>&1; then
ufw allow 'OpenSSH' >/dev/null 2>&1 || true
ufw allow 'Nginx Full' >/dev/null 2>&1 || true
echo -e "${GREEN}✓ Firewall ports 80 (HTTP), 443 (HTTPS), and SSH allowed.${RESET}"
fi
# 6. Request Let's Encrypt SSL Certificate
echo ""
echo -e "${BLUE}[6/6] Requesting automated Let's Encrypt SSL certificate for ${SUBDOMAIN}...${RESET}"
# Test if DNS points to this server
VPS_PUBLIC_IP=$(curl -s -4 ifconfig.me || curl -s -4 icanhazip.com || echo "UNKNOWN")
RESOLVED_IP=$(getent ahostsv4 "${SUBDOMAIN}" | head -n 1 | awk '{print $1}' || echo "UNRESOLVED")
echo -e " • VPS Public IP : ${BOLD}${VPS_PUBLIC_IP}${RESET}"
echo -e " • ${SUBDOMAIN} IP : ${BOLD}${RESOLVED_IP}${RESET}"
SSL_SUCCESS=false
if [ "$VPS_PUBLIC_IP" = "$RESOLVED_IP" ] && [ "$RESOLVED_IP" != "UNRESOLVED" ]; then
echo -e " → DNS is properly pointed! Executing Certbot..."
if certbot --nginx -d "${SUBDOMAIN}" --non-interactive --agree-tos -m "${SSL_EMAIL}" --redirect ; then
echo -e "${GREEN}✓ Free Let's Encrypt SSL certificate issued and HTTPS redirect enabled!${RESET}"
SSL_SUCCESS=true
fi
else
echo -e "${YELLOW} âš Notice: DNS for '${SUBDOMAIN}' does not point to this VPS yet.${RESET}"
echo -e " Current DNS resolves to: ${RESOLVED_IP}"
echo -e " This VPS Public IP is : ${VPS_PUBLIC_IP}"
echo -e " Certbot requires the DNS A record to match before issuing SSL."
fi
# Ensure services are enabled on boot
systemctl enable nginx
PHP_SVC=$(basename "$PHP_SOCK" .sock | sed 's/\.sock//')
systemctl enable "$PHP_SVC" 2>/dev/null || systemctl enable php-fpm 2>/dev/null || true
echo ""
echo -e "${GREEN}${BOLD}================================================================================"
echo " 🎉 Subdomain VPS Setup Completed for https://${SUBDOMAIN}"
echo "================================================================================"
echo -e "${RESET}"
echo -e " • Web Directory : ${BOLD}${WEB_ROOT}${RESET}"
echo -e " • Nginx Config : ${BOLD}${NGINX_CONF}${RESET}"
echo -e " • PHP-FPM Sock : ${BOLD}${PHP_SOCK}${RESET}"
if [ "$SSL_SUCCESS" = true ]; then
echo -e " • Status : ${GREEN}Active with HTTPS (SSL Enabled)${RESET}"
echo -e " • Live URL : ${CYAN}https://${SUBDOMAIN}/${RESET}"
else
echo -e " • Status : ${YELLOW}Active on HTTP. Awaiting DNS for HTTPS SSL.${RESET}"
echo -e " • Action Needed : Add an 'A' record in your DNS provider:"
echo -e " ${BOLD}Host: food | Points to: ${VPS_PUBLIC_IP}${RESET}"
echo -e " Then run this command to enable SSL:"
echo -e " ${BOLD}sudo certbot --nginx -d ${SUBDOMAIN} -m ${SSL_EMAIL} --agree-tos --redirect${RESET}"
fi
echo ""
echo -e "${CYAN}Next Step: Run 'bash deploy.sh' from your local workspace to copy all files.${RESET}"
echo ""