Add colored output to install.sh, update all URLs to Gitea
Color system: green checkmarks for success, orange bold for info/hints, cyan section headers, bold white title headers, yellow warnings, red errors. Rolling progress preview lines shown in dim. UFW "Rules updated" noise suppressed. Updated all repository URLs from github.com/websitebox/websitebox to git.constantprojects.xyz/tankadmin/websitebox across install.sh, guide.md, and README.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
125
install.sh
125
install.sh
@@ -5,6 +5,25 @@ set -eo pipefail
|
||||
# Bootstrap script: installs Docker, clones repo, runs setup wizard
|
||||
# Usage: curl -fsSL <url>/install.sh | bash
|
||||
|
||||
# --- Colors and formatting ---
|
||||
BOLD='\033[1m'
|
||||
DIM='\033[2m'
|
||||
RESET='\033[0m'
|
||||
RED='\033[1;31m'
|
||||
GREEN='\033[1;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
ORANGE='\033[1;38;5;208m'
|
||||
CYAN='\033[1;36m'
|
||||
WHITE='\033[1;37m'
|
||||
|
||||
header() { printf "\n${WHITE}═══════════════════════════════════════════════════════════${RESET}\n ${BOLD}%s${RESET}\n${WHITE}═══════════════════════════════════════════════════════════${RESET}\n\n" "$1"; }
|
||||
section() { printf "\n${CYAN}───────────────────────────────────────────────────────────${RESET}\n ${BOLD}%s${RESET}\n${CYAN}───────────────────────────────────────────────────────────${RESET}\n" "$1"; }
|
||||
step() { printf "${GREEN}▸${RESET} ${BOLD}%s${RESET}\n" "$1"; }
|
||||
info() { printf "${ORANGE} %s${RESET}\n" "$1"; }
|
||||
ok() { printf "${GREEN} ✓ %s${RESET}\n" "$1"; }
|
||||
warn() { printf "${YELLOW} ⚠ %s${RESET}\n" "$1"; }
|
||||
err() { printf "${RED} ✗ %s${RESET}\n" "$1"; }
|
||||
|
||||
# --- Rolling preview helper ---
|
||||
# Shows last 4 lines of output in-place, then clears when done.
|
||||
# Keeps the terminal clean while still showing live progress.
|
||||
@@ -20,7 +39,7 @@ show_progress() {
|
||||
printf '\033[%dA' "${#buffer[@]}" 2>/dev/null || true
|
||||
fi
|
||||
for l in "${buffer[@]}"; do
|
||||
printf '\033[2K %.60s\n' "$l"
|
||||
printf "\033[2K${DIM} %.60s${RESET}\n" "$l"
|
||||
done
|
||||
done
|
||||
# clear preview lines when done
|
||||
@@ -31,11 +50,7 @@ show_progress() {
|
||||
fi
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════"
|
||||
echo " WebsiteBox Installer"
|
||||
echo "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
header "WebsiteBox Installer"
|
||||
|
||||
# --- Check for root/sudo ---
|
||||
|
||||
@@ -44,7 +59,7 @@ if [ "$(id -u)" -eq 0 ]; then
|
||||
ACTUAL_USER="${SUDO_USER:-root}"
|
||||
else
|
||||
if ! command -v sudo &>/dev/null; then
|
||||
echo "ERROR: This script requires root or sudo access."
|
||||
err "This script requires root or sudo access."
|
||||
exit 1
|
||||
fi
|
||||
SUDO="sudo"
|
||||
@@ -59,27 +74,27 @@ if [ -f /etc/os-release ]; then
|
||||
OS_ID="$ID"
|
||||
OS_VERSION="$VERSION_ID"
|
||||
else
|
||||
echo "ERROR: Cannot detect OS. /etc/os-release not found."
|
||||
echo "WebsiteBox supports Ubuntu 20.04+ and Debian 11+."
|
||||
err "Cannot detect OS. /etc/os-release not found."
|
||||
err "WebsiteBox supports Ubuntu 20.04+ and Debian 11+."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$OS_ID" in
|
||||
ubuntu)
|
||||
if [ "${OS_VERSION%%.*}" -lt 20 ]; then
|
||||
echo "ERROR: Ubuntu 20.04 or later is required (detected: ${OS_VERSION})."
|
||||
err "Ubuntu 20.04 or later is required (detected: ${OS_VERSION})."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
debian)
|
||||
if [ "${OS_VERSION%%.*}" -lt 11 ]; then
|
||||
echo "ERROR: Debian 11 or later is required (detected: ${OS_VERSION})."
|
||||
err "Debian 11 or later is required (detected: ${OS_VERSION})."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "WARNING: Unsupported OS detected (${OS_ID} ${OS_VERSION})."
|
||||
echo "WebsiteBox is tested on Ubuntu 20.04+ and Debian 11+."
|
||||
warn "Unsupported OS detected (${OS_ID} ${OS_VERSION})."
|
||||
warn "WebsiteBox is tested on Ubuntu 20.04+ and Debian 11+."
|
||||
read -rp "Continue anyway? (y/N) " cont
|
||||
if [ "$cont" != "y" ] && [ "$cont" != "Y" ]; then
|
||||
exit 1
|
||||
@@ -87,48 +102,43 @@ case "$OS_ID" in
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Detected: ${OS_ID} ${OS_VERSION}"
|
||||
ok "Detected: ${OS_ID} ${OS_VERSION}"
|
||||
|
||||
# --- Secure the Server ---
|
||||
|
||||
echo ""
|
||||
echo "───────────────────────────────────────────────────────────"
|
||||
echo " Securing your server..."
|
||||
echo "───────────────────────────────────────────────────────────"
|
||||
section "Securing your server"
|
||||
|
||||
# Update system packages
|
||||
echo "Updating system packages..."
|
||||
echo " Downloading the latest security patches for your operating system."
|
||||
echo " On a fresh server this can take 2-10 minutes. Sit tight."
|
||||
step "Updating system packages..."
|
||||
info "Downloading the latest security patches for your operating system."
|
||||
info "On a fresh server this can take 2-10 minutes. Sit tight."
|
||||
$SUDO apt-get update -qq
|
||||
DEBIAN_FRONTEND=noninteractive $SUDO apt-get upgrade -y -o Dpkg::Options::="--force-confold" 2>&1 | show_progress
|
||||
echo "System packages updated."
|
||||
ok "System packages updated."
|
||||
|
||||
# Install firewall, fail2ban, and automatic updates
|
||||
echo "Installing security tools (firewall, fail2ban, auto-updates)..."
|
||||
echo " These protect your server from common attacks. Usually under a minute."
|
||||
step "Installing security tools (firewall, fail2ban, auto-updates)..."
|
||||
info "These protect your server from common attacks. Usually under a minute."
|
||||
DEBIAN_FRONTEND=noninteractive $SUDO apt-get install -y ufw fail2ban unattended-upgrades 2>&1 | show_progress
|
||||
|
||||
# Configure firewall — allow SSH first to avoid lockout
|
||||
if ! $SUDO ufw status | grep -q "Status: active"; then
|
||||
echo "Configuring firewall..."
|
||||
$SUDO ufw allow OpenSSH
|
||||
$SUDO ufw allow 80/tcp
|
||||
$SUDO ufw allow 443/tcp
|
||||
$SUDO ufw --force enable
|
||||
echo "Firewall enabled: SSH, HTTP, and HTTPS allowed. All other ports blocked."
|
||||
step "Configuring firewall..."
|
||||
$SUDO ufw allow OpenSSH > /dev/null 2>&1
|
||||
$SUDO ufw allow 80/tcp > /dev/null 2>&1
|
||||
$SUDO ufw allow 443/tcp > /dev/null 2>&1
|
||||
$SUDO ufw --force enable > /dev/null 2>&1
|
||||
ok "Firewall enabled: SSH, HTTP, and HTTPS allowed. All other ports blocked."
|
||||
else
|
||||
# Firewall already active — just make sure our ports are open
|
||||
$SUDO ufw allow OpenSSH 2>/dev/null || true
|
||||
$SUDO ufw allow 80/tcp 2>/dev/null || true
|
||||
$SUDO ufw allow 443/tcp 2>/dev/null || true
|
||||
echo "Firewall already active. Verified SSH, HTTP, and HTTPS are allowed."
|
||||
ok "Firewall already active. Verified SSH, HTTP, and HTTPS are allowed."
|
||||
fi
|
||||
|
||||
# Enable fail2ban
|
||||
$SUDO systemctl enable fail2ban --quiet 2>/dev/null || true
|
||||
$SUDO systemctl start fail2ban 2>/dev/null || true
|
||||
echo "Fail2ban enabled: brute-force SSH protection active."
|
||||
ok "Fail2ban enabled: brute-force SSH protection active."
|
||||
|
||||
# Enable automatic security updates (non-interactive)
|
||||
echo 'Unattended-Upgrade::Allowed-Origins {
|
||||
@@ -143,7 +153,7 @@ Unattended-Upgrade::Remove-Unused-Dependencies "true";' | $SUDO tee /etc/apt/apt
|
||||
|
||||
echo 'APT::Periodic::Update-Package-Lists "1";
|
||||
APT::Periodic::Unattended-Upgrade "1";' | $SUDO tee /etc/apt/apt.conf.d/20auto-upgrades > /dev/null
|
||||
echo "Automatic security updates enabled."
|
||||
ok "Automatic security updates enabled."
|
||||
|
||||
# Configure Docker log rotation (create config before Docker install)
|
||||
$SUDO mkdir -p /etc/docker
|
||||
@@ -155,33 +165,32 @@ if [ ! -f /etc/docker/daemon.json ]; then
|
||||
"max-file": "3"
|
||||
}
|
||||
}' | $SUDO tee /etc/docker/daemon.json > /dev/null
|
||||
echo "Docker log rotation configured (10MB max per log, 3 files per container)."
|
||||
ok "Docker log rotation configured (10MB max per log, 3 files per container)."
|
||||
else
|
||||
echo "Docker daemon.json already exists. Skipping log rotation config."
|
||||
ok "Docker daemon.json already exists. Skipping log rotation config."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Server secured:"
|
||||
echo " Firewall: active (SSH, HTTP, HTTPS only)"
|
||||
echo " Fail2ban: active (SSH brute-force protection)"
|
||||
echo " Auto-updates: enabled (daily security patches)"
|
||||
echo " Docker log limits: configured (30MB max per container)"
|
||||
echo ""
|
||||
printf "\n${GREEN} Server secured:${RESET}\n"
|
||||
printf " ${BOLD}Firewall:${RESET} active (SSH, HTTP, HTTPS only)\n"
|
||||
printf " ${BOLD}Fail2ban:${RESET} active (SSH brute-force protection)\n"
|
||||
printf " ${BOLD}Auto-updates:${RESET} enabled (daily security patches)\n"
|
||||
printf " ${BOLD}Docker log limits:${RESET} configured (30MB max per container)\n\n"
|
||||
|
||||
# --- Install Docker if needed ---
|
||||
|
||||
DOCKER_JUST_INSTALLED=false
|
||||
|
||||
if command -v docker &>/dev/null; then
|
||||
echo "Docker is already installed."
|
||||
ok "Docker is already installed."
|
||||
# Restart to pick up daemon.json if it was just created
|
||||
if [ -f /etc/docker/daemon.json ]; then
|
||||
$SUDO systemctl restart docker 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
echo "Installing Docker..."
|
||||
echo " Docker packages and runs your website in isolated containers."
|
||||
echo " This is the largest download — usually takes 1-3 minutes."
|
||||
section "Installing Docker"
|
||||
step "Installing Docker..."
|
||||
info "Docker packages and runs your website in isolated containers."
|
||||
info "This is the largest download — usually takes 1-3 minutes."
|
||||
|
||||
# Install prerequisites
|
||||
$SUDO apt-get update -qq
|
||||
@@ -206,14 +215,14 @@ else
|
||||
if [ "$ACTUAL_USER" != "root" ]; then
|
||||
$SUDO usermod -aG docker "$ACTUAL_USER"
|
||||
DOCKER_JUST_INSTALLED=true
|
||||
echo "Docker installed. User '${ACTUAL_USER}' added to docker group."
|
||||
ok "Docker installed. User '${ACTUAL_USER}' added to docker group."
|
||||
fi
|
||||
|
||||
# Start and enable Docker
|
||||
$SUDO systemctl start docker
|
||||
$SUDO systemctl enable docker
|
||||
|
||||
echo "Docker installation complete."
|
||||
ok "Docker installation complete."
|
||||
fi
|
||||
|
||||
# --- Clone Repository ---
|
||||
@@ -221,14 +230,14 @@ fi
|
||||
INSTALL_DIR="${HOME}/websitebox"
|
||||
|
||||
if [ -d "$INSTALL_DIR" ]; then
|
||||
echo "WebsiteBox directory already exists at ${INSTALL_DIR}"
|
||||
echo "Pulling latest changes..."
|
||||
ok "WebsiteBox directory already exists at ${INSTALL_DIR}"
|
||||
info "Pulling latest changes..."
|
||||
cd "$INSTALL_DIR"
|
||||
git pull || true
|
||||
else
|
||||
echo "Cloning WebsiteBox..."
|
||||
echo " Downloading the project files from GitHub. Just a few seconds."
|
||||
git clone https://github.com/websitebox/websitebox.git "$INSTALL_DIR"
|
||||
step "Cloning WebsiteBox..."
|
||||
info "Downloading the project files. Just a few seconds."
|
||||
git clone https://git.constantprojects.xyz/tankadmin/websitebox.git "$INSTALL_DIR"
|
||||
cd "$INSTALL_DIR"
|
||||
fi
|
||||
|
||||
@@ -240,13 +249,13 @@ chmod +x setup.sh install.sh scripts/*.sh
|
||||
echo ""
|
||||
if [ "$DOCKER_JUST_INSTALLED" = true ] && [ "$ACTUAL_USER" != "root" ]; then
|
||||
# Activate docker group for this session without requiring logout/login
|
||||
echo "Activating Docker permissions for current session..."
|
||||
info "Activating Docker permissions for current session..."
|
||||
sg docker -c "./setup.sh"
|
||||
else
|
||||
./setup.sh
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "If 'docker compose' commands fail later, log out and back in"
|
||||
echo "to permanently activate Docker permissions, then try again."
|
||||
warn "If 'docker compose' commands fail later, log out and back in"
|
||||
warn "to permanently activate Docker permissions, then try again."
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user