Files
ai-server/install-ubuntu.sh
2025-09-22 15:31:51 +05:00

597 lines
19 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 /opt/ai-server -m $SERVICE_USER
usermod -aG docker $SERVICE_USER
log_success "Пользователь $SERVICE_USER создан"
fi
# Создание домашней директории Ollama
mkdir -p /opt/ai-server/.ollama
chown -R $SERVICE_USER:$SERVICE_USER /opt/ai-server/.ollama
log_success "Директория Ollama создана"
}
# Настройка 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_HOME=/opt/ai-server/.ollama ollama pull $DEFAULT_MODEL
log_success "Модель $DEFAULT_MODEL установлена"
# Список доступных моделей
log_info "Доступные модели:"
sudo -u $SERVICE_USER OLLAMA_HOME=/opt/ai-server/.ollama 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 "$@"