Files
links/setup.sh
Andrey K. Choi 2e535513b5 + Приведены все функции приложения в рабочий вид
+ Наведен порядок в файлах проекта
+ Наведен порядок в документации
+ Настроены скрипты установки, развертки и так далее, расширен MakeFile
2025-11-02 06:09:55 +09:00

521 lines
15 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
# CatLink Setup Script
# ====================
# Автоматическая настройка среды разработки
set -e # Остановить при ошибке
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Функции для цветного вывода
print_header() {
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}========================================${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
# Проверка зависимостей
check_dependencies() {
print_header "Проверка зависимостей"
# Проверка Docker
if ! command -v docker &> /dev/null; then
print_error "Docker не установлен"
print_info "Установите Docker: https://docs.docker.com/get-docker/"
exit 1
fi
print_success "Docker найден: $(docker --version)"
# Проверка Docker Compose
if ! command -v docker-compose &> /dev/null; then
print_error "Docker Compose не установлен"
print_info "Установите Docker Compose: https://docs.docker.com/compose/install/"
exit 1
fi
print_success "Docker Compose найден: $(docker-compose --version)"
# Проверка Git
if ! command -v git &> /dev/null; then
print_warning "Git не установлен (рекомендуется для обновлений)"
else
print_success "Git найден: $(git --version)"
fi
# Проверка Make
if ! command -v make &> /dev/null; then
print_warning "Make не установлен (рекомендуется для удобства)"
print_info "Установите: sudo apt-get install make"
else
print_success "Make найден: $(make --version | head -1)"
fi
}
# Создание .env файла
create_env_file() {
print_header "Создание конфигурации (.env)"
if [ -f .env ]; then
print_info ".env файл уже существует"
read -p "Пересоздать? (y/N): " recreate
if [[ ! $recreate =~ ^[Yy]$ ]]; then
print_info "Пропуск создания .env"
return
fi
fi
# Генерация SECRET_KEY
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(50))" 2>/dev/null || openssl rand -base64 32)
# Запрос данных от пользователя
echo ""
read -p "Имя базы данных [links_db]: " DB_NAME
DB_NAME=${DB_NAME:-links_db}
read -p "Пользователь БД [links_user]: " DB_USER
DB_USER=${DB_USER:-links_user}
read -p "Пароль БД [links_password]: " DB_PASSWORD
DB_PASSWORD=${DB_PASSWORD:-links_password}
read -p "Хост БД [db]: " DB_HOST
DB_HOST=${DB_HOST:-db}
read -p "Порт БД [5432]: " DB_PORT
DB_PORT=${DB_PORT:-5432}
read -p "Домен для продакшена [localhost]: " DOMAIN
DOMAIN=${DOMAIN:-localhost}
read -p "Email для SSL сертификатов: " SSL_EMAIL
# Создание .env файла
cat > .env << EOF
# Django Configuration
SECRET_KEY=$SECRET_KEY
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1,$DOMAIN
# Database Configuration
DATABASE_URL=postgresql://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME
DB_NAME=$DB_NAME
DB_USER=$DB_USER
DB_PASSWORD=$DB_PASSWORD
DB_HOST=$DB_HOST
DB_PORT=$DB_PORT
# Production Settings
DOMAIN=$DOMAIN
SSL_EMAIL=$SSL_EMAIL
# CORS Settings
CORS_ALLOWED_ORIGINS=http://localhost:3000,https://$DOMAIN
# File Upload Settings
MAX_UPLOAD_SIZE=10485760
MEDIA_ROOT=/app/storage
# Cache Settings
CACHE_TTL=300
# Email Settings (optional)
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
EMAIL_HOST=
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
# Redis Settings (optional)
REDIS_URL=redis://redis:6379/0
# Logging
LOG_LEVEL=INFO
EOF
print_success ".env файл создан"
}
# Создание продакшен конфигурации
create_production_config() {
print_header "Создание продакшен конфигурации"
if [ ! -f docker-compose.prod.yml ]; then
cat > docker-compose.prod.yml << 'EOF'
version: '3.8'
services:
web:
environment:
- DEBUG=False
- DJANGO_SETTINGS_MODULE=backend.settings
volumes:
- ./storage:/app/storage
- ./logs:/app/logs
restart: unless-stopped
frontend:
environment:
- NODE_ENV=production
- NEXT_TELEMETRY_DISABLED=1
restart: unless-stopped
db:
restart: unless-stopped
volumes:
- postgres_data:/var/lib/postgresql/data
- ./backups:/backups
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- ./storage:/var/www/storage:ro
- /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
- web
- frontend
restart: unless-stopped
volumes:
postgres_data:
EOF
print_success "docker-compose.prod.yml создан"
else
print_info "docker-compose.prod.yml уже существует"
fi
}
# Создание nginx конфигурации
create_nginx_config() {
print_header "Создание конфигурации Nginx"
if [ ! -f nginx.conf ]; then
cat > nginx.conf << 'EOF'
events {
worker_connections 1024;
}
http {
upstream backend {
server web:8000;
}
upstream frontend {
server frontend:3000;
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# HTTPS Server
server {
listen 443 ssl http2;
server_name _;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Frontend
location / {
proxy_pass http://frontend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Backend API
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Admin
location /admin/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Static files
location /storage/ {
alias /var/www/storage/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
}
EOF
print_success "nginx.conf создан"
else
print_info "nginx.conf уже существует"
fi
}
# Создание директорий
create_directories() {
print_header "Создание необходимых директорий"
directories=(
"storage"
"storage/avatars"
"storage/images"
"storage/images/links"
"storage/images/link_groups"
"storage/customization"
"backups"
"logs"
"ssl"
)
for dir in "${directories[@]}"; do
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
print_success "Создана директория: $dir"
else
print_info "Директория уже существует: $dir"
fi
done
# Установка прав доступа
chmod 755 storage
chmod -R 755 storage/
print_success "Права доступа установлены"
}
# Сборка и запуск контейнеров
build_and_start() {
print_header "Сборка и запуск контейнеров"
print_info "Остановка существующих контейнеров..."
docker-compose down 2>/dev/null || true
print_info "Сборка контейнеров..."
docker-compose build --no-cache
print_info "Запуск контейнеров..."
docker-compose up -d
print_info "Ожидание запуска сервисов..."
sleep 10
print_success "Контейнеры запущены"
}
# Инициализация базы данных
initialize_database() {
print_header "Инициализация базы данных"
print_info "Ожидание готовности базы данных..."
sleep 5
print_info "Выполнение миграций..."
docker-compose exec -T web python manage.py migrate
print_info "Сбор статических файлов..."
docker-compose exec -T web python manage.py collectstatic --noinput
print_success "База данных инициализирована"
}
# Создание суперпользователя
create_superuser() {
print_header "Создание суперпользователя"
echo ""
read -p "Создать суперпользователя? (Y/n): " create_user
if [[ ! $create_user =~ ^[Nn]$ ]]; then
print_info "Создание суперпользователя..."
docker-compose exec web python manage.py createsuperuser
print_success "Суперпользователь создан"
else
print_info "Пропуск создания суперпользователя"
print_info "Вы можете создать его позже командой: make superuser"
fi
}
# Проверка здоровья системы
health_check() {
print_header "Проверка здоровья системы"
print_info "Проверка frontend..."
if curl -s http://localhost:3000 > /dev/null; then
print_success "Frontend доступен: http://localhost:3000"
else
print_error "Frontend недоступен"
fi
print_info "Проверка backend..."
if curl -s http://localhost:8000 > /dev/null; then
print_success "Backend доступен: http://localhost:8000"
else
print_error "Backend недоступен"
fi
print_info "Проверка базы данных..."
if docker-compose exec -T db pg_isready -U links_user > /dev/null 2>&1; then
print_success "База данных готова"
else
print_error "База данных недоступна"
fi
}
# Создание документации
create_documentation() {
print_header "Создание документации"
if [ ! -f DEPLOYMENT.md ]; then
cat > DEPLOYMENT.md << 'EOF'
# CatLink Deployment Guide
## Быстрый старт
```bash
# Первый запуск
make install
# Режим разработки
make dev
# Продакшен
make deploy
```
## Полезные команды
```bash
# Статус сервисов
make status
# Логи
make logs
# Перезапуск
make restart
# Создание суперпользователя
make superuser
# Бэкап базы данных
make backup
# SSL настройка
make ssl
```
## Структура проекта
- `frontend/` - Next.js приложение
- `backend/` - Django API
- `storage/` - Загруженные файлы
- `backups/` - Бэкапы базы данных
- `logs/` - Логи приложения
## Продакшен
1. Настройте домен в `.env`
2. Запустите `make ssl` для настройки HTTPS
3. Используйте `make deploy` для развертывания
EOF
print_success "DEPLOYMENT.md создан"
else
print_info "DEPLOYMENT.md уже существует"
fi
}
# Финальный вывод
print_final_info() {
print_header "Установка завершена!"
echo ""
echo -e "${GREEN}🎉 CatLink успешно установлен!${NC}"
echo ""
echo -e "${BLUE}📱 Frontend:${NC} http://localhost:3000"
echo -e "${BLUE}🔧 Backend API:${NC} http://localhost:8000/api/"
echo -e "${BLUE}📊 Admin панель:${NC} http://localhost:8000/admin/"
echo ""
echo -e "${YELLOW}📚 Полезные команды:${NC}"
echo " make help - Все доступные команды"
echo " make status - Статус сервисов"
echo " make logs - Просмотр логов"
echo " make restart - Перезапуск"
echo " make superuser - Создать суперпользователя"
echo " make backup - Создать бэкап"
echo ""
echo -e "${BLUE}📖 Документация:${NC} DEPLOYMENT.md"
echo ""
}
# Основная функция
main() {
print_header "CatLink Setup Script v2.0"
# Проверка, что мы в правильной директории
if [ ! -f "docker-compose.yml" ]; then
print_error "docker-compose.yml не найден. Убедитесь, что вы в корневой директории проекта."
exit 1
fi
check_dependencies
create_env_file
create_production_config
create_nginx_config
create_directories
build_and_start
initialize_database
create_superuser
health_check
create_documentation
print_final_info
}
# Обработка ошибок
trap 'print_error "Произошла ошибка. Установка прервана."' ERR
# Запуск основной функции
main "$@"