Files
Vish-hands cddeee6849 Clean up - simple zero-intervention bootstrap
- Removed ansible, compose, docs, scripts, tasks, templates
- Simplified bootstrap.sh for all major distros
- Works on Ubuntu, Debian, Fedora, Rocky, Arch, openSUSE
- Installs Docker, Tailscale, essential tools
- Configures firewall automatically

Co-authored-by: openhands <openhands@all-hands.dev>
2026-01-10 09:04:07 +00:00

325 lines
10 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# Server Bootstrap Script
# =============================================================================
# Prepares a fresh server with Docker, Tailscale, and essential tools.
# Zero intervention required - just run and go.
#
# Supported: Ubuntu, Debian, Fedora, Rocky/Alma/RHEL, Arch, openSUSE
#
# Usage:
# curl -fsSL <url>/bootstrap.sh | sudo bash
#
# Options:
# --no-tailscale Skip Tailscale installation
# --no-firewall Skip firewall configuration
# =============================================================================
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log() { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1" >&2; exit 1; }
# Configuration
SKIP_TAILSCALE=false
SKIP_FIREWALL=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--no-tailscale) SKIP_TAILSCALE=true; shift ;;
--no-firewall) SKIP_FIREWALL=true; shift ;;
--help|-h)
echo "Usage: bootstrap.sh [--no-tailscale] [--no-firewall]"
exit 0
;;
*) shift ;;
esac
done
# Check root
[[ $EUID -ne 0 ]] && error "Run as root: sudo bash bootstrap.sh"
# Detect OS
detect_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS=$ID
OS_VERSION=${VERSION_ID:-}
OS_NAME=$NAME
else
error "Cannot detect OS"
fi
log "Detected: $OS_NAME $OS_VERSION"
}
# Install essential packages
install_essentials() {
log "Installing essential packages..."
case $OS in
ubuntu|debian|linuxmint|pop)
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq \
curl wget git unzip htop nano vim \
ca-certificates gnupg lsb-release \
jq tree ncdu lsof net-tools
;;
fedora)
dnf install -y -q \
curl wget git unzip htop nano vim \
ca-certificates gnupg \
jq tree ncdu lsof net-tools
;;
rocky|almalinux|rhel|centos)
dnf install -y -q epel-release 2>/dev/null || true
dnf install -y -q \
curl wget git unzip htop nano vim \
ca-certificates gnupg \
jq tree ncdu lsof net-tools
;;
arch|manjaro|endeavouros)
pacman -Sy --noconfirm \
curl wget git unzip htop nano vim \
ca-certificates gnupg \
jq tree ncdu lsof net-tools
;;
opensuse*|sles)
zypper install -y \
curl wget git unzip htop nano vim \
ca-certificates \
jq tree ncdu lsof net-tools
;;
*)
warn "Unknown OS: $OS - skipping package installation"
;;
esac
success "Essential packages installed"
}
# Install Docker
install_docker() {
if command -v docker &>/dev/null; then
success "Docker already installed"
return
fi
log "Installing Docker..."
case $OS in
ubuntu|debian|linuxmint|pop)
# Remove old versions
apt-get remove -y -qq docker docker-engine docker.io containerd runc 2>/dev/null || true
install -m 0755 -d /etc/apt/keyrings
# Determine base OS for Docker repo
DOCKER_OS=$OS
if [[ "$OS" == "linuxmint" || "$OS" == "pop" ]]; then
DOCKER_OS="ubuntu"
fi
curl -fsSL https://download.docker.com/linux/$DOCKER_OS/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 2>/dev/null
chmod a+r /etc/apt/keyrings/docker.gpg
# Get codename
if [[ -n "${VERSION_CODENAME:-}" ]]; then
CODENAME=$VERSION_CODENAME
else
CODENAME=$(lsb_release -cs 2>/dev/null || echo "jammy")
fi
# Map derivative codenames to Ubuntu
case $OS in
linuxmint|pop)
case $OS_VERSION in
20*|21.0|21.1) CODENAME="focal" ;;
21.2|21.3|22*) CODENAME="jammy" ;;
*) CODENAME="jammy" ;;
esac
;;
esac
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$DOCKER_OS $CODENAME stable" > /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y -qq docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
;;
fedora)
dnf remove -y -q docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true
dnf install -y -q dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
dnf install -y -q docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
;;
rocky|almalinux|rhel|centos)
dnf remove -y -q docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 2>/dev/null || true
dnf install -y -q dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y -q docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
;;
arch|manjaro|endeavouros)
pacman -Sy --noconfirm docker docker-compose
;;
opensuse*|sles)
zypper install -y docker docker-compose
;;
*)
error "Unsupported OS for Docker: $OS"
;;
esac
systemctl enable --now docker
success "Docker installed"
}
# Install Tailscale
install_tailscale() {
$SKIP_TAILSCALE && return
if command -v tailscale &>/dev/null; then
success "Tailscale already installed"
return
fi
log "Installing Tailscale..."
curl -fsSL https://tailscale.com/install.sh | sh
success "Tailscale installed - run 'sudo tailscale up' to connect"
}
# Configure firewall
configure_firewall() {
$SKIP_FIREWALL && return
log "Configuring firewall..."
case $OS in
ubuntu|debian|linuxmint|pop)
if ! command -v ufw &>/dev/null; then
apt-get install -y -qq ufw
fi
ufw --force reset >/dev/null 2>&1
ufw default deny incoming >/dev/null
ufw default allow outgoing >/dev/null
ufw allow ssh >/dev/null
ufw allow 32400/tcp >/dev/null # Plex
ufw allow 8096/tcp >/dev/null # Jellyfin
ufw --force enable >/dev/null
success "UFW firewall configured"
;;
fedora|rocky|almalinux|rhel|centos)
if command -v firewall-cmd &>/dev/null; then
firewall-cmd --permanent --add-service=ssh >/dev/null 2>&1
firewall-cmd --permanent --add-port=32400/tcp >/dev/null 2>&1 # Plex
firewall-cmd --permanent --add-port=8096/tcp >/dev/null 2>&1 # Jellyfin
firewall-cmd --reload >/dev/null 2>&1
success "firewalld configured"
fi
;;
*)
warn "Firewall configuration skipped for $OS"
;;
esac
}
# Create helpful aliases
create_aliases() {
log "Creating helpful aliases..."
cat > /etc/profile.d/server-aliases.sh << 'EOF'
# Server management aliases
alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
alias dlogs='docker compose logs -f'
alias dstop='docker compose stop'
alias dstart='docker compose up -d'
alias drestart='docker compose restart'
alias dupdate='docker compose pull && docker compose up -d'
# System info
alias sysinfo='echo "=== System ===" && uname -a && echo && free -h && echo && df -h /'
alias myip='curl -s ifconfig.me'
alias ports='ss -tulpn | grep LISTEN'
EOF
chmod +x /etc/profile.d/server-aliases.sh
success "Aliases created (reload shell to use)"
}
# Show completion message
show_complete() {
local IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')
echo ""
echo "========================================"
echo " Server Bootstrap Complete!"
echo "========================================"
echo ""
echo "Installed:"
echo " ✅ Docker & Docker Compose"
if ! $SKIP_TAILSCALE; then
echo " ✅ Tailscale (run 'sudo tailscale up' to connect)"
fi
if ! $SKIP_FIREWALL; then
echo " ✅ Firewall (SSH, Plex, Jellyfin allowed)"
fi
echo " ✅ Essential tools (htop, git, curl, etc.)"
echo ""
echo "Server IP: $IP"
echo ""
echo "Next steps:"
echo " 1. Connect Tailscale: sudo tailscale up"
echo " 2. Install arr-suite:"
echo ""
echo " # Plex version:"
echo " curl -fsSL -H \"Authorization: token YOUR_TOKEN\" \\"
echo " \"https://git.vish.gg/Vish/arr-suite/raw/branch/main/install.sh\" | sudo bash"
echo ""
echo " # Jellyfin version:"
echo " curl -fsSL -H \"Authorization: token YOUR_TOKEN\" \\"
echo " \"https://git.vish.gg/Vish/arr-suite-jellyfin/raw/branch/main/install.sh\" | sudo bash"
echo ""
echo "Helpful commands:"
echo " dps - Show running containers"
echo " dlogs - View container logs"
echo " dupdate - Update all containers"
echo " sysinfo - System information"
echo " myip - Show public IP"
echo ""
}
# Main
main() {
echo ""
echo "========================================"
echo " Server Bootstrap"
echo "========================================"
echo ""
detect_os
install_essentials
install_docker
install_tailscale
configure_firewall
create_aliases
show_complete
}
main