Clean up server architecture for multi-instance deployment
- Remove main_cycling.py, main_multi.py, main_release.py (single main.py is canonical) - Update setup.sh to read SERVICE_NAME and PORT from .env - Update env.example with SERVICE_NAME and PORT for multi-instance support - Fix server-csi to try rpicam-still before libcamera-still (Debian Trixie) Deploy pattern: clone repo twice, configure each .env, run setup.sh Each instance gets its own systemd service and install directory.
This commit is contained in:
126
server/setup.sh
126
server/setup.sh
@@ -1,14 +1,14 @@
|
||||
#!/bin/bash
|
||||
# vixy-vision Server Setup Script
|
||||
# Run this on a Raspberry Pi or similar edge device
|
||||
#
|
||||
# Usage: ./setup.sh [--with-audio]
|
||||
#
|
||||
# Usage: ./setup.sh
|
||||
#
|
||||
# Reads SERVICE_NAME and PORT from .env file for multi-instance support
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALL_DIR="${HOME}/vixy-vision"
|
||||
SERVICE_NAME="vixy-vision"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
@@ -20,20 +20,9 @@ echo_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
echo_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
echo_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Parse arguments
|
||||
WITH_AUDIO=false
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--with-audio)
|
||||
WITH_AUDIO=true
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "=========================================="
|
||||
echo " vixy-vision Server Setup"
|
||||
echo " Eyes and ears for the fox 🦊"
|
||||
echo " Eyes for the fox 🦊"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
@@ -42,21 +31,48 @@ if [[ "$(uname)" != "Linux" ]]; then
|
||||
echo_error "This script is designed for Linux (Raspberry Pi)"
|
||||
exit 1
|
||||
fi
|
||||
# Check for .env file
|
||||
if [ ! -f "${SCRIPT_DIR}/.env" ]; then
|
||||
echo_error "No .env file found!"
|
||||
echo_info "Copy env.example to .env and configure it first:"
|
||||
echo " cp env.example .env"
|
||||
echo " nano .env"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Load configuration from .env
|
||||
source "${SCRIPT_DIR}/.env"
|
||||
|
||||
# Set defaults if not in .env
|
||||
SERVICE_NAME="${SERVICE_NAME:-vixy-vision}"
|
||||
PORT="${PORT:-8443}"
|
||||
CAMERA_ID="${CAMERA_ID:-camera}"
|
||||
|
||||
echo_info "Configuration:"
|
||||
echo " SERVICE_NAME: ${SERVICE_NAME}"
|
||||
echo " PORT: ${PORT}"
|
||||
echo " CAMERA_ID: ${CAMERA_ID}"
|
||||
echo ""
|
||||
|
||||
# Install directory based on service name
|
||||
INSTALL_DIR="${HOME}/${SERVICE_NAME}"
|
||||
|
||||
# Install system dependencies
|
||||
echo_info "Installing system dependencies..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python3-pip python3-venv libopencv-dev
|
||||
|
||||
if [ "$WITH_AUDIO" = true ]; then
|
||||
echo_info "Installing audio dependencies..."
|
||||
sudo apt-get install -y portaudio19-dev python3-pyaudio alsa-utils
|
||||
fi
|
||||
sudo apt-get install -y python3-pip python3-venv libopencv-dev python3-opencv
|
||||
|
||||
# Create install directory
|
||||
echo_info "Creating install directory: ${INSTALL_DIR}"
|
||||
mkdir -p "${INSTALL_DIR}"
|
||||
cp -r "${SCRIPT_DIR}"/* "${INSTALL_DIR}/"
|
||||
mkdir -p "${INSTALL_DIR}/ssl"
|
||||
|
||||
# Copy files
|
||||
cp "${SCRIPT_DIR}/main.py" "${INSTALL_DIR}/"
|
||||
cp "${SCRIPT_DIR}/motion.py" "${INSTALL_DIR}/"
|
||||
cp "${SCRIPT_DIR}/requirements.txt" "${INSTALL_DIR}/"
|
||||
cp "${SCRIPT_DIR}/generate_cert.sh" "${INSTALL_DIR}/"
|
||||
cp "${SCRIPT_DIR}/.env" "${INSTALL_DIR}/"
|
||||
|
||||
# Create virtual environment
|
||||
echo_info "Creating Python virtual environment..."
|
||||
@@ -69,54 +85,29 @@ echo_info "Installing Python dependencies..."
|
||||
pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
|
||||
if [ "$WITH_AUDIO" = true ]; then
|
||||
pip install pyaudio webrtcvad numpy
|
||||
fi
|
||||
|
||||
# Generate SSL certificates
|
||||
echo_info "Generating SSL certificates..."
|
||||
chmod +x generate_cert.sh
|
||||
./generate_cert.sh
|
||||
|
||||
# Generate API key if .env doesn't exist
|
||||
if [ ! -f .env ]; then
|
||||
echo_info "Generating API key..."
|
||||
API_KEY=$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')
|
||||
cat > .env << EOF
|
||||
# vixy-vision Server Configuration
|
||||
# Generated by setup.sh on $(date)
|
||||
|
||||
# API Key for authentication (keep secret!)
|
||||
API_KEY=${API_KEY}
|
||||
|
||||
# Camera settings
|
||||
CAMERA_INDEX=0
|
||||
CAMERA_WIDTH=1920
|
||||
CAMERA_HEIGHT=1080
|
||||
JPEG_QUALITY=85
|
||||
EOF
|
||||
echo_info "API key generated and saved to .env"
|
||||
echo ""
|
||||
echo_warn "IMPORTANT: Save this API key for your MCP config:"
|
||||
echo -e " ${GREEN}${API_KEY}${NC}"
|
||||
echo ""
|
||||
# Generate SSL certificates if not present
|
||||
if [ ! -f ssl/cert.pem ]; then
|
||||
echo_info "Generating SSL certificates..."
|
||||
chmod +x generate_cert.sh
|
||||
./generate_cert.sh
|
||||
else
|
||||
echo_info "Using existing .env file"
|
||||
echo_info "SSL certificates already exist"
|
||||
fi
|
||||
|
||||
# Create systemd service
|
||||
echo_info "Creating systemd service..."
|
||||
echo_info "Creating systemd service: ${SERVICE_NAME}"
|
||||
sudo tee /etc/systemd/system/${SERVICE_NAME}.service > /dev/null << EOF
|
||||
[Unit]
|
||||
Description=vixy-vision Camera Server
|
||||
Description=vixy-vision Camera Server (${CAMERA_ID})
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=${USER}
|
||||
WorkingDirectory=${INSTALL_DIR}
|
||||
EnvironmentFile=${INSTALL_DIR}/.env
|
||||
Environment="PATH=${INSTALL_DIR}/venv/bin"
|
||||
ExecStart=${INSTALL_DIR}/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8443 --ssl-keyfile ssl/key.pem --ssl-certfile ssl/cert.pem
|
||||
ExecStart=${INSTALL_DIR}/venv/bin/uvicorn main:app --host 0.0.0.0 --port ${PORT} --ssl-keyfile ssl/key.pem --ssl-certfile ssl/cert.pem
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
@@ -133,6 +124,10 @@ echo "=========================================="
|
||||
echo " Setup Complete! 🦊"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Service: ${SERVICE_NAME}"
|
||||
echo "Port: ${PORT}"
|
||||
echo "Camera ID: ${CAMERA_ID}"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " Start: sudo systemctl start ${SERVICE_NAME}"
|
||||
echo " Stop: sudo systemctl stop ${SERVICE_NAME}"
|
||||
@@ -140,18 +135,9 @@ echo " Status: sudo systemctl status ${SERVICE_NAME}"
|
||||
echo " Logs: sudo journalctl -u ${SERVICE_NAME} -f"
|
||||
echo ""
|
||||
echo "Server will be available at:"
|
||||
echo " https://$(hostname -I | awk '{print $1}'):8443/"
|
||||
echo " https://$(hostname).local:${PORT}/"
|
||||
echo ""
|
||||
echo "Add to Vixy's vision config (~/.vision_setup.json):"
|
||||
echo " {"
|
||||
echo " \"cameras\": ["
|
||||
echo " {"
|
||||
echo " \"id\": \"$(hostname)\","
|
||||
echo " \"type\": \"http\","
|
||||
echo " \"url\": \"https://$(hostname -I | awk '{print $1}'):8443\","
|
||||
echo " \"api_key\": \"<your-api-key-from-above>\""
|
||||
echo " }"
|
||||
echo " ]"
|
||||
echo " }"
|
||||
echo "API Key from .env:"
|
||||
grep "^API_KEY=" "${INSTALL_DIR}/.env" | cut -d'=' -f2
|
||||
echo ""
|
||||
echo_info "Start the server with: sudo systemctl start ${SERVICE_NAME}"
|
||||
|
||||
Reference in New Issue
Block a user