#!/bin/bash # install.sh - Seedbox Server Initial Setup # Usage: curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/seedbox/install.sh | bash # # This script prepares the server for Docker-based seedbox deployment. # Services are deployed separately via Gitea Actions. set -euo pipefail # Colors for logging RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Configuration (can be overridden via environment) HOSTNAME="${SEEDBOX_HOSTNAME:-seedbox}" NFS_SERVER="${NFS_SERVER:-}" NFS_SHARE_MEDIA="${NFS_SHARE_MEDIA:-/volume2/Multimédia}" NFS_MOUNT_MEDIA="${NFS_MOUNT_MEDIA:-/mnt/media}" NFS_OPTS="defaults,_netdev,nofail,x-systemd.automount,x-systemd.mount-timeout=30s" SEEDBOX_DIR="/srv/seedbox" DOWNLOADS_DIR="${SEEDBOX_DIR}/downloads" REPO_URL="${REPO_URL:-https://gitea.arnodo.fr/Damien/infra-scripts.git}" # Pre-flight checks check_root() { if [[ $EUID -eq 0 ]]; then log_error "Do not run as root directly. Use a user with sudo privileges." exit 1 fi if ! sudo -v; then log_error "User must have sudo privileges." exit 1 fi } check_debian() { if ! grep -qi debian /etc/os-release 2>/dev/null; then log_warn "This script is optimized for Debian. Continuing anyway..." fi } main() { log_info "=== Seedbox Server Setup ===" check_root check_debian # Step 1: System update log_info "Updating system..." sudo apt-get update -qq sudo apt-get upgrade -y -qq # Step 2: Set hostname log_info "Setting hostname to: $HOSTNAME" echo "$HOSTNAME" | sudo tee /etc/hostname > /dev/null sudo hostnamectl set-hostname "$HOSTNAME" # Step 3: Install base packages log_info "Installing base packages..." sudo apt-get install -y -qq \ vim \ ca-certificates \ curl \ gnupg \ lsb-release \ fail2ban \ unattended-upgrades \ nfs-common \ ufw \ at \ git \ > /dev/null # Step 4: Install Tailscale log_info "Installing Tailscale..." curl -fsSL https://tailscale.com/install.sh | sh log_info "Connecting to Tailscale (SSH only)..." sudo tailscale up --ssh # Get Tailscale hostname for display TS_FQDN=$(tailscale status --json 2>/dev/null | awk -F'"' ' /"Self"/ { in_self=1 } in_self && /"DNSName"/ { gsub(/\.$/, "", $4); print $4; exit } ' || echo "${HOSTNAME}.ts.net") # Step 5: Install Docker log_info "Installing Docker..." sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # shellcheck disable=SC1091 sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null < /dev/null # Step 6: Configure Docker for user log_info "Adding current user to docker group..." sudo usermod -aG docker "$USER" # Step 7: Configure UFW firewall log_info "Configuring UFW firewall..." sudo ufw --force reset > /dev/null sudo ufw default deny incoming > /dev/null sudo ufw default allow outgoing > /dev/null # BitTorrent peer port (public) sudo ufw allow 51413/tcp > /dev/null sudo ufw allow 51413/udp > /dev/null # Allow all traffic on Tailscale interface sudo ufw allow in on tailscale0 > /dev/null # Temporary SSH access (safety net) sudo ufw allow 22/tcp > /dev/null sudo ufw --force enable > /dev/null # Schedule SSH rule removal in 5 minutes log_warn "SSH port 22 temporarily open for 5 minutes (safety net)." echo "sudo ufw delete allow 22/tcp && logger 'UFW: SSH port 22 closed'" | sudo at now + 5 minutes 2>/dev/null || { log_warn "Could not schedule automatic SSH cleanup. Run manually:" log_warn " sudo ufw delete allow 22/tcp" } # Step 8: Create directory structure log_info "Creating directory structure..." sudo mkdir -p "$SEEDBOX_DIR" sudo mkdir -p "$DOWNLOADS_DIR" sudo chown -R "$USER:$USER" "$SEEDBOX_DIR" # Step 9: Configure NFS mount (if NFS_SERVER provided) if [[ -n "$NFS_SERVER" ]]; then log_info "Configuring NFS mount..." sudo mkdir -p "$NFS_MOUNT_MEDIA" if ! grep -q "${NFS_SERVER}:${NFS_SHARE_MEDIA}" /etc/fstab; then log_info "Adding NFS mount: ${NFS_SERVER}:${NFS_SHARE_MEDIA} -> ${NFS_MOUNT_MEDIA}" echo "${NFS_SERVER}:${NFS_SHARE_MEDIA} ${NFS_MOUNT_MEDIA} nfs ${NFS_OPTS} 0 0" | sudo tee -a /etc/fstab > /dev/null fi sudo mount -a || log_warn "NFS mount failed - ensure NAS is accessible via Tailscale" else log_warn "NFS_SERVER not set. NFS mount skipped. Set it later if needed." fi # Step 10: Clone repository log_info "Cloning infra-scripts repository..." if [[ -d "${SEEDBOX_DIR}/.git" ]]; then cd "$SEEDBOX_DIR" git pull origin main || log_warn "Git pull failed" else git clone "$REPO_URL" "${SEEDBOX_DIR}/repo-tmp" mv "${SEEDBOX_DIR}/repo-tmp/seedbox/"* "$SEEDBOX_DIR/" 2>/dev/null || true mv "${SEEDBOX_DIR}/repo-tmp/seedbox/".* "$SEEDBOX_DIR/" 2>/dev/null || true rm -rf "${SEEDBOX_DIR}/repo-tmp" cd "$SEEDBOX_DIR" git init git remote add origin "$REPO_URL" git fetch origin git checkout -b main --track origin/main -- seedbox/ 2>/dev/null || true fi # Step 11: Configure MOTD log_info "Configuring MOTD..." sudo chmod -x /etc/update-motd.d/* 2>/dev/null || true cat << 'MOTD' | sudo tee /etc/update-motd.d/00-seedbox > /dev/null #!/bin/bash TS_FQDN=$(tailscale status --json 2>/dev/null | awk -F'"' ' /"Self"/ { in_self=1 } in_self && /"DNSName"/ { gsub(/\.$/, "", $4); print $4; exit } ') [[ -z "$TS_FQDN" ]] && TS_FQDN="$(hostname).ts.net" echo "" echo " ____ _____ _____ ____ ____ _____ __" echo "/ ___|| ____| ____| _ \| __ ) / _ \ \/ /" echo "\___ \| _| | _| | | | | _ \| | | \ /" echo " ___) | |___| |___| |_| | |_) | |_| / \\" echo "|____/|_____|_____|____/|____/ \___/_/\_\\" echo "" echo "Docker Seedbox Server" echo "─────────────────────────────────────────" echo "Access:" echo " • SSH : ${TS_FQDN}" echo " • Seeding : Public port 51413" echo "" echo "Services: (via Tailscale)" docker ps --format ' • {{.Names}} : {{.Status}}' 2>/dev/null || echo " Docker not running" echo "" echo "Storage:" echo " • Downloads : /srv/seedbox/downloads" echo " • Media : /mnt/media (NFS)" echo "" echo "Useful commands:" echo " cd /srv/seedbox && docker compose ls" echo " docker logs -f " echo "─────────────────────────────────────────" echo "" MOTD sudo chmod +x /etc/update-motd.d/00-seedbox # Final summary echo "" log_info "==========================================" log_info "Server setup complete!" log_info "==========================================" echo "" echo "Server accessible at:" echo " SSH: ${TS_FQDN}" echo "" echo "Directory structure:" echo " ${SEEDBOX_DIR}/" echo " ├── stacks/ # Docker Compose stacks" echo " ├── downloads/ # Local downloads (SSD)" echo " └── .env # Secrets (created by Gitea Actions)" echo "" echo "NFS mount:" if [[ -n "$NFS_SERVER" ]]; then echo " ${NFS_SERVER}:${NFS_SHARE_MEDIA} -> ${NFS_MOUNT_MEDIA}" else echo " Not configured. Run with NFS_SERVER= to configure." fi echo "" echo "Next steps:" echo " 1. Configure Gitea secrets (see README.md)" echo " 2. Push to main branch to trigger deployment" echo " 3. Services will be available at .taila5ad8.ts.net" echo "" log_warn "SSH port 22 will be closed in 5 minutes." log_warn "Use Tailscale SSH: ssh ${TS_FQDN}" echo "" } main "$@"