172 lines
8.5 KiB
Bash
172 lines
8.5 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
source ./scripts/Unix/starter.sh
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Native Linux Installation Script for Schon
|
|
# Installs Schon for production use with systemd services
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
INSTALL_DIR="/opt/schon"
|
|
SCHON_USER="schon"
|
|
SCHON_GROUP="schon"
|
|
|
|
# Check if running as root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
log_error "This script must be run as root (use sudo)"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if we're in the correct directory
|
|
if [ "$(pwd)" != "$INSTALL_DIR" ]; then
|
|
log_warning "Current directory is not $INSTALL_DIR"
|
|
log_info "For production, Schon should be installed in $INSTALL_DIR"
|
|
if ! confirm "Continue anyway?"; then
|
|
log_info "Please clone the repository to $INSTALL_DIR and run again"
|
|
exit 0
|
|
fi
|
|
INSTALL_DIR="$(pwd)"
|
|
fi
|
|
|
|
log_step "Starting native Linux installation..."
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Check prerequisites
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
log_step "Checking prerequisites..."
|
|
|
|
missing_deps=()
|
|
|
|
if ! command_exists uv; then
|
|
missing_deps+=("uv (https://docs.astral.sh/uv/)")
|
|
fi
|
|
|
|
if ! command_exists psql; then
|
|
missing_deps+=("postgresql-client")
|
|
fi
|
|
|
|
if ! command_exists redis-cli; then
|
|
missing_deps+=("redis-tools")
|
|
fi
|
|
|
|
if [ ${#missing_deps[@]} -gt 0 ]; then
|
|
log_error "Missing required dependencies:"
|
|
for dep in "${missing_deps[@]}"; do
|
|
log_error " - $dep"
|
|
done
|
|
echo
|
|
log_info "Install uv with: curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
log_info "Install others with: apt install postgresql-client redis-tools"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "All prerequisites found"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Check system requirements
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
if ! check_system_requirements 4 6 20; then
|
|
if ! confirm "System requirements not met. Continue anyway?"; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Create schon user
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
log_step "Setting up schon user..."
|
|
|
|
if id "$SCHON_USER" &>/dev/null; then
|
|
log_info "User '$SCHON_USER' already exists"
|
|
else
|
|
useradd --system --shell /usr/sbin/nologin --home-dir "$INSTALL_DIR" "$SCHON_USER"
|
|
log_success "Created system user '$SCHON_USER'"
|
|
fi
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Check for .env file
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
if [ ! -f "$INSTALL_DIR/.env" ]; then
|
|
log_error ".env file not found"
|
|
log_info "Run 'make generate-env' first, then configure your .env file"
|
|
exit 1
|
|
fi
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Install Python dependencies
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
log_step "Installing Python dependencies with uv..."
|
|
|
|
cd "$INSTALL_DIR"
|
|
|
|
# Create virtual environment if it doesn't exist
|
|
if [ ! -d "$INSTALL_DIR/.venv" ]; then
|
|
uv venv "$INSTALL_DIR/.venv"
|
|
log_success "Created virtual environment"
|
|
fi
|
|
|
|
# Sync dependencies
|
|
uv sync --extra worker --extra openai
|
|
log_success "Dependencies installed"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Set ownership
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
log_step "Setting file ownership..."
|
|
|
|
chown -R "$SCHON_USER:$SCHON_GROUP" "$INSTALL_DIR"
|
|
log_success "Ownership set to $SCHON_USER:$SCHON_GROUP"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Install systemd services
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
log_step "Installing systemd services..."
|
|
|
|
SYSTEMD_DIR="/etc/systemd/system"
|
|
SERVICES=("schon-web" "schon-worker" "schon-beat" "schon-stock-updater")
|
|
|
|
for service in "${SERVICES[@]}"; do
|
|
src="$INSTALL_DIR/systemd/${service}.service"
|
|
dst="$SYSTEMD_DIR/${service}.service"
|
|
|
|
if [ -f "$src" ]; then
|
|
ln -sf "$src" "$dst"
|
|
log_info " Linked ${service}.service"
|
|
else
|
|
log_warning " Service file not found: $src"
|
|
fi
|
|
done
|
|
|
|
# Reload systemd
|
|
systemctl daemon-reload
|
|
log_success "Systemd services installed"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Enable services
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
log_step "Enabling services..."
|
|
|
|
for service in "${SERVICES[@]}"; do
|
|
systemctl enable "$service" 2>/dev/null || true
|
|
log_info " Enabled ${service}"
|
|
done
|
|
|
|
log_success "Services enabled"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Summary
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
echo
|
|
log_result "Installation complete!"
|
|
echo
|
|
log_info "Next steps:"
|
|
log_info " 1. Configure your .env file: nano $INSTALL_DIR/.env"
|
|
log_info " 2. Ensure PostgreSQL, Redis, and Elasticsearch are running"
|
|
log_info " 3. Run migrations: sudo -u $SCHON_USER $INSTALL_DIR/.venv/bin/python manage.py migrate"
|
|
log_info " 4. Create superuser: sudo -u $SCHON_USER $INSTALL_DIR/.venv/bin/python manage.py createsuperuser"
|
|
log_info " 5. Start services: systemctl start schon-web schon-worker schon-beat schon-stock-updater"
|
|
log_info " 6. Configure nginx with nginx.example.conf"
|
|
echo
|
|
log_info "View service status: systemctl status schon-web"
|
|
log_info "View logs: journalctl -u schon-web -f"
|