174 lines
7.0 KiB
Bash
174 lines
7.0 KiB
Bash
#!/usr/bin/env bash
|
|
# Music Orchestrator — production deploy script for Ubuntu
|
|
# Run as a regular user with sudo access. Do NOT run as root.
|
|
#
|
|
# First run: bash deploy.sh
|
|
# Update: bash deploy.sh (re-run at any time — it's idempotent)
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Config ─────────────────────────────────────────────────────────────────────
|
|
INSTALL_DIR="/opt/music-orchestrator"
|
|
SERVICE_NAME="music-orchestrator"
|
|
SERVICE_USER="$(whoami)"
|
|
NGINX_SITE="music-orchestrator"
|
|
|
|
# Where your Plex library lives on this machine.
|
|
# Can be changed later by editing $INSTALL_DIR/backend/.env
|
|
DEFAULT_MUSIC_DIR="$HOME/Music"
|
|
|
|
# Colours
|
|
GREEN="\033[0;32m"; YELLOW="\033[0;33m"; RED="\033[0;31m"; NC="\033[0m"
|
|
info() { echo -e "${GREEN}[+]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
|
section() { echo -e "\n${GREEN}── $* ──────────────────────────────────────────────────${NC}"; }
|
|
|
|
# ── Checks ─────────────────────────────────────────────────────────────────────
|
|
section "Checking prerequisites"
|
|
|
|
if [[ $EUID -eq 0 ]]; then
|
|
echo -e "${RED}[✗]${NC} Do not run this script as root. Run as your regular user."
|
|
exit 1
|
|
fi
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
if [[ ! -f "$SCRIPT_DIR/backend/main.py" ]]; then
|
|
echo -e "${RED}[✗]${NC} Run this script from the music-orchestrator project root."
|
|
exit 1
|
|
fi
|
|
|
|
# ── System dependencies ────────────────────────────────────────────────────────
|
|
section "Installing system packages"
|
|
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y \
|
|
python3 python3-pip python3-venv \
|
|
ffmpeg \
|
|
nginx \
|
|
nodejs npm \
|
|
--no-install-recommends
|
|
|
|
info "System packages ready"
|
|
|
|
# ── Install directory ──────────────────────────────────────────────────────────
|
|
section "Setting up install directory ($INSTALL_DIR)"
|
|
|
|
sudo mkdir -p "$INSTALL_DIR"
|
|
sudo chown "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
|
|
|
|
# Sync project files (rsync excludes dev artifacts)
|
|
rsync -a --delete \
|
|
--exclude='.git' \
|
|
--exclude='node_modules' \
|
|
--exclude='frontend/dist' \
|
|
--exclude='backend/venv' \
|
|
--exclude='backend/__pycache__' \
|
|
--exclude='backend/tmp' \
|
|
--exclude='backend/Music' \
|
|
--exclude='.env' \
|
|
"$SCRIPT_DIR/" "$INSTALL_DIR/"
|
|
|
|
info "Project files synced to $INSTALL_DIR"
|
|
|
|
# ── Backend: Python virtualenv ─────────────────────────────────────────────────
|
|
section "Setting up Python virtual environment"
|
|
|
|
python3 -m venv "$INSTALL_DIR/backend/venv"
|
|
"$INSTALL_DIR/backend/venv/bin/pip" install --quiet --upgrade pip
|
|
"$INSTALL_DIR/backend/venv/bin/pip" install --quiet -r "$INSTALL_DIR/backend/requirements.txt"
|
|
|
|
info "Python dependencies installed"
|
|
|
|
# ── Backend: .env ──────────────────────────────────────────────────────────────
|
|
section "Configuring backend .env"
|
|
|
|
ENV_FILE="$INSTALL_DIR/backend/.env"
|
|
|
|
if [[ ! -f "$ENV_FILE" ]]; then
|
|
# First install — prompt for music dir
|
|
echo ""
|
|
warn "Where is your Plex music library? (press Enter for default: $DEFAULT_MUSIC_DIR)"
|
|
read -r -p " Music directory: " MUSIC_DIR_INPUT
|
|
MUSIC_DIR="${MUSIC_DIR_INPUT:-$DEFAULT_MUSIC_DIR}"
|
|
|
|
mkdir -p "$MUSIC_DIR"
|
|
|
|
cat > "$ENV_FILE" <<EOF
|
|
# Path to your Plex music library folder
|
|
MUSIC_DIR=$MUSIC_DIR
|
|
|
|
# Temp directory for in-progress downloads (auto-cleaned)
|
|
TEMP_DIR=/tmp/music-orchestrator
|
|
EOF
|
|
|
|
info ".env created — MUSIC_DIR=$MUSIC_DIR"
|
|
else
|
|
warn ".env already exists at $ENV_FILE — skipping (edit manually to change settings)"
|
|
fi
|
|
|
|
# Ensure tmp dir exists
|
|
TEMP_DIR=$(grep '^TEMP_DIR' "$ENV_FILE" 2>/dev/null | cut -d= -f2 || echo "/tmp/music-orchestrator")
|
|
mkdir -p "$TEMP_DIR"
|
|
|
|
# ── Frontend: build ────────────────────────────────────────────────────────────
|
|
section "Building React frontend"
|
|
|
|
cd "$INSTALL_DIR/frontend"
|
|
npm install --silent
|
|
npm run build
|
|
|
|
info "Frontend built to $INSTALL_DIR/frontend/dist"
|
|
|
|
# ── nginx ──────────────────────────────────────────────────────────────────────
|
|
section "Configuring nginx"
|
|
|
|
sudo cp "$INSTALL_DIR/nginx.conf" "/etc/nginx/sites-available/$NGINX_SITE"
|
|
|
|
# Enable the site, remove default if present
|
|
sudo ln -sf "/etc/nginx/sites-available/$NGINX_SITE" "/etc/nginx/sites-enabled/$NGINX_SITE"
|
|
sudo rm -f /etc/nginx/sites-enabled/default
|
|
|
|
sudo nginx -t # validate config before reloading
|
|
sudo systemctl enable nginx --quiet
|
|
sudo systemctl reload nginx
|
|
|
|
info "nginx configured and reloaded"
|
|
|
|
# ── systemd service ────────────────────────────────────────────────────────────
|
|
section "Installing systemd service"
|
|
|
|
# The service uses %i (instance name) for User= — we pass the username as the instance
|
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}@.service"
|
|
sudo cp "$INSTALL_DIR/music-orchestrator.service" "$SERVICE_FILE"
|
|
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable "${SERVICE_NAME}@${SERVICE_USER}" --quiet
|
|
sudo systemctl restart "${SERVICE_NAME}@${SERVICE_USER}"
|
|
|
|
# Wait a moment and check it started cleanly
|
|
sleep 2
|
|
if systemctl is-active --quiet "${SERVICE_NAME}@${SERVICE_USER}"; then
|
|
info "Service started successfully"
|
|
else
|
|
echo -e "${RED}[✗]${NC} Service failed to start. Check logs with:"
|
|
echo " journalctl -u ${SERVICE_NAME}@${SERVICE_USER} -n 50"
|
|
exit 1
|
|
fi
|
|
|
|
# ── Done ───────────────────────────────────────────────────────────────────────
|
|
section "Deploy complete"
|
|
|
|
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
|
|
|
echo ""
|
|
echo -e " ${GREEN}Music Orchestrator is running at:${NC}"
|
|
echo -e " http://$LOCAL_IP"
|
|
echo ""
|
|
echo " Useful commands:"
|
|
echo " View logs: journalctl -u ${SERVICE_NAME}@${SERVICE_USER} -f"
|
|
echo " Restart API: sudo systemctl restart ${SERVICE_NAME}@${SERVICE_USER}"
|
|
echo " Edit config: nano $ENV_FILE"
|
|
echo ""
|
|
echo " To update after code changes: just re-run bash deploy.sh"
|
|
echo ""
|