Private
Public Access
1
0

Add colored output and UX improvements to setup.sh

- Config option labels (domain, email, etc.) shown in bold blue
- Errors in red, warnings in yellow, success checkmarks in green
- Password field: note that input won't appear on screen
- SMTP prompt: "if you don't know what this is, press Enter to skip"
- Summary next steps: detailed A record fields (Type, Name, Value, TTL)
  with explanations, dig command with success/failure examples,
  "copy this command into the server terminal" instead of "run"
- Matching color scheme with install.sh (header, section, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
constantprojects
2026-02-24 08:59:14 -07:00
parent d76c572af8
commit a35569863e

154
setup.sh
View File

@@ -7,18 +7,28 @@ set -eo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR" cd "$SCRIPT_DIR"
echo "" # --- Colors and formatting ---
echo "═══════════════════════════════════════════════════════════" BOLD='\033[1m'
echo " WebsiteBox Setup Wizard" DIM='\033[2m'
echo "═══════════════════════════════════════════════════════════" RESET='\033[0m'
echo "" RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
ORANGE='\033[1;38;5;208m'
CYAN='\033[1;36m'
BLUE='\033[1;34m'
WHITE='\033[1;37m'
printf "\n${WHITE}═══════════════════════════════════════════════════════════${RESET}\n"
printf " ${BOLD}WebsiteBox Setup Wizard${RESET}\n"
printf "${WHITE}═══════════════════════════════════════════════════════════${RESET}\n\n"
# --- Prerequisite Checks --- # --- Prerequisite Checks ---
check_command() { check_command() {
if ! command -v "$1" &>/dev/null; then if ! command -v "$1" &>/dev/null; then
echo "ERROR: $1 is not installed." printf "${RED} $1 is not installed.${RESET}\n"
echo "$2" printf "${RED} $2${RESET}\n"
exit 1 exit 1
fi fi
} }
@@ -26,24 +36,24 @@ check_command() {
check_command docker "Install Docker: https://docs.docker.com/engine/install/" check_command docker "Install Docker: https://docs.docker.com/engine/install/"
if ! docker compose version &>/dev/null; then if ! docker compose version &>/dev/null; then
echo "ERROR: Docker Compose (v2) is not available." printf "${RED} Docker Compose (v2) is not available.${RESET}\n"
echo "Install it: https://docs.docker.com/compose/install/" printf "${RED} Install it: https://docs.docker.com/compose/install/${RESET}\n"
exit 1 exit 1
fi fi
# Check if Docker is accessible # Check if Docker is accessible
if ! docker info &>/dev/null; then if ! docker info &>/dev/null; then
echo "ERROR: Cannot connect to Docker daemon." printf "${RED} Cannot connect to Docker daemon.${RESET}\n"
echo "Make sure Docker is running and your user has permission." printf "${RED} Make sure Docker is running and your user has permission.${RESET}\n"
echo "You may need to: sudo usermod -aG docker \$USER && newgrp docker" printf "${RED} You may need to: sudo usermod -aG docker \$USER && newgrp docker${RESET}\n"
exit 1 exit 1
fi fi
# Check ports # Check ports
for port in 80 443; do for port in 80 443; do
if ss -tlnp 2>/dev/null | grep -q ":${port} " || netstat -tlnp 2>/dev/null | grep -q ":${port} "; then if ss -tlnp 2>/dev/null | grep -q ":${port} " || netstat -tlnp 2>/dev/null | grep -q ":${port} "; then
echo "WARNING: Port ${port} is already in use." printf "${YELLOW} Port ${port} is already in use.${RESET}\n"
echo "Another service may need to be stopped first." printf "${YELLOW} Another service may need to be stopped first.${RESET}\n"
read -rp "Continue anyway? (y/N) " cont read -rp "Continue anyway? (y/N) " cont
if [ "$cont" != "y" ] && [ "$cont" != "Y" ]; then if [ "$cont" != "y" ] && [ "$cont" != "Y" ]; then
exit 1 exit 1
@@ -64,31 +74,33 @@ generate_salt() {
# --- Collect Configuration --- # --- Collect Configuration ---
echo "Please provide the following configuration:" printf "Please provide the following configuration:\n\n"
echo ""
# Domain # Domain
while true; do while true; do
read -rp "Domain name (e.g., example.com): " DOMAIN printf "${BLUE}Domain name${RESET} (e.g., example.com): "
read -r DOMAIN
if [[ "$DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]{2,})+$ ]]; then if [[ "$DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]{2,})+$ ]]; then
break break
fi fi
echo "Invalid domain format. Please enter a valid domain (e.g., example.com)" printf "${RED} Invalid domain format. Please enter a valid domain (e.g., example.com)${RESET}\n"
done done
# Site title # Site title
read -rp "Site title [My Portfolio]: " SITE_TITLE printf "${BLUE}Site title${RESET} [My Portfolio]: "
read -r SITE_TITLE
SITE_TITLE="${SITE_TITLE:-My Portfolio}" SITE_TITLE="${SITE_TITLE:-My Portfolio}"
# Admin username # Admin username
while true; do while true; do
read -rp "WordPress admin username: " ADMIN_USER printf "${BLUE}WordPress admin username${RESET}: "
read -r ADMIN_USER
if [ -z "$ADMIN_USER" ]; then if [ -z "$ADMIN_USER" ]; then
echo "Username cannot be empty." printf "${RED} Username cannot be empty.${RESET}\n"
continue continue
fi fi
if [ "$ADMIN_USER" = "admin" ]; then if [ "$ADMIN_USER" = "admin" ]; then
echo "For security, please choose a username other than 'admin'." printf "${YELLOW} For security, please choose a username other than 'admin'.${RESET}\n"
continue continue
fi fi
break break
@@ -96,75 +108,88 @@ done
# Admin email # Admin email
while true; do while true; do
read -rp "Admin email (used for SSL & WordPress): " ADMIN_EMAIL printf "${BLUE}Admin email${RESET} (used for SSL & WordPress): "
read -r ADMIN_EMAIL
if [[ "$ADMIN_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then if [[ "$ADMIN_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
break break
fi fi
echo "Please enter a valid email address." printf "${RED} Please enter a valid email address.${RESET}\n"
done done
# Admin password # Admin password
echo "" echo ""
echo "Set your WordPress admin password." printf "${BLUE}Set your WordPress admin password.${RESET}\n"
echo "Press Enter to auto-generate a secure 20-character password." printf "${DIM} Press Enter to auto-generate a secure 20-character password.${RESET}\n"
printf "${DIM} Note: your password won't appear on screen as you type — that's normal.${RESET}\n"
while true; do while true; do
read -rsp "Admin password: " ADMIN_PASSWORD printf "${BLUE}Admin password${RESET}: "
read -rs ADMIN_PASSWORD
echo "" echo ""
if [ -z "$ADMIN_PASSWORD" ]; then if [ -z "$ADMIN_PASSWORD" ]; then
ADMIN_PASSWORD=$(generate_password 20) ADMIN_PASSWORD=$(generate_password 20)
PASSWORD_AUTO_GENERATED=true PASSWORD_AUTO_GENERATED=true
echo "Password auto-generated." printf "${GREEN}Password auto-generated.${RESET}\n"
break break
fi fi
if [ ${#ADMIN_PASSWORD} -lt 12 ]; then if [ ${#ADMIN_PASSWORD} -lt 12 ]; then
echo "Password must be at least 12 characters." printf "${RED} Password must be at least 12 characters.${RESET}\n"
continue continue
fi fi
read -rsp "Confirm password: " ADMIN_PASSWORD_CONFIRM printf "${BLUE}Confirm password${RESET}: "
read -rs ADMIN_PASSWORD_CONFIRM
echo "" echo ""
if [ "$ADMIN_PASSWORD" != "$ADMIN_PASSWORD_CONFIRM" ]; then if [ "$ADMIN_PASSWORD" != "$ADMIN_PASSWORD_CONFIRM" ]; then
echo "Passwords do not match. Try again." printf "${RED} Passwords do not match. Try again.${RESET}\n"
continue continue
fi fi
PASSWORD_AUTO_GENERATED=false PASSWORD_AUTO_GENERATED=false
printf "${GREEN} ✓ Password set.${RESET}\n"
break break
done done
# Age Gate # Age Gate
echo "" echo ""
read -rp "Enable age verification gate? (Y/n): " AGE_GATE_INPUT printf "${BLUE}Enable age verification gate?${RESET} (Y/n): "
read -r AGE_GATE_INPUT
if [ "$AGE_GATE_INPUT" = "n" ] || [ "$AGE_GATE_INPUT" = "N" ]; then if [ "$AGE_GATE_INPUT" = "n" ] || [ "$AGE_GATE_INPUT" = "N" ]; then
AGE_GATE_ENABLED=false AGE_GATE_ENABLED=false
AGE_GATE_MIN_AGE=18 AGE_GATE_MIN_AGE=18
else else
AGE_GATE_ENABLED=true AGE_GATE_ENABLED=true
read -rp "Minimum age (18-21) [18]: " AGE_GATE_MIN_AGE printf "${BLUE}Minimum age${RESET} (18-21) [18]: "
read -r AGE_GATE_MIN_AGE
AGE_GATE_MIN_AGE="${AGE_GATE_MIN_AGE:-18}" AGE_GATE_MIN_AGE="${AGE_GATE_MIN_AGE:-18}"
if [ "$AGE_GATE_MIN_AGE" -lt 18 ] 2>/dev/null || [ "$AGE_GATE_MIN_AGE" -gt 21 ] 2>/dev/null; then if [ "$AGE_GATE_MIN_AGE" -lt 18 ] 2>/dev/null || [ "$AGE_GATE_MIN_AGE" -gt 21 ] 2>/dev/null; then
echo "Invalid age. Using default: 18" printf "${YELLOW} Invalid age. Using default: 18${RESET}\n"
AGE_GATE_MIN_AGE=18 AGE_GATE_MIN_AGE=18
fi fi
fi fi
# SMTP (optional) # SMTP (optional)
echo "" echo ""
read -rp "SMTP server (optional, press Enter to skip): " SMTP_HOST printf "${BLUE}SMTP server${RESET} (if you don't know what this is, press Enter to skip): "
read -r SMTP_HOST
SMTP_PORT=587 SMTP_PORT=587
SMTP_USER="" SMTP_USER=""
SMTP_PASS="" SMTP_PASS=""
SMTP_FROM="" SMTP_FROM=""
if [ -n "$SMTP_HOST" ]; then if [ -n "$SMTP_HOST" ]; then
read -rp "SMTP port [587]: " SMTP_PORT_INPUT printf "${BLUE}SMTP port${RESET} [587]: "
read -r SMTP_PORT_INPUT
SMTP_PORT="${SMTP_PORT_INPUT:-587}" SMTP_PORT="${SMTP_PORT_INPUT:-587}"
read -rp "SMTP username: " SMTP_USER printf "${BLUE}SMTP username${RESET}: "
read -rsp "SMTP password: " SMTP_PASS read -r SMTP_USER
printf "${BLUE}SMTP password${RESET}: "
read -rs SMTP_PASS
echo "" echo ""
read -rp "SMTP from address [${ADMIN_EMAIL}]: " SMTP_FROM_INPUT printf "${BLUE}SMTP from address${RESET} [${ADMIN_EMAIL}]: "
read -r SMTP_FROM_INPUT
SMTP_FROM="${SMTP_FROM_INPUT:-$ADMIN_EMAIL}" SMTP_FROM="${SMTP_FROM_INPUT:-$ADMIN_EMAIL}"
fi fi
# Backup retention # Backup retention
read -rp "Days to keep local backups (1-365) [30]: " BACKUP_RETENTION_DAYS printf "${BLUE}Days to keep local backups${RESET} (1-365) [30]: "
read -r BACKUP_RETENTION_DAYS
BACKUP_RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-30}" BACKUP_RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-30}"
# --- Auto-generated Values --- # --- Auto-generated Values ---
@@ -246,29 +271,36 @@ SERVER_IP=$(curl -s -4 ifconfig.me 2>/dev/null || curl -s -4 icanhazip.com 2>/de
# --- Print Summary --- # --- Print Summary ---
echo "" printf "\n${WHITE}═══════════════════════════════════════════════════════════${RESET}\n"
echo "═══════════════════════════════════════════════════════════" printf " ${GREEN}${BOLD}WebsiteBox Setup Complete!${RESET}\n"
echo " WebsiteBox Setup Complete!" printf "${WHITE}═══════════════════════════════════════════════════════════${RESET}\n\n"
echo "═══════════════════════════════════════════════════════════" printf " ${GREEN}${RESET} Configuration saved to ${BOLD}.env${RESET}\n\n"
echo "" printf " ${BOLD}Next steps:${RESET}\n\n"
echo " Configuration saved to .env" printf " ${BLUE}1.${RESET} ${BOLD}Point your domain's A record to this server${RESET}\n"
echo "" printf " Log in to your domain registrar and add a DNS record:\n"
echo " Next steps:" printf " ${DIM}Type:${RESET} A\n"
echo " 1. Point your domain's A record to this server's IP: ${SERVER_IP}" printf " ${DIM}Name:${RESET} @ ${DIM}(this means the root domain, e.g., ${DOMAIN})${RESET}\n"
echo " 2. Wait for DNS propagation (check: dig ${DOMAIN})" printf " ${DIM}Value:${RESET} ${BOLD}${SERVER_IP}${RESET} ${DIM}(your server's IP address)${RESET}\n"
echo " 3. Run: docker compose up -d" printf " ${DIM}TTL:${RESET} Auto ${DIM}(or the lowest option available)${RESET}\n\n"
echo " 4. Access your site at: https://${DOMAIN}" printf " ${BLUE}2.${RESET} ${BOLD}Wait for DNS propagation, then verify it's working${RESET}\n"
echo " 5. Log in at: https://${DOMAIN}/wp-admin" printf " Copy this command into the server terminal:\n\n"
echo " Username: ${ADMIN_USER}" printf " ${CYAN}dig ${DOMAIN} +short${RESET}\n\n"
printf " ${GREEN}✓ Success looks like:${RESET} ${BOLD}${SERVER_IP}${RESET}\n"
printf " ${RED}✗ Not ready yet:${RESET} ${DIM}(blank output or a different IP — wait a few minutes and try again)${RESET}\n\n"
printf " ${BLUE}3.${RESET} ${BOLD}Launch your website${RESET}\n"
printf " Once DNS is working, copy this command into the server terminal:\n\n"
printf " ${CYAN}docker compose up -d${RESET}\n\n"
printf " ${BLUE}4.${RESET} ${BOLD}Visit your site${RESET}\n"
printf " Your website: ${CYAN}https://${DOMAIN}${RESET}\n"
printf " Admin login: ${CYAN}https://${DOMAIN}/wp-admin${RESET}\n"
printf " Username: ${BOLD}${ADMIN_USER}${RESET}\n"
if [ "$PASSWORD_AUTO_GENERATED" = true ]; then if [ "$PASSWORD_AUTO_GENERATED" = true ]; then
echo " Password: ${ADMIN_PASSWORD}" printf " Password: ${BOLD}${ADMIN_PASSWORD}${RESET}\n\n"
echo "" printf " ${YELLOW}${RESET} Your auto-generated password has also been saved to: ${BOLD}.credentials${RESET}\n"
echo " WARNING: Your auto-generated password has also been saved to: .credentials" printf " Delete this file after recording your password somewhere secure.\n"
echo " Delete this file after recording your password somewhere secure."
else else
echo " Password: ******* (the password you set during setup)" printf " Password: ${DIM}(the password you set during setup)${RESET}\n"
fi fi
echo "" printf "\n${WHITE}═══════════════════════════════════════════════════════════${RESET}\n"
echo "═══════════════════════════════════════════════════════════"