add interaction menu, add color format for more visual appeal, add stop / start functionalliity

This commit is contained in:
2025-01-30 13:43:03 +09:00
parent 730dbff3b3
commit d9fc07e386
5 changed files with 830 additions and 234 deletions
+1
View File
@@ -1,3 +1,4 @@
caddy/* caddy/*
wordpress/* wordpress/*
kazewp.log kazewp.log
backup/*
+19 -216
View File
@@ -1,9 +1,5 @@
#!/bin/bash #!/bin/bash
LOG_FILE="kazewp.log"
exec > >(tee -a "$LOG_FILE") 2>&1
echo -e "\n========== $(date '+%Y-%m-%d %H:%M:%S') =========="
# Get the directory where the script is located # Get the directory where the script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
@@ -15,6 +11,8 @@ source "${SCRIPT_DIR}/lib/validation.sh"
source "${SCRIPT_DIR}/lib/docker.sh" source "${SCRIPT_DIR}/lib/docker.sh"
source "${SCRIPT_DIR}/lib/caddy.sh" source "${SCRIPT_DIR}/lib/caddy.sh"
source "${SCRIPT_DIR}/lib/wordpress.sh" source "${SCRIPT_DIR}/lib/wordpress.sh"
source "${SCRIPT_DIR}/lib/menu.sh"
#source "${SCRIPT_DIR}/lib/log.sh"
# Check if Docker is installed # Check if Docker is installed
@@ -34,171 +32,6 @@ if ! systemctl is-active --quiet docker; then
sudo systemctl start docker sudo systemctl start docker
fi fi
# Function to install a new WordPress site
install_site() {
FIRST_TIME=false
if ! check_container_running "caddy"; then
FIRST_TIME=true
fi
setup_directories
DOMAIN="$1"
WP_PROJECT_DIR="${WORDPRESS_DIR}/${DOMAIN}"
if [ -d "$WP_PROJECT_DIR" ]; then
echo -e "${RED}Directory ${WP_PROJECT_DIR} already exists!${NC}"
exit 1
fi
while true; do
read -p "Enter admin email: " ADMIN_EMAIL
if validate_email "$ADMIN_EMAIL"; then
break
fi
done
read -p "Enter admin username: " ADMIN_USER
read -s -p "Enter password (press Enter for random password): " ADMIN_PASSWORD
echo
if [ -z "$ADMIN_PASSWORD" ]; then
ADMIN_PASSWORD=$(generate_password)
echo "Generated password: $ADMIN_PASSWORD"
fi
read -p "Enter site title: " SITE_TITLE
MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32)
MYSQL_PASSWORD=$(openssl rand -base64 32)
mkdir -p "$WP_PROJECT_DIR"
cd "$WP_PROJECT_DIR"
create_docker_compose "$DOMAIN" "$MYSQL_ROOT_PASSWORD" "$MYSQL_PASSWORD"
create_caddy_config "$DOMAIN"
create_wp_setup "$DOMAIN" "$ADMIN_USER" "$ADMIN_PASSWORD" "$ADMIN_EMAIL" "$SITE_TITLE"
create_env_file "$DOMAIN" "$ADMIN_USER" "$ADMIN_PASSWORD" "$ADMIN_EMAIL" "$MYSQL_ROOT_PASSWORD" "$MYSQL_PASSWORD"
while true; do
read -p "Do you want to (1) start services and set up WordPress automatically or (2) do it manually later? [1/2]: " SETUP_CHOICE
case $SETUP_CHOICE in
1)
if start_services "$FIRST_TIME" "$DOMAIN"; then
if run_wp_setup "$DOMAIN"; then
echo -e "${GREEN}Complete setup finished successfully!${NC}"
else
echo -e "${RED}WordPress setup failed. You may need to run setup manually later.${NC}"
fi
else
echo -e "${RED}Service startup failed. You may need to start services manually.${NC}"
fi
break
;;
2)
echo -e "\n${BLUE}Manual setup instructions:${NC}"
if [ "$FIRST_TIME" = true ]; then
echo "1. Start Caddy:"
echo " cd ${CADDY_DIR} && docker compose up -d"
fi
reload_caddy
echo "2. Start WordPress:"
echo " cd ${WP_PROJECT_DIR} && docker compose up -d"
echo "3. Run the WordPress setup script:"
echo " ./wp-setup.sh"
break
;;
*)
echo -e "${RED}Invalid choice. Please enter 1 or 2.${NC}"
;;
esac
done
echo -e "\n${BLUE}WordPress Site Information:${NC}"
echo "----------------------------------------"
echo "Domain: https://$DOMAIN"
echo "Admin URL: https://$DOMAIN/wp-admin"
echo "Username: $ADMIN_USER"
echo "Password: $ADMIN_PASSWORD (SAVE THIS PASSWORD!)"
echo "Email: $ADMIN_EMAIL"
echo "----------------------------------------"
save_credentials "$WP_PROJECT_DIR" "$DOMAIN" "$ADMIN_USER" "$ADMIN_PASSWORD" "$ADMIN_EMAIL"
echo -e "\nCredentials have been saved to: ${WP_PROJECT_DIR}/credentials.txt"
exit 0
}
# Function to list all installed WordPress sites
list_sites() {
if [ ! -d "$WORDPRESS_DIR" ]; then
echo "There are no websites setup yet!"
exit 1
fi
echo "Installed WordPress Sites:"
echo "-------------------------"
subfolders=($(find "$WORDPRESS_DIR" -mindepth 1 -maxdepth 1 -type d))
if [ ${#subfolders[@]} -eq 0 ]; then
echo "There are no websites setup yet!"
else
for site in "$WORDPRESS_DIR"/*; do
if [ -d "$site" ]; then
DOMAIN=$(basename "$site")
if [ -f "$site/compose.yaml" ]; then
echo "Site: $DOMAIN"
echo "Path: $site"
get_containers_status "$site/compose.yaml"
#echo "Status: $(docker compose -f $site/compose.yaml ps --status running | grep -v 'Name' | wc -l) containers running"
echo "-------------------------"
fi
fi
done
fi
}
# Function to delete a WordPress site
delete_site() {
DOMAIN="$1"
WP_PROJECT_DIR="${WORDPRESS_DIR}/${DOMAIN}"
#echo $DOMAIN
#echo $WP_PROJECT_DIR
if [ ! -d "$WP_PROJECT_DIR" ]; then
echo "Error: Site '$DOMAIN' not found"
return 1
fi
echo "Warning: This will permanently delete the site: $DOMAIN"
read -p "Are you sure you want to continue? (y/N): " confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
echo "Operation cancelled"
return 0
fi
echo "Stopping Docker containers..."
docker compose -f "$WP_PROJECT_DIR/compose.yaml" down
echo "Removing site directory..."
rm -rf "$WP_PROJECT_DIR"
echo "Removing Caddy configuration..."
rm -f "${CADDY_DIR}/sites/${DOMAIN}.caddy"
echo "Reloading Caddy..."
reload_caddy
echo "Site '$DOMAIN' has been successfully deleted"
}
# Main script # Main script
case "$1" in case "$1" in
"install") "install")
@@ -219,59 +52,29 @@ case "$1" in
;; ;;
"delete") "delete")
# Check if correct arguments are provided
if [ "$2" == "all" ]; then
# Ask for confirmation before proceeding with the uninstallation
read -p "Are you sure you want to uninstall everything? This will stop and remove all containers, and delete files. (Y/n): " confirm
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
# Stop all running containers
echo "Stopping all containers..."
find . -name 'compose.yaml' -execdir docker compose down \;
# Remove WordPress files
echo "Removing WordPress files..."
rm -rf wordpress
# Remove Caddy files
echo "Removing Caddy files..."
rm -rf caddy
# Remove log files
rm -rf kazewp.log
docker system prune -af
echo "Uninstallation complete."
else
echo "Uninstallation aborted."
fi
else
if [ -z "$2" ]; then if [ -z "$2" ]; then
echo "Error: Please provide a site name to delete or using all to delete everything" show_action_menu "delete"
#list_sites
while true; do
read -p "Enter domain (e.g., example.com): " DOMAIN
if validate_domain "$DOMAIN"; then
break
fi
done
delete_site "$DOMAIN"
else else
delete_site "$2" delete_sites "$2"
fi
fi fi
;;
"stop")
if [ -z "$2" ]; then
show_action_menu "stop"
else
stop_sites "$2"
fi
;;
"start")
if [ -z "$2" ]; then
show_action_menu "start"
else
start_sites "$2"
fi
;; ;;
*) *)
echo "KazeWP - WordPress Site Management Script" show_interactive_menu
echo "Usage:"
echo " $0 install <domain> - Install a new WordPress site"
echo " $0 list - List all installed WordPress sites"
echo " $0 delete <domain> - Delete a WordPress site"
echo " $0 delete all - Delete everything"
exit 1
;; ;;
esac esac
+116 -7
View File
@@ -1,13 +1,122 @@
if [ -t 1 ]; then #!/bin/bash
# Terminal supports colors
# Reset
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Regular Colors
BLACK='\033[0;30m'
RED='\033[0;31m' RED='\033[0;31m'
GREEN='\033[0;32m' GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m' BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[0;37m'
# Bold Colors
BBLACK='\033[1;30m'
BRED='\033[1;31m'
BGREEN='\033[1;32m'
BYELLOW='\033[1;33m'
BBLUE='\033[1;34m'
BPURPLE='\033[1;35m'
BCYAN='\033[1;36m'
BWHITE='\033[1;37m'
# Underline
UBLACK='\033[4;30m'
URED='\033[4;31m'
UGREEN='\033[4;32m'
UYELLOW='\033[4;33m'
UBLUE='\033[4;34m'
UPURPLE='\033[4;35m'
UCYAN='\033[4;36m'
UWHITE='\033[4;37m'
# Background Colors
BG_BLACK='\033[40m'
BG_RED='\033[41m'
BG_GREEN='\033[42m'
BG_YELLOW='\033[43m'
BG_BLUE='\033[44m'
BG_PURPLE='\033[45m'
BG_CYAN='\033[46m'
BG_WHITE='\033[47m'
# Styling Helper Functions
print_header() {
local text="$1"
local padding=2 # Padding on each side
local terminal_width=$(tput cols)
local text_length=${#text}
local total_padding=$(( (terminal_width - text_length - 2) / 2 ))
echo
printf "${BBLUE}%${terminal_width}s${NC}\n" | tr ' ' '='
printf "${BBLUE}|${NC}%${total_padding}s${BWHITE}%s${NC}%${total_padding}s${BBLUE}|${NC}\n" "" "$text" ""
printf "${BBLUE}%${terminal_width}s${NC}\n" | tr ' ' '='
}
print_subheader() {
local text="$1"
echo -e "\n${BCYAN}> ${text}${NC}"
echo -e "${CYAN}$(printf '%.s-' $(seq 1 $(tput cols)))${NC}"
}
print_menu_item() {
local number="$1"
local text="$2"
local status="${3:-}"
if [ -n "$status" ]; then
echo -e "${BWHITE}$number)${NC} $text ${status}"
else else
# Disable colors for non-terminal outputs (like logs) echo -e "${BWHITE}$number)${NC} $text"
NC=''
RED=''
GREEN=''
BLUE=''
fi fi
}
print_menu_action() {
local key="$1"
local text="$2"
echo -e "${BPURPLE}$key)${NC} $text"
}
print_success() {
echo -e "${BGREEN}${NC} $1"
}
print_error() {
echo -e "${BRED}${NC} $1"
}
print_warning() {
echo -e "${BYELLOW}! $1${NC}"
}
print_info() {
echo -e "${WHITE}$1${NC}"
}
print_separator() {
echo -e "${BLUE}$(printf '%.s-' $(seq 1 $(tput cols)))${NC}"
}
# Status Indicators with simple ASCII
status_running() {
echo -e "${BGREEN}[ RUNNING ]${NC}"
}
status_stopped() {
echo -e "${BRED}[ STOPPED ]${NC}"
}
status_partial() {
local running="$1"
local total="$2"
echo -e "${BYELLOW}[ PARTIAL: $running/$total ]${NC}"
}
status_loading() {
echo -e "${BCYAN}[ LOADING ]${NC}"
}
+34
View File
@@ -0,0 +1,34 @@
#!/bin/bash
# Get the directory of the main script that sources this file
MAIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LOG_FILE="$MAIN_DIR/kazewp.log"
# Create log file if it doesn't exist
touch "$LOG_FILE"
# Ensure log file is writable
if [ ! -w "$LOG_FILE" ]; then
echo "Error: Cannot write to log file $LOG_FILE"
exit 1
fi
# Function to add timestamp to log file
add_timestamp() {
echo -e "\n========== $(date '+%Y-%m-%d %H:%M:%S') ==========" >> "$LOG_FILE"
}
# Save original file descriptors
exec 3>&1
exec 4>&2
# Add timestamp to log file
add_timestamp
# Setup logging while preserving read -p functionality:
# Use process substitution for logging
exec 1> >(tee >(sed 's/\x1B\[[0-9;]*[JKmsu]//g' >> "$LOG_FILE"))
exec 2> >(tee >(sed 's/\x1B\[[0-9;]*[JKmsu]//g' >> "$LOG_FILE"))
# Restore original stdout for read commands
export BASH_READ_FD=3
+649
View File
@@ -0,0 +1,649 @@
#!/bin/bash
# lib/menu.sh
# Show the main interactive menu
show_interactive_menu() {
print_header "KazeWP - WordPress Site Management"
print_separator
print_subheader "Quick Usage:"
print_info " $0 list - List all installed WordPress sites"
print_info " $0 install <domain> - Install a new WordPress site"
print_info " $0 stop <domain> - Stop running WordPress sites"
print_info " $0 start <domain> - Start an installed WordPress sites"
print_info " $0 delete <domain> - Delete a WordPress site"
print_info " $0 delete all - Delete everything"
# First check if any sites exist
if [ ! -d "$WORDPRESS_DIR" ] || [ -z "$(ls -A "$WORDPRESS_DIR" 2>/dev/null)" ]; then
print_warning "No WordPress sites installed yet."
show_action_menu "brand-new"
return
fi
# Get and display existing sites
local -a sites=()
local i=1
print_subheader "Installed WordPress Sites"
while IFS= read -r site; do
if [ -f "$site/compose.yaml" ]; then
sites+=("$(basename "$site")")
domain=$(basename "$site")
status=$(get_site_status "$site/compose.yaml")
print_menu_item "$i" "$domain" "$status"
((i++))
fi
done < <(find "$WORDPRESS_DIR" -mindepth 1 -maxdepth 1 -type d | sort)
print_subheader "Available Actions"
echo -e "${BWHITE}Select an option:${NC}"
print_menu_action "n" "Install new WordPress site"
print_menu_action "m" "Manage multiple sites"
print_menu_action "q" "Quit"
print_separator
read -p "$(echo -e ${BCYAN}${NC}) " CHOICE
case $CHOICE in
"q"|"Q")
exit 0
;;
"n"|"N")
show_action_menu "new"
;;
"m"|"M")
show_multi_site_menu "${sites[@]}"
;;
*)
if [[ $CHOICE =~ ^[0-9]+$ ]] && [ "$CHOICE" -le "${#sites[@]}" ] && [ "$CHOICE" -gt 0 ]; then
show_single_site_menu "${sites[$CHOICE-1]}"
else
echo -e "${RED}Invalid selection. Please try again.${NC}"
show_interactive_menu
fi
;;
esac
}
# Show the menu for specific actions
show_action_menu() {
local action=$1
shift
local -a sites=("$@")
case $action in
"brand-new")
while true; do
read -p "Do you want to install new WordPress site now? (y/N): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
show_action_menu "new"
return
else
exit
fi
done
;;
"new")
while true; do
read -p "Enter domain for new WordPress site (or 'q' to quit): " domain
if [ "$domain" = "q" ]; then
show_interactive_menu
return
fi
if validate_domain "$domain"; then
install_site "$domain"
break
fi
done
;;
"delete")
echo -e "\n${YELLOW}Selected sites to delete:${NC}"
printf '%s\n' "${sites[@]}"
read -p "Are you sure you want to delete these sites? (y/N): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
for site in "${sites[@]}"; do
delete_sites "$site"
done
else
show_interactive_menu
fi
;;
"stop")
echo -e "\n${YELLOW}Stopping selected sites:${NC}"
printf '%s\n' "${sites[@]}"
for site in "${sites[@]}"; do
stop_sites "$site"
done
;;
"all")
echo -e "\n${BLUE}Available actions for all sites:${NC}"
echo "1) Stop all sites"
echo "2) Delete all sites"
echo "3) Back to main menu"
read -p "Enter your choice: " choice
case $choice in
1) stop_sites "all" ;;
2) delete_sites "all" ;;
3) show_interactive_menu ;;
*) echo -e "${RED}Invalid choice${NC}" ;;
esac
;;
esac
}
# Get the current status of a site
get_site_status() {
local compose_file=$1
local status=""
local running_count=0
local total_count=0
# Get the total number of containers defined in the compose file
total_count=$(docker compose -f "$compose_file" ps --quiet | wc -l)
# Get the number of running containers
running_count=$(docker compose -f "$compose_file" ps --status running --quiet | wc -l)
if [ $total_count -eq 0 ]; then
status="${YELLOW}[Not Started]${NC}"
elif [ $running_count -eq 0 ]; then
status="${RED}[Stopped]${NC}"
elif [ $running_count -eq $total_count ]; then
status="${GREEN}[Running]${NC}"
else
status="${YELLOW}[Partial: $running_count/$total_count]${NC}"
fi
echo -e "$status"
}
# Function to install a new WordPress site
install_site() {
FIRST_TIME=false
if ! check_container_running "caddy"; then
FIRST_TIME=true
fi
setup_directories
DOMAIN="$1"
WP_PROJECT_DIR="${WORDPRESS_DIR}/${DOMAIN}"
if [ -d "$WP_PROJECT_DIR" ]; then
print_error "${RED}Directory ${WP_PROJECT_DIR} already exists!${NC}"
exit 1
fi
while true; do
read -p "Enter admin email: " ADMIN_EMAIL
if validate_email "$ADMIN_EMAIL"; then
break
fi
done
read -p "Enter admin username: " ADMIN_USER
read -s -p "Enter password (press Enter for random password): " ADMIN_PASSWORD
echo
if [ -z "$ADMIN_PASSWORD" ]; then
ADMIN_PASSWORD=$(generate_password)
echo "Generated password: $ADMIN_PASSWORD"
fi
read -p "Enter site title: " SITE_TITLE
MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32)
MYSQL_PASSWORD=$(openssl rand -base64 32)
mkdir -p "$WP_PROJECT_DIR"
cd "$WP_PROJECT_DIR"
create_docker_compose "$DOMAIN" "$MYSQL_ROOT_PASSWORD" "$MYSQL_PASSWORD"
create_caddy_config "$DOMAIN"
create_wp_setup "$DOMAIN" "$ADMIN_USER" "$ADMIN_PASSWORD" "$ADMIN_EMAIL" "$SITE_TITLE"
create_env_file "$DOMAIN" "$ADMIN_USER" "$ADMIN_PASSWORD" "$ADMIN_EMAIL" "$MYSQL_ROOT_PASSWORD" "$MYSQL_PASSWORD"
while true; do
read -p "Do you want to (1) start services and set up WordPress automatically or (2) do it manually later? [1/2]: " SETUP_CHOICE
case $SETUP_CHOICE in
1)
if start_services "$FIRST_TIME" "$DOMAIN"; then
if run_wp_setup "$DOMAIN"; then
print_success "${GREEN}Complete setup finished successfully!${NC}"
else
print_error "${RED}WordPress setup failed. You may need to run setup manually later.${NC}"
fi
else
print_error "${RED}Service startup failed. You may need to start services manually.${NC}"
fi
break
;;
2)
print_info "\n${BLUE}Manual setup instructions:${NC}"
if [ "$FIRST_TIME" = true ]; then
print_info "1. Start Caddy:"
print_info " cd ${CADDY_DIR} && docker compose up -d"
fi
reload_caddy
print_info "2. Start WordPress:"
print_info " cd ${WP_PROJECT_DIR} && docker compose up -d"
print_info "3. Run the WordPress setup script:"
print_info " ./wp-setup.sh"
break
;;
*)
echo -e "${RED}Invalid choice. Please enter 1 or 2.${NC}"
;;
esac
done
echo -e "\n${BLUE}WordPress Site Information:${NC}"
echo "----------------------------------------"
echo "Domain: https://$DOMAIN"
echo "Admin URL: https://$DOMAIN/wp-admin"
echo "Username: $ADMIN_USER"
echo "Password: $ADMIN_PASSWORD (SAVE THIS PASSWORD!)"
echo "Email: $ADMIN_EMAIL"
echo "----------------------------------------"
save_credentials "$WP_PROJECT_DIR" "$DOMAIN" "$ADMIN_USER" "$ADMIN_PASSWORD" "$ADMIN_EMAIL"
echo -e "\nCredentials have been saved to: ${WP_PROJECT_DIR}/credentials.txt"
exit 0
}
# Function to list all installed WordPress sites
list_sites_sss() {
if [ ! -d "$WORDPRESS_DIR" ]; then
echo "There are no websites setup yet!"
exit 1
fi
echo "Installed WordPress Sites:"
echo "-------------------------"
subfolders=($(find "$WORDPRESS_DIR" -mindepth 1 -maxdepth 1 -type d))
if [ ${#subfolders[@]} -eq 0 ]; then
echo "There are no websites setup yet!"
else
for site in "$WORDPRESS_DIR"/*; do
if [ -d "$site" ]; then
DOMAIN=$(basename "$site")
if [ -f "$site/compose.yaml" ]; then
echo "Site: $DOMAIN"
echo "Path: $site"
get_containers_status "$site/compose.yaml"
#echo "Status: $(docker compose -f $site/compose.yaml ps --status running | grep -v 'Name' | wc -l) containers running"
echo "-------------------------"
fi
fi
done
fi
}
list_sites() {
print_subheader "Installed WordPress Sites"
while IFS= read -r site; do
if [ -f "$site/compose.yaml" ]; then
sites+=("$(basename "$site")")
domain=$(basename "$site")
status=$(get_site_status "$site/compose.yaml")
print_menu_item "$i" "$domain" "$status"
((i++))
fi
done < <(find "$WORDPRESS_DIR" -mindepth 1 -maxdepth 1 -type d | sort)
}
# Function to stop WordPress sites
stop_sites() {
local target="$1"
if [ ! -d "$WORDPRESS_DIR" ]; then
echo "No WordPress installations found!"
exit 1
fi
case "$target" in
"all")
echo "Stopping all WordPress containers..."
# Stop Caddy first
if [ -f "${CADDY_DIR}/compose.yaml" ]; then
echo "Stopping Caddy reverse proxy..."
docker compose -f "${CADDY_DIR}/compose.yaml" stop
fi
# Stop all WordPress installations
for site in "$WORDPRESS_DIR"/*; do
if [ -d "$site" ] && [ -f "$site/compose.yaml" ]; then
domain=$(basename "$site")
echo "Stopping site: $domain"
docker compose -f "$site/compose.yaml" stop
fi
done
echo "All containers have been stopped."
;;
*)
# Stop specific site
WP_PROJECT_DIR="${WORDPRESS_DIR}/${target}"
if [ ! -d "$WP_PROJECT_DIR" ] || [ ! -f "$WP_PROJECT_DIR/compose.yaml" ]; then
echo "Error: Site '$target' not found"
exit 1
fi
echo "Stopping site: $target"
docker compose -f "$WP_PROJECT_DIR/compose.yaml" stop
echo "Site containers have been stopped."
;;
esac
}
# Function to start WordPress sites
start_sites() {
local target="$1"
if [ ! -d "$WORDPRESS_DIR" ]; then
echo "No WordPress installations found!"
exit 1
fi
case "$target" in
"all")
echo "Starting all WordPress containers..."
# Start Caddy first
if [ -f "${CADDY_DIR}/compose.yaml" ]; then
echo "Starting Caddy reverse proxy..."
docker compose -f "${CADDY_DIR}/compose.yaml" up -d
fi
# Start all WordPress installations
for site in "$WORDPRESS_DIR"/*; do
if [ -d "$site" ] && [ -f "$site/compose.yaml" ]; then
domain=$(basename "$site")
echo "Starting site: $domain"
docker compose -f "$site/compose.yaml" up -d
fi
done
echo "All containers have been started."
;;
*)
# Start specific site
WP_PROJECT_DIR="${WORDPRESS_DIR}/${target}"
if [ ! -d "$WP_PROJECT_DIR" ] || [ ! -f "$WP_PROJECT_DIR/compose.yaml" ]; then
echo "Error: Site '$target' not found"
exit 1
fi
echo "Starting site: $target"
docker compose -f "$WP_PROJECT_DIR/compose.yaml" up -d
echo "Site containers have been started."
;;
esac
}
# Function to delete a WordPress site
delete_sites() {
DOMAIN="$1"
WP_PROJECT_DIR="${WORDPRESS_DIR}/${DOMAIN}"
case "$DOMAIN" in
"all")
read -p "Are you sure you want to uninstall everything? This will stop and remove all containers, and delete files. (Y/n): " confirm
if [[ "$confirm" == "y" || "$confirm" == "Y" ]]; then
# Stop all running containers
echo "Stopping all containers..."
find . -name 'compose.yaml' -execdir docker compose down \;
# Remove WordPress files
echo "Removing WordPress files..."
rm -rf wordpress
# Remove Caddy files
echo "Removing Caddy files..."
rm -rf caddy
# Remove log files
rm -rf kazewp.log
docker system prune -af
echo "Uninstallation complete."
else
echo "Uninstallation aborted."
fi
;;
*)
if [ ! -d "$WP_PROJECT_DIR" ]; then
echo "Error: Site '$DOMAIN' not found"
return 1
else
echo "Warning: This will permanently delete the site: $DOMAIN"
read -p "Are you sure you want to continue? (y/N): " confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
echo "Operation cancelled"
return 0
fi
echo "Stopping Docker containers..."
docker compose -f "$WP_PROJECT_DIR/compose.yaml" down
echo "Removing site directory..."
rm -rf "$WP_PROJECT_DIR"
echo "Removing Caddy configuration..."
rm -f "${CADDY_DIR}/sites/${DOMAIN}.caddy"
echo "Reloading Caddy..."
reload_caddy
echo "Site '$DOMAIN' has been successfully deleted"
fi
;;
esac
}
show_single_site_menu() {
local domain=$1
local compose_file="${WORDPRESS_DIR}/${domain}/compose.yaml"
local status=$(get_site_status "$compose_file")
while true; do
print_header "Site Management"
print_info "Managing site: ${BGREEN}${domain}${NC} ${status}"
print_separator
print_menu_item "1" "Start site"
print_menu_item "2" "Stop site"
print_menu_item "3" "Restart site"
print_menu_item "4" "View site details"
print_menu_item "5" "Delete site"
print_menu_action "b" "Back to main menu"
print_menu_action "q" "Quit"
print_separator
read -p "$(echo -e ${BCYAN}${NC}) " action
case $action in
1)
start_sites "$domain"
status=$(get_site_status "$compose_file")
;;
2)
stop_sites "$domain"
status=$(get_site_status "$compose_file")
;;
3)
restart_sites "$domain"
status=$(get_site_status "$compose_file")
;;
4)
show_site_details "$domain"
read -p "Press Enter to continue..."
;;
5)
delete_sites "$domain"
show_interactive_menu
return
;;
"b"|"B")
show_interactive_menu
return
;;
"q"|"Q")
exit 0
;;
*)
echo -e "${RED}Invalid choice${NC}"
;;
esac
done
}
show_multi_site_menu() {
local -a sites=("$@")
print_header "Site Management"
print_separator
echo "Select sites (e.g., 1,3,5 or 1-4 or all):"
local i=1
for domain in "${sites[@]}"; do
status=$(get_site_status "${WORDPRESS_DIR}/${domain}/compose.yaml")
echo -e "$i) $domain ${status}"
((i++))
done
echo "----------------------------------------"
read -p "Enter site selection (or 'b' for back): " selection
[ "$selection" = "b" ] && show_interactive_menu && return
if [ "$selection" = "all" ]; then
selected_sites=("${sites[@]}")
else
# Convert selection to array of sites
local -a selected_sites=()
IFS=',' read -ra NUMS <<< "$selection"
for num in "${NUMS[@]}"; do
if [[ $num =~ ^[0-9]+-[0-9]+$ ]]; then
# Handle range (e.g., "1-3")
start="${num%-*}"
end="${num#*-}"
for ((i=start; i<=end; i++)); do
if [ $i -le ${#sites[@]} ]; then
selected_sites+=("${sites[$i-1]}")
fi
done
elif [[ $num =~ ^[0-9]+$ ]] && [ "$num" -le "${#sites[@]}" ]; then
selected_sites+=("${sites[$num-1]}")
fi
done
fi
if [ ${#selected_sites[@]} -eq 0 ]; then
echo -e "${RED}No valid sites selected${NC}"
sleep 2
show_multi_site_menu "${sites[@]}"
return
fi
show_bulk_action_menu "${selected_sites[@]}"
}
show_bulk_action_menu() {
local -a sites=("$@")
echo -e "\n${BLUE}Bulk Actions for Selected Sites:${NC}"
echo "Selected sites: ${sites[*]}"
echo "----------------------------------------"
echo "1) Start sites"
echo "2) Stop sites"
echo "3) Restart sites"
echo "4) Delete sites"
echo "b) Back to site selection"
echo "q) Quit"
echo "----------------------------------------"
read -p "Enter your choice: " action
case $action in
1)
for site in "${sites[@]}"; do
start_sites "$site"
done
;;
2)
for site in "${sites[@]}"; do
stop_sites "$site"
done
;;
3)
for site in "${sites[@]}"; do
restart_sites "$site"
done
;;
4)
echo -e "${YELLOW}Are you sure you want to delete these sites?${NC}"
printf '%s\n' "${sites[@]}"
read -p "Confirm deletion (y/N): " confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
for site in "${sites[@]}"; do
delete_sites "$site"
done
fi
show_interactive_menu
return
;;
"b"|"B")
show_multi_site_menu "${sites[@]}"
return
;;
"q"|"Q")
exit 0
;;
*)
echo -e "${RED}Invalid choice${NC}"
sleep 2
show_bulk_action_menu "${sites[@]}"
;;
esac
show_multi_site_menu "${sites[@]}"
}
show_site_details() {
local domain=$1
local compose_file="${WORDPRESS_DIR}/${domain}/compose.yaml"
echo -e "\n${BLUE}Site Details for ${GREEN}${domain}${NC}"
echo "----------------------------------------"
echo -e "Status: $(get_site_status "$compose_file")"
echo "Installation Directory: ${WORDPRESS_DIR}/${domain}"
echo -e "\nContainer Status:"
docker compose -f "$compose_file" ps
#echo -e "\nContainer Logs (last 5 lines):"
#docker compose -f "$compose_file" logs --tail=5
}
restart_sites() {
local domain=$1
echo -e "${YELLOW}Restarting site: ${domain}${NC}"
docker compose -f "${WORDPRESS_DIR}/${domain}/compose.yaml" restart
}