592 lines
19 KiB
Bash
592 lines
19 KiB
Bash
#!/bin/bash
|
||
|
||
# ======================================
|
||
# AI Server Ubuntu Installation Script
|
||
# ======================================
|
||
# Автоматическое развертывание Ollama + Open WebUI на Ubuntu
|
||
# Оптимизировано для RTX 2060 и других NVIDIA GPU
|
||
# Версия: 1.0
|
||
|
||
set -e # Остановка при ошибках
|
||
|
||
# Цвета для вывода
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
PURPLE='\033[0;35m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Конфигурация
|
||
DEFAULT_MODEL="llama3.2:3b"
|
||
WEB_PORT=3000
|
||
OLLAMA_PORT=11434
|
||
INSTALL_DIR="/opt/ai-server"
|
||
SERVICE_USER="aiserver"
|
||
|
||
# Функции вывода
|
||
print_banner() {
|
||
echo -e "${GREEN}"
|
||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||
echo "║ AI SERVER UBUNTU ║"
|
||
echo "║ Ollama + Open WebUI + RTX 2060 ║"
|
||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||
echo -e "${NC}"
|
||
}
|
||
|
||
log_info() {
|
||
echo -e "${CYAN}[INFO]${NC} $1"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
}
|
||
|
||
log_step() {
|
||
echo -e "${PURPLE}[STEP]${NC} $1"
|
||
}
|
||
|
||
# Проверка прав root
|
||
check_root() {
|
||
if [[ $EUID -ne 0 ]]; then
|
||
log_error "Этот скрипт должен запускаться с правами root"
|
||
log_info "Используйте: sudo $0"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Определение дистрибутива
|
||
detect_distro() {
|
||
if [[ -f /etc/os-release ]]; then
|
||
. /etc/os-release
|
||
DISTRO=$ID
|
||
VERSION=$VERSION_ID
|
||
log_info "Обнаружен дистрибутив: $PRETTY_NAME"
|
||
else
|
||
log_error "Не удается определить дистрибутив Linux"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Обновление системы
|
||
update_system() {
|
||
log_step "Обновление системы..."
|
||
apt update && apt upgrade -y
|
||
apt install -y curl wget git htop neofetch lsb-release gnupg software-properties-common
|
||
log_success "Система обновлена"
|
||
}
|
||
|
||
# Проверка и установка NVIDIA драйверов
|
||
install_nvidia_drivers() {
|
||
log_step "Проверка NVIDIA GPU..."
|
||
|
||
if ! command -v nvidia-smi &> /dev/null; then
|
||
log_warning "NVIDIA драйверы не найдены, устанавливаю..."
|
||
|
||
# Определение рекомендуемого драйвера
|
||
ubuntu-drivers devices
|
||
|
||
# Автоматическая установка рекомендуемого драйвера
|
||
ubuntu-drivers autoinstall
|
||
|
||
log_info "NVIDIA драйверы установлены. Требуется перезагрузка!"
|
||
log_warning "Выполните 'sudo reboot' и запустите скрипт снова"
|
||
exit 0
|
||
else
|
||
log_success "NVIDIA драйверы уже установлены"
|
||
nvidia-smi
|
||
fi
|
||
}
|
||
|
||
# Установка Docker
|
||
install_docker() {
|
||
log_step "Установка Docker..."
|
||
|
||
if ! command -v docker &> /dev/null; then
|
||
# Удаление старых версий
|
||
apt remove -y docker.io docker-doc docker-compose podman-docker containerd runc 2>/dev/null || true
|
||
|
||
# Установка репозитория Docker
|
||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
|
||
# Установка Docker
|
||
apt update
|
||
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||
|
||
# Настройка пользователя
|
||
usermod -aG docker $SUDO_USER 2>/dev/null || true
|
||
systemctl enable docker
|
||
systemctl start docker
|
||
|
||
log_success "Docker установлен"
|
||
else
|
||
log_success "Docker уже установлен"
|
||
fi
|
||
|
||
# Проверка Docker
|
||
docker --version
|
||
}
|
||
|
||
# Установка NVIDIA Container Toolkit
|
||
install_nvidia_docker() {
|
||
log_step "Установка NVIDIA Container Toolkit..."
|
||
|
||
if ! docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi &>/dev/null; then
|
||
# Добавление репозитория NVIDIA
|
||
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
|
||
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
|
||
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
|
||
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
|
||
|
||
apt update
|
||
apt install -y nvidia-container-toolkit
|
||
|
||
# Настройка Docker для NVIDIA
|
||
nvidia-ctk runtime configure --runtime=docker
|
||
systemctl restart docker
|
||
|
||
log_success "NVIDIA Container Toolkit установлен"
|
||
else
|
||
log_success "NVIDIA Container Toolkit уже настроен"
|
||
fi
|
||
|
||
# Тест GPU в Docker
|
||
log_info "Тестирование GPU в Docker..."
|
||
docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi
|
||
}
|
||
|
||
# Установка Ollama
|
||
install_ollama() {
|
||
log_step "Установка Ollama..."
|
||
|
||
if ! command -v ollama &> /dev/null; then
|
||
curl -fsSL https://ollama.ai/install.sh | sh
|
||
log_success "Ollama установлен"
|
||
else
|
||
log_success "Ollama уже установлен"
|
||
fi
|
||
|
||
# Создание пользователя для сервиса
|
||
if ! id "$SERVICE_USER" &>/dev/null; then
|
||
useradd -r -s /bin/false -d /nonexistent $SERVICE_USER
|
||
usermod -aG docker $SERVICE_USER
|
||
log_success "Пользователь $SERVICE_USER создан"
|
||
fi
|
||
}
|
||
|
||
# Настройка systemd сервиса для Ollama
|
||
setup_ollama_service() {
|
||
log_step "Настройка Ollama сервиса..."
|
||
|
||
cat > /etc/systemd/system/ollama.service << EOF
|
||
[Unit]
|
||
Description=Ollama Server
|
||
After=network-online.target
|
||
|
||
[Service]
|
||
ExecStart=/usr/local/bin/ollama serve
|
||
User=$SERVICE_USER
|
||
Group=$SERVICE_USER
|
||
Restart=always
|
||
RestartSec=3
|
||
Environment="OLLAMA_HOST=0.0.0.0:$OLLAMA_PORT"
|
||
Environment="OLLAMA_KEEP_ALIVE=24h"
|
||
Environment="OLLAMA_NUM_PARALLEL=2"
|
||
Environment="OLLAMA_MAX_LOADED_MODELS=2"
|
||
Environment="OLLAMA_FLASH_ATTENTION=1"
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
systemctl daemon-reload
|
||
systemctl enable ollama
|
||
systemctl start ollama
|
||
|
||
log_success "Ollama сервис настроен"
|
||
|
||
# Ожидание запуска
|
||
sleep 10
|
||
|
||
# Проверка статуса
|
||
if systemctl is-active --quiet ollama; then
|
||
log_success "Ollama сервис запущен"
|
||
else
|
||
log_error "Ошибка запуска Ollama сервиса"
|
||
journalctl -u ollama --no-pager -l
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Установка моделей
|
||
install_models() {
|
||
log_step "Установка модели $DEFAULT_MODEL..."
|
||
log_info "Это может занять несколько минут в зависимости от скорости интернета..."
|
||
|
||
# Установка модели от имени пользователя сервиса
|
||
sudo -u $SERVICE_USER ollama pull $DEFAULT_MODEL
|
||
|
||
log_success "Модель $DEFAULT_MODEL установлена"
|
||
|
||
# Список доступных моделей
|
||
log_info "Доступные модели:"
|
||
sudo -u $SERVICE_USER ollama list
|
||
}
|
||
|
||
# Создание рабочей директории
|
||
setup_directories() {
|
||
log_step "Создание рабочих директорий..."
|
||
|
||
mkdir -p $INSTALL_DIR
|
||
mkdir -p $INSTALL_DIR/config
|
||
mkdir -p $INSTALL_DIR/logs
|
||
mkdir -p $INSTALL_DIR/scripts
|
||
|
||
# Копирование файлов конфигурации
|
||
if [[ -f docker-compose.yml ]]; then
|
||
cp docker-compose.yml $INSTALL_DIR/
|
||
fi
|
||
|
||
chown -R $SERVICE_USER:$SERVICE_USER $INSTALL_DIR
|
||
|
||
log_success "Директории созданы: $INSTALL_DIR"
|
||
}
|
||
|
||
# Создание Docker Compose файла
|
||
create_docker_compose() {
|
||
log_step "Создание Docker Compose конфигурации..."
|
||
|
||
cat > $INSTALL_DIR/docker-compose.yml << EOF
|
||
version: '3.8'
|
||
|
||
services:
|
||
open-webui:
|
||
image: ghcr.io/open-webui/open-webui:main
|
||
container_name: ai-server-webui
|
||
ports:
|
||
- "$WEB_PORT:8080"
|
||
environment:
|
||
- OLLAMA_BASE_URL=http://host.docker.internal:$OLLAMA_PORT
|
||
- WEBUI_SECRET_KEY=ai-server-secret-key-ubuntu-2024
|
||
- WEBUI_NAME=AI Server Ubuntu
|
||
- DEFAULT_LOCALE=ru-RU
|
||
- DEFAULT_MODELS=$DEFAULT_MODEL
|
||
- ENABLE_SIGNUP=true
|
||
- ENABLE_LOGIN_FORM=true
|
||
- SHOW_ADMIN_DETAILS=false
|
||
- ENABLE_COMMUNITY_SHARING=false
|
||
volumes:
|
||
- open-webui-data:/app/backend/data
|
||
- $INSTALL_DIR/config:/app/backend/config:ro
|
||
extra_hosts:
|
||
- "host.docker.internal:host-gateway"
|
||
restart: unless-stopped
|
||
networks:
|
||
- ai-network
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
cpus: '2.0'
|
||
memory: 4G
|
||
reservations:
|
||
cpus: '0.5'
|
||
memory: 1G
|
||
|
||
# Мониторинг (опционально)
|
||
portainer:
|
||
image: portainer/portainer-ce:latest
|
||
container_name: ai-server-portainer
|
||
ports:
|
||
- "9000:9000"
|
||
volumes:
|
||
- /var/run/docker.sock:/var/run/docker.sock
|
||
- portainer-data:/data
|
||
restart: unless-stopped
|
||
networks:
|
||
- ai-network
|
||
profiles:
|
||
- monitoring
|
||
|
||
networks:
|
||
ai-network:
|
||
driver: bridge
|
||
|
||
volumes:
|
||
open-webui-data:
|
||
driver: local
|
||
portainer-data:
|
||
driver: local
|
||
EOF
|
||
|
||
log_success "Docker Compose файл создан"
|
||
}
|
||
|
||
# Запуск веб-интерфейса
|
||
start_webui() {
|
||
log_step "Запуск веб-интерфейса..."
|
||
|
||
cd $INSTALL_DIR
|
||
docker compose up -d
|
||
|
||
# Проверка запуска
|
||
sleep 15
|
||
|
||
if docker compose ps | grep -q "running"; then
|
||
log_success "Веб-интерфейс запущен"
|
||
log_info "Доступен по адресу: http://$(hostname -I | awk '{print $1}'):$WEB_PORT"
|
||
else
|
||
log_error "Ошибка запуска веб-интерфейса"
|
||
docker compose logs
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Создание скриптов управления
|
||
create_management_scripts() {
|
||
log_step "Создание скриптов управления..."
|
||
|
||
# Скрипт запуска
|
||
cat > $INSTALL_DIR/scripts/start.sh << 'EOF'
|
||
#!/bin/bash
|
||
echo "🚀 Запуск AI Server..."
|
||
|
||
cd /opt/ai-server
|
||
|
||
# Проверка Ollama
|
||
if ! systemctl is-active --quiet ollama; then
|
||
echo "Запуск Ollama..."
|
||
sudo systemctl start ollama
|
||
sleep 5
|
||
fi
|
||
|
||
# Запуск веб-интерфейса
|
||
echo "Запуск веб-интерфейса..."
|
||
docker compose up -d
|
||
|
||
echo "✅ AI Server запущен!"
|
||
echo "🌐 Веб-интерфейс: http://$(hostname -I | awk '{print $1}'):3000"
|
||
EOF
|
||
|
||
# Скрипт остановки
|
||
cat > $INSTALL_DIR/scripts/stop.sh << 'EOF'
|
||
#!/bin/bash
|
||
echo "⏹️ Остановка AI Server..."
|
||
|
||
cd /opt/ai-server
|
||
|
||
# Остановка веб-интерфейса
|
||
docker compose down
|
||
|
||
# Остановка Ollama (опционально)
|
||
# sudo systemctl stop ollama
|
||
|
||
echo "✅ AI Server остановлен!"
|
||
EOF
|
||
|
||
# Скрипт статуса
|
||
cat > $INSTALL_DIR/scripts/status.sh << 'EOF'
|
||
#!/bin/bash
|
||
echo "📊 Статус AI Server"
|
||
echo "==================="
|
||
|
||
# Статус Ollama
|
||
echo "🤖 Ollama:"
|
||
if systemctl is-active --quiet ollama; then
|
||
echo " ✅ Запущен"
|
||
echo " 📍 http://localhost:11434"
|
||
else
|
||
echo " ❌ Остановлен"
|
||
fi
|
||
|
||
# Статус веб-интерфейса
|
||
echo ""
|
||
echo "🌐 Веб-интерфейс:"
|
||
cd /opt/ai-server
|
||
if docker compose ps | grep -q "running"; then
|
||
echo " ✅ Запущен"
|
||
echo " 📍 http://$(hostname -I | awk '{print $1}'):3000"
|
||
else
|
||
echo " ❌ Остановлен"
|
||
fi
|
||
|
||
# Модели
|
||
echo ""
|
||
echo "📦 Установленные модели:"
|
||
sudo -u aiserver ollama list 2>/dev/null || echo " ❌ Ollama недоступен"
|
||
|
||
# Ресурсы
|
||
echo ""
|
||
echo "💻 Использование ресурсов:"
|
||
echo "GPU:"
|
||
nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total --format=csv,noheader,nounits 2>/dev/null || echo " ❌ NVIDIA GPU недоступен"
|
||
|
||
echo ""
|
||
echo "CPU/RAM:"
|
||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}" 2>/dev/null | grep ai-server || echo " ❌ Контейнеры не запущены"
|
||
EOF
|
||
|
||
# Установка прав
|
||
chmod +x $INSTALL_DIR/scripts/*.sh
|
||
|
||
# Создание символических ссылок
|
||
ln -sf $INSTALL_DIR/scripts/start.sh /usr/local/bin/ai-start
|
||
ln -sf $INSTALL_DIR/scripts/stop.sh /usr/local/bin/ai-stop
|
||
ln -sf $INSTALL_DIR/scripts/status.sh /usr/local/bin/ai-status
|
||
|
||
log_success "Скрипты управления созданы"
|
||
log_info "Доступные команды: ai-start, ai-stop, ai-status"
|
||
}
|
||
|
||
# Настройка файрвола
|
||
setup_firewall() {
|
||
log_step "Настройка файрвола..."
|
||
|
||
if command -v ufw &> /dev/null; then
|
||
ufw allow $WEB_PORT/tcp comment "AI Server Web UI"
|
||
ufw allow $OLLAMA_PORT/tcp comment "Ollama API"
|
||
ufw --force enable
|
||
log_success "Файрвол настроен"
|
||
else
|
||
log_warning "UFW не найден, настройте файрвол вручную"
|
||
log_info "Откройте порты: $WEB_PORT (веб-интерфейс), $OLLAMA_PORT (Ollama API)"
|
||
fi
|
||
}
|
||
|
||
# Создание конфигурационного файла
|
||
create_config() {
|
||
log_step "Создание конфигурационного файла..."
|
||
|
||
cat > $INSTALL_DIR/config/server.conf << EOF
|
||
# AI Server Configuration
|
||
# RTX 2060 Optimized Settings
|
||
|
||
[ollama]
|
||
host = 0.0.0.0
|
||
port = $OLLAMA_PORT
|
||
keep_alive = 24h
|
||
num_parallel = 2
|
||
max_loaded_models = 2
|
||
flash_attention = true
|
||
|
||
[webui]
|
||
port = $WEB_PORT
|
||
default_model = $DEFAULT_MODEL
|
||
locale = ru-RU
|
||
enable_signup = true
|
||
|
||
[gpu]
|
||
# RTX 2060 имеет 6GB VRAM
|
||
# Рекомендуемые модели для RTX 2060:
|
||
# - llama3.2:1b (быстрая, ~1.3GB VRAM)
|
||
# - llama3.2:3b (оптимальная, ~2.0GB VRAM)
|
||
# - codellama:7b (для кода, ~3.8GB VRAM)
|
||
# - mistral:7b (универсальная, ~4.1GB VRAM)
|
||
|
||
recommended_models = llama3.2:1b,llama3.2:3b,codellama:7b,mistral:7b
|
||
max_context_length = 4096
|
||
gpu_memory_fraction = 0.8
|
||
|
||
[performance]
|
||
# Оптимизация для RTX 2060
|
||
batch_size = 8
|
||
num_threads = 4
|
||
use_mlock = true
|
||
use_mmap = true
|
||
EOF
|
||
|
||
log_success "Конфигурационный файл создан"
|
||
}
|
||
|
||
# Финальные настройки
|
||
finalize_installation() {
|
||
log_step "Финальные настройки..."
|
||
|
||
# Создание алиасов
|
||
cat >> /home/$SUDO_USER/.bashrc << EOF
|
||
|
||
# AI Server aliases
|
||
alias ai-start='sudo /usr/local/bin/ai-start'
|
||
alias ai-stop='sudo /usr/local/bin/ai-stop'
|
||
alias ai-status='/usr/local/bin/ai-status'
|
||
alias ai-logs='cd /opt/ai-server && docker compose logs -f'
|
||
alias ai-models='sudo -u aiserver ollama list'
|
||
EOF
|
||
|
||
# Информация о системе
|
||
log_success "Установка завершена!"
|
||
|
||
echo -e "${GREEN}"
|
||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||
echo "║ УСТАНОВКА ЗАВЕРШЕНА! ║"
|
||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||
echo -e "${NC}"
|
||
|
||
echo -e "${YELLOW}🌐 Веб-интерфейс:${NC} http://$(hostname -I | awk '{print $1}'):$WEB_PORT"
|
||
echo -e "${YELLOW}🤖 Ollama API:${NC} http://$(hostname -I | awk '{print $1}'):$OLLAMA_PORT"
|
||
echo -e "${YELLOW}📁 Рабочая директория:${NC} $INSTALL_DIR"
|
||
echo ""
|
||
echo -e "${CYAN}📋 Команды управления:${NC}"
|
||
echo " • ai-start - запуск AI сервера"
|
||
echo " • ai-stop - остановка AI сервера"
|
||
echo " • ai-status - проверка статуса"
|
||
echo " • ai-logs - просмотр логов"
|
||
echo " • ai-models - список моделей"
|
||
echo ""
|
||
echo -e "${CYAN}📦 Установленные модели:${NC}"
|
||
sudo -u $SERVICE_USER ollama list 2>/dev/null || echo " Модели будут загружены при первом запуске"
|
||
echo ""
|
||
echo -e "${CYAN}🎯 Рекомендуемые модели для RTX 2060:${NC}"
|
||
echo " • ollama pull llama3.2:1b (быстрая, 1.3GB)"
|
||
echo " • ollama pull llama3.2:3b (сбалансированная, 2GB)"
|
||
echo " • ollama pull codellama:7b (для кода, 3.8GB)"
|
||
echo " • ollama pull mistral:7b (универсальная, 4.1GB)"
|
||
echo ""
|
||
echo -e "${GREEN}Перезайдите в терминал для применения алиасов!${NC}"
|
||
}
|
||
|
||
# ======================================
|
||
# ОСНОВНАЯ ЛОГИКА СКРИПТА
|
||
# ======================================
|
||
|
||
main() {
|
||
print_banner
|
||
|
||
# Проверки
|
||
check_root
|
||
detect_distro
|
||
|
||
# Установка компонентов
|
||
update_system
|
||
install_nvidia_drivers
|
||
install_docker
|
||
install_nvidia_docker
|
||
install_ollama
|
||
|
||
# Настройка сервисов
|
||
setup_directories
|
||
create_docker_compose
|
||
create_config
|
||
setup_ollama_service
|
||
install_models
|
||
|
||
# Запуск сервисов
|
||
start_webui
|
||
create_management_scripts
|
||
setup_firewall
|
||
|
||
# Завершение
|
||
finalize_installation
|
||
}
|
||
|
||
# Запуск основной функции
|
||
main "$@" |