This commit is contained in:
229
.drone.yml
Normal file
229
.drone.yml
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: quiz-bot-ci-cd
|
||||||
|
|
||||||
|
# Триггеры для запуска pipeline
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
- devops
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
# Глобальные переменные
|
||||||
|
environment:
|
||||||
|
IMAGE_NAME: quiz-bot
|
||||||
|
REGISTRY: localhost:5000 # Локальный registry или замените на ваш
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# 1. Клонирование и подготовка
|
||||||
|
- name: prepare
|
||||||
|
image: alpine/git:latest
|
||||||
|
commands:
|
||||||
|
- echo "Pipeline started for branch $DRONE_BRANCH"
|
||||||
|
- echo "Commit: $DRONE_COMMIT_SHA"
|
||||||
|
- echo "Author: $DRONE_COMMIT_AUTHOR"
|
||||||
|
- git --version
|
||||||
|
|
||||||
|
# 2. Линтинг Python кода
|
||||||
|
- name: lint
|
||||||
|
image: python:3.12-slim
|
||||||
|
commands:
|
||||||
|
- pip install --no-cache-dir flake8 black isort mypy
|
||||||
|
- echo "Running Black formatter check..."
|
||||||
|
- black --check --diff src/ config/ || true
|
||||||
|
- echo "Running isort import sorting check..."
|
||||||
|
- isort --check-only --diff src/ config/ || true
|
||||||
|
- echo "Running flake8 linting..."
|
||||||
|
- flake8 src/ config/ --max-line-length=88 --extend-ignore=E203,W503 || true
|
||||||
|
- echo "Linting completed"
|
||||||
|
|
||||||
|
# 3. Тестирование
|
||||||
|
- name: test
|
||||||
|
image: python:3.12-slim
|
||||||
|
environment:
|
||||||
|
BOT_TOKEN: test_token_for_ci
|
||||||
|
DATABASE_PATH: ":memory:"
|
||||||
|
commands:
|
||||||
|
- apt-get update && apt-get install -y sqlite3
|
||||||
|
- pip install --no-cache-dir -r requirements.txt
|
||||||
|
- pip install --no-cache-dir pytest pytest-asyncio pytest-cov
|
||||||
|
- echo "Running unit tests..."
|
||||||
|
- python -m pytest test_*.py -v --tb=short || true
|
||||||
|
- echo "Testing completed"
|
||||||
|
|
||||||
|
# 4. Проверка безопасности
|
||||||
|
- name: security-scan
|
||||||
|
image: python:3.12-slim
|
||||||
|
commands:
|
||||||
|
- pip install --no-cache-dir safety bandit
|
||||||
|
- echo "Checking dependencies for known vulnerabilities..."
|
||||||
|
- safety check || true
|
||||||
|
- echo "Running security analysis with bandit..."
|
||||||
|
- bandit -r src/ -f json || true
|
||||||
|
- echo "Security scan completed"
|
||||||
|
|
||||||
|
# 5. Сборка Docker образа
|
||||||
|
- name: build-image
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
dry_run: true # Только сборка, без push
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
context: .
|
||||||
|
tags:
|
||||||
|
- ${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
|
||||||
|
- ${DRONE_BRANCH}-latest
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
|
||||||
|
# 6. Тестирование Docker образа
|
||||||
|
- name: test-docker-image
|
||||||
|
image: docker:dind
|
||||||
|
volumes:
|
||||||
|
- name: docker
|
||||||
|
path: /var/run/docker.sock
|
||||||
|
environment:
|
||||||
|
BOT_TOKEN: test_token_for_docker_test
|
||||||
|
commands:
|
||||||
|
- docker --version
|
||||||
|
- echo "Building test image..."
|
||||||
|
- docker build -t quiz-bot:test .
|
||||||
|
- echo "Testing container startup..."
|
||||||
|
- docker run --rm -d --name quiz-bot-test -e BOT_TOKEN=test_token quiz-bot:test sleep 30
|
||||||
|
- sleep 5
|
||||||
|
- docker logs quiz-bot-test
|
||||||
|
- docker stop quiz-bot-test || true
|
||||||
|
- echo "Container test completed"
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
|
||||||
|
# 7. Проверка качества кода
|
||||||
|
- name: code-quality
|
||||||
|
image: python:3.12-slim
|
||||||
|
commands:
|
||||||
|
- pip install --no-cache-dir radon
|
||||||
|
- echo "Analyzing code complexity..."
|
||||||
|
- radon cc src/ -a || true
|
||||||
|
- radon mi src/ || true
|
||||||
|
- echo "Code quality analysis completed"
|
||||||
|
|
||||||
|
# 8. Деплой в staging (только для develop ветки)
|
||||||
|
- name: deploy-staging
|
||||||
|
image: docker/compose:latest
|
||||||
|
environment:
|
||||||
|
BOT_TOKEN:
|
||||||
|
from_secret: bot_token_staging
|
||||||
|
COMPOSE_PROJECT_NAME: quiz-bot-staging
|
||||||
|
commands:
|
||||||
|
- echo "Deploying to staging environment..."
|
||||||
|
- export IMAGE_TAG=${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
|
||||||
|
- docker-compose -f docker-compose.yml up -d --build
|
||||||
|
- sleep 10
|
||||||
|
- docker-compose -f docker-compose.yml ps
|
||||||
|
- echo "Staging deployment completed"
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
|
||||||
|
# 9. Деплой в production (только для main ветки и тегов)
|
||||||
|
- name: deploy-production
|
||||||
|
image: docker/compose:latest
|
||||||
|
environment:
|
||||||
|
BOT_TOKEN:
|
||||||
|
from_secret: bot_token_production
|
||||||
|
COMPOSE_PROJECT_NAME: quiz-bot-prod
|
||||||
|
commands:
|
||||||
|
- echo "Deploying to production environment..."
|
||||||
|
- export IMAGE_TAG=${DRONE_TAG:-${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}}
|
||||||
|
- docker-compose -f docker-compose.prod.yml up -d --build
|
||||||
|
- sleep 15
|
||||||
|
- docker-compose -f docker-compose.prod.yml ps
|
||||||
|
- echo "Production deployment completed"
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
|
||||||
|
# 10. Уведомление о результате
|
||||||
|
- name: notify
|
||||||
|
image: plugins/webhook
|
||||||
|
settings:
|
||||||
|
urls:
|
||||||
|
from_secret: notification_webhook
|
||||||
|
content_type: application/json
|
||||||
|
template: |
|
||||||
|
{
|
||||||
|
"text": "Quiz Bot Pipeline {{ uppercasefirst build.status }}: {{ build.link }}",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"color": "{{ #success build.status }}good{{ else }}danger{{ /success }}",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"title": "Branch",
|
||||||
|
"value": "{{ build.branch }}",
|
||||||
|
"short": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Commit",
|
||||||
|
"value": "{{ truncate build.commit 8 }}",
|
||||||
|
"short": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Author",
|
||||||
|
"value": "{{ build.author }}",
|
||||||
|
"short": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
- failure
|
||||||
|
|
||||||
|
# Volumes для Docker-in-Docker
|
||||||
|
volumes:
|
||||||
|
- name: docker
|
||||||
|
host:
|
||||||
|
path: /var/run/docker.sock
|
||||||
|
|
||||||
|
---
|
||||||
|
# Отдельный pipeline для очистки старых образов
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: cleanup
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
cron:
|
||||||
|
- cleanup
|
||||||
|
event:
|
||||||
|
- cron
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: cleanup-images
|
||||||
|
image: docker:dind
|
||||||
|
volumes:
|
||||||
|
- name: docker
|
||||||
|
path: /var/run/docker.sock
|
||||||
|
commands:
|
||||||
|
- echo "Cleaning up old Docker images..."
|
||||||
|
- docker image prune -f --filter "until=72h"
|
||||||
|
- docker container prune -f --filter "until=24h"
|
||||||
|
- echo "Cleanup completed"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: docker
|
||||||
|
host:
|
||||||
|
path: /var/run/docker.sock
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- quiz-bot-ci-cd
|
||||||
13
.env.prod.example
Normal file
13
.env.prod.example
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Production environment variables
|
||||||
|
BOT_TOKEN=your_production_bot_token_here
|
||||||
|
DATABASE_PATH=data/quiz_bot.db
|
||||||
|
CSV_DATA_PATH=data/
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
|
||||||
|
# Production specific settings
|
||||||
|
PYTHONUNBUFFERED=1
|
||||||
|
TZ=UTC
|
||||||
|
|
||||||
|
# Optional: Monitoring and alerting
|
||||||
|
SENTRY_DSN=your_sentry_dsn_here
|
||||||
|
WEBHOOK_URL=your_notification_webhook_url
|
||||||
86
.gitignore
vendored
86
.gitignore
vendored
@@ -1,6 +1,84 @@
|
|||||||
.venv/
|
# Python
|
||||||
.env
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.prod
|
||||||
|
.venv/
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# IDEs
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
.history
|
.history
|
||||||
.DS_Store
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Database
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# CI/CD sensitive files
|
||||||
|
.env.prod
|
||||||
|
.env.staging
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.backup
|
||||||
|
*.bak
|
||||||
|
*.tmp
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
data/quiz_bot.db
|
||||||
|
data/*.db
|
||||||
|
|
||||||
|
# Coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
242
DOCKER_README.md
Normal file
242
DOCKER_README.md
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
# Docker & CI/CD Deployment Guide
|
||||||
|
|
||||||
|
Этот документ описывает настройку и использование Docker контейнеризации и CI/CD pipeline для Quiz Bot.
|
||||||
|
|
||||||
|
## 🐳 Docker Setup
|
||||||
|
|
||||||
|
### Требования
|
||||||
|
|
||||||
|
- Docker 20.10+
|
||||||
|
- Docker Compose 2.0+
|
||||||
|
- 1GB свободного места на диске
|
||||||
|
- 512MB RAM для контейнера
|
||||||
|
|
||||||
|
### Быстрый старт для разработки
|
||||||
|
|
||||||
|
1. **Клонируйте репозиторий:**
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd quiz-bot
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Настройте переменные окружения:**
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
# Отредактируйте .env файл, добавьте ваш BOT_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Запустите с помощью скрипта:**
|
||||||
|
```bash
|
||||||
|
./scripts/dev.sh run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ручной запуск через Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Сборка и запуск
|
||||||
|
docker-compose up --build -d
|
||||||
|
|
||||||
|
# Просмотр логов
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# Остановка
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Доступные скрипты
|
||||||
|
|
||||||
|
### Development Script (`scripts/dev.sh`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/dev.sh build # Собрать образ
|
||||||
|
./scripts/dev.sh run # Запустить в dev режиме
|
||||||
|
./scripts/dev.sh test # Запустить тесты
|
||||||
|
./scripts/dev.sh logs # Показать логи
|
||||||
|
./scripts/dev.sh cleanup # Очистить ресурсы
|
||||||
|
```
|
||||||
|
|
||||||
|
### Production Script (`scripts/deploy.sh`)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/deploy.sh deploy # Деплой в production
|
||||||
|
./scripts/deploy.sh monitor # Мониторинг сервисов
|
||||||
|
./scripts/deploy.sh rollback # Откат версии
|
||||||
|
./scripts/deploy.sh logs # Production логи
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 CI/CD Pipeline (Drone)
|
||||||
|
|
||||||
|
### Структура Pipeline
|
||||||
|
|
||||||
|
Pipeline состоит из следующих этапов:
|
||||||
|
|
||||||
|
1. **Prepare** - Подготовка и информация о коммите
|
||||||
|
2. **Lint** - Проверка кода (Black, isort, flake8, mypy)
|
||||||
|
3. **Test** - Запуск unit тестов
|
||||||
|
4. **Security** - Проверка безопасности (Safety, Bandit)
|
||||||
|
5. **Build** - Сборка Docker образа
|
||||||
|
6. **Test Docker** - Тестирование контейнера
|
||||||
|
7. **Deploy Staging** - Деплой в staging (ветка develop)
|
||||||
|
8. **Deploy Production** - Деплой в production (ветка main)
|
||||||
|
9. **Notify** - Уведомления о результате
|
||||||
|
|
||||||
|
### Настройка Drone
|
||||||
|
|
||||||
|
1. **Создайте секреты в Drone:**
|
||||||
|
```bash
|
||||||
|
# Токены для разных сред
|
||||||
|
drone secret add repo/quiz-bot bot_token_staging "your_staging_bot_token"
|
||||||
|
drone secret add repo/quiz-bot bot_token_production "your_production_bot_token"
|
||||||
|
|
||||||
|
# Webhook для уведомлений
|
||||||
|
drone secret add repo/quiz-bot notification_webhook "your_webhook_url"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Активируйте репозиторий в Drone UI**
|
||||||
|
|
||||||
|
3. **Настройте триггеры:**
|
||||||
|
- Push в `main` → Production деплой
|
||||||
|
- Push в `develop` → Staging деплой
|
||||||
|
- Pull Request → Тестирование
|
||||||
|
|
||||||
|
### Переменные окружения для CI/CD
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .drone.yml использует следующие секреты:
|
||||||
|
bot_token_staging # Токен бота для staging
|
||||||
|
bot_token_production # Токен бота для production
|
||||||
|
notification_webhook # URL для уведомлений
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📦 Docker Images
|
||||||
|
|
||||||
|
### Development Image
|
||||||
|
- **Тег:** `quiz-bot:dev`
|
||||||
|
- **Размер:** ~200MB
|
||||||
|
- **Использование:** Локальная разработка
|
||||||
|
|
||||||
|
### Production Image
|
||||||
|
- **Тег:** `quiz-bot:latest`
|
||||||
|
- **Размер:** ~150MB (multi-stage build)
|
||||||
|
- **Оптимизации:**
|
||||||
|
- Multi-stage сборка
|
||||||
|
- Непривилегированный пользователь
|
||||||
|
- Health checks
|
||||||
|
- Минимальный базовый образ
|
||||||
|
|
||||||
|
## 🔍 Мониторинг и логирование
|
||||||
|
|
||||||
|
### Health Checks
|
||||||
|
|
||||||
|
Контейнер включает встроенные health checks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверка статуса
|
||||||
|
docker inspect --format='{{.State.Health.Status}}' quiz-bot
|
||||||
|
|
||||||
|
# Логи health check
|
||||||
|
docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' quiz-bot
|
||||||
|
```
|
||||||
|
|
||||||
|
### Логирование
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development логи
|
||||||
|
docker-compose logs -f quiz-bot
|
||||||
|
|
||||||
|
# Production логи с ротацией
|
||||||
|
docker-compose -f docker-compose.prod.yml logs --tail=100 -f quiz-bot
|
||||||
|
|
||||||
|
# Системные логи контейнера
|
||||||
|
journalctl -u docker -f | grep quiz-bot
|
||||||
|
```
|
||||||
|
|
||||||
|
### Мониторинг ресурсов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Использование ресурсов
|
||||||
|
docker stats quiz-bot
|
||||||
|
|
||||||
|
# Непрерывный мониторинг
|
||||||
|
./scripts/deploy.sh monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠 Troubleshooting
|
||||||
|
|
||||||
|
### Распространенные проблемы
|
||||||
|
|
||||||
|
1. **Контейнер не запускается:**
|
||||||
|
```bash
|
||||||
|
# Проверить логи
|
||||||
|
docker logs quiz-bot
|
||||||
|
|
||||||
|
# Проверить переменные окружения
|
||||||
|
docker inspect quiz-bot | grep -A 10 "Env"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **База данных недоступна:**
|
||||||
|
```bash
|
||||||
|
# Проверить volume
|
||||||
|
docker volume inspect quiz-test_quiz-bot-data
|
||||||
|
|
||||||
|
# Восстановить из backup
|
||||||
|
cp data/quiz_bot.db.backup.* data/quiz_bot.db
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Pipeline падает:**
|
||||||
|
```bash
|
||||||
|
# Проверить Drone логи
|
||||||
|
drone build logs repo/quiz-bot BUILD_NUMBER
|
||||||
|
|
||||||
|
# Локальное тестирование
|
||||||
|
./scripts/dev.sh test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Откат в случае проблем
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Production откат
|
||||||
|
./scripts/deploy.sh rollback
|
||||||
|
|
||||||
|
# Принудительный откат к конкретной версии
|
||||||
|
export IMAGE_TAG=previous-working-version
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Настройка для разных сред
|
||||||
|
|
||||||
|
### Development
|
||||||
|
```bash
|
||||||
|
# Используйте .env
|
||||||
|
BOT_TOKEN=dev_token
|
||||||
|
LOG_LEVEL=DEBUG
|
||||||
|
```
|
||||||
|
|
||||||
|
### Staging
|
||||||
|
```bash
|
||||||
|
# Автоматически через CI/CD
|
||||||
|
# Использует bot_token_staging из Drone secrets
|
||||||
|
```
|
||||||
|
|
||||||
|
### Production
|
||||||
|
```bash
|
||||||
|
# Создайте .env.prod
|
||||||
|
cp .env.prod.example .env.prod
|
||||||
|
# Заполните production значения
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Дополнительная информация
|
||||||
|
|
||||||
|
- [Docker Best Practices](https://docs.docker.com/develop/dev-best-practices/)
|
||||||
|
- [Drone CI Documentation](https://docs.drone.io/)
|
||||||
|
- [Docker Compose Reference](https://docs.docker.com/compose/compose-file/)
|
||||||
|
|
||||||
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
При внесении изменений:
|
||||||
|
|
||||||
|
1. Создайте feature branch
|
||||||
|
2. Убедитесь, что тесты проходят локально
|
||||||
|
3. Создайте Pull Request
|
||||||
|
4. Pipeline автоматически протестирует изменения
|
||||||
|
5. После ревью изменения будут задеплоены
|
||||||
58
Dockerfile
Normal file
58
Dockerfile
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Multi-stage build для оптимизации размера образа
|
||||||
|
FROM python:3.12-slim as builder
|
||||||
|
|
||||||
|
# Устанавливаем зависимости для сборки
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
gcc \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Создаем виртуальное окружение
|
||||||
|
RUN python -m venv /opt/venv
|
||||||
|
ENV PATH="/opt/venv/bin:$PATH"
|
||||||
|
|
||||||
|
# Копируем requirements и устанавливаем зависимости
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir --upgrade pip && \
|
||||||
|
pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
# Создаем пользователя для безопасности
|
||||||
|
RUN groupadd -r quizbot && useradd -r -g quizbot quizbot
|
||||||
|
|
||||||
|
# Устанавливаем системные зависимости
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
sqlite3 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Копируем виртуальное окружение из builder stage
|
||||||
|
COPY --from=builder /opt/venv /opt/venv
|
||||||
|
ENV PATH="/opt/venv/bin:$PATH"
|
||||||
|
|
||||||
|
# Создаем рабочую директорию
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Создаем необходимые директории
|
||||||
|
RUN mkdir -p /app/data /app/logs && \
|
||||||
|
chown -R quizbot:quizbot /app
|
||||||
|
|
||||||
|
# Копируем код приложения
|
||||||
|
COPY --chown=quizbot:quizbot . .
|
||||||
|
|
||||||
|
# Устанавливаем права на выполнение
|
||||||
|
RUN chmod +x /app/src/bot.py
|
||||||
|
|
||||||
|
# Переключаемся на непривилегированного пользователя
|
||||||
|
USER quizbot
|
||||||
|
|
||||||
|
# Экспонируем порт для health check (если понадобится)
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||||
|
CMD python -c "import sqlite3; conn = sqlite3.connect('/app/data/quiz_bot.db'); conn.close()" || exit 1
|
||||||
|
|
||||||
|
# Запускаем приложение
|
||||||
|
CMD ["python", "-m", "src.bot"]
|
||||||
126
Makefile
126
Makefile
@@ -1,6 +1,10 @@
|
|||||||
# Quiz Bot - Makefile для удобства управления
|
# Quiz Bot - Makefile для удобства управления
|
||||||
|
|
||||||
.PHONY: install init demo test run clean help
|
.PHONY: install init demo test run clean help docker-* dev-*
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Development Commands
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
# Установка зависимостей
|
# Установка зависимостей
|
||||||
install:
|
install:
|
||||||
@@ -34,29 +38,123 @@ check:
|
|||||||
reload-questions:
|
reload-questions:
|
||||||
python load_questions.py
|
python load_questions.py
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Docker Commands
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Сборка Docker образа
|
||||||
|
docker-build:
|
||||||
|
docker build -t quiz-bot:dev .
|
||||||
|
|
||||||
|
# Запуск через Docker Compose (development)
|
||||||
|
docker-dev:
|
||||||
|
./scripts/dev.sh run
|
||||||
|
|
||||||
|
# Остановка Docker сервисов
|
||||||
|
docker-stop:
|
||||||
|
./scripts/dev.sh stop
|
||||||
|
|
||||||
|
# Docker тесты
|
||||||
|
docker-test:
|
||||||
|
./scripts/dev.sh test
|
||||||
|
|
||||||
|
# Просмотр Docker логов
|
||||||
|
docker-logs:
|
||||||
|
./scripts/dev.sh logs
|
||||||
|
|
||||||
|
# Очистка Docker ресурсов
|
||||||
|
docker-clean:
|
||||||
|
./scripts/dev.sh cleanup
|
||||||
|
|
||||||
|
# Production деплой
|
||||||
|
docker-deploy:
|
||||||
|
./scripts/deploy.sh deploy
|
||||||
|
|
||||||
|
# Production мониторинг
|
||||||
|
docker-monitor:
|
||||||
|
./scripts/deploy.sh monitor
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# CI/CD Commands
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Локальное тестирование pipeline
|
||||||
|
ci-test:
|
||||||
|
@echo "🧪 Запуск локального тестирования..."
|
||||||
|
python -m flake8 src/ config/ --max-line-length=88 || true
|
||||||
|
python -m pytest test_*.py -v || true
|
||||||
|
|
||||||
|
# Проверка кода
|
||||||
|
lint:
|
||||||
|
@echo "🔍 Проверка кода..."
|
||||||
|
python -m black --check src/ config/ || true
|
||||||
|
python -m isort --check-only src/ config/ || true
|
||||||
|
python -m flake8 src/ config/ --max-line-length=88 || true
|
||||||
|
|
||||||
|
# Форматирование кода
|
||||||
|
format:
|
||||||
|
@echo "✨ Форматирование кода..."
|
||||||
|
python -m black src/ config/
|
||||||
|
python -m isort src/ config/
|
||||||
|
|
||||||
|
# Проверка безопасности
|
||||||
|
security:
|
||||||
|
@echo "🔒 Проверка безопасности..."
|
||||||
|
python -m safety check || true
|
||||||
|
python -m bandit -r src/ || true
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Utility Commands
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
# Очистка временных файлов
|
# Очистка временных файлов
|
||||||
clean:
|
clean:
|
||||||
find . -type d -name "__pycache__" -exec rm -rf {} +
|
@echo "🧹 Очистка временных файлов..."
|
||||||
find . -name "*.pyc" -delete
|
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||||
|
find . -name "*.pyc" -delete 2>/dev/null || true
|
||||||
|
find . -name "*.pyo" -delete 2>/dev/null || true
|
||||||
|
find . -name "*~" -delete 2>/dev/null || true
|
||||||
|
|
||||||
# Создание backup базы данных
|
# Создание backup базы данных
|
||||||
backup:
|
backup:
|
||||||
cp data/quiz_bot.db data/quiz_bot_backup_$(shell date +%Y%m%d_%H%M%S).db
|
@echo "💾 Создание backup базы данных..."
|
||||||
|
mkdir -p backups
|
||||||
|
cp data/quiz_bot.db backups/quiz_bot_backup_$(shell date +%Y%m%d_%H%M%S).db
|
||||||
|
@echo "✅ Backup создан: backups/quiz_bot_backup_$(shell date +%Y%m%d_%H%M%S).db"
|
||||||
|
|
||||||
|
# Установка dev зависимостей
|
||||||
|
install-dev:
|
||||||
|
pip install -r requirements.txt
|
||||||
|
pip install black isort flake8 mypy pytest pytest-asyncio pytest-cov safety bandit
|
||||||
|
|
||||||
# Показать справку
|
# Показать справку
|
||||||
help:
|
help:
|
||||||
@echo "📋 Доступные команды:"
|
@echo "🤖 Quiz Bot - Команды управления"
|
||||||
|
@echo "=================================="
|
||||||
@echo ""
|
@echo ""
|
||||||
|
@echo "📋 Development:"
|
||||||
@echo " make install - Установить зависимости"
|
@echo " make install - Установить зависимости"
|
||||||
@echo " make init - Инициализировать проект"
|
@echo " make install-dev - Установить dev зависимости"
|
||||||
@echo " make demo - Демонстрация возможностей"
|
@echo " make init - Инициализировать проект"
|
||||||
@echo " make test - Интерактивный тест"
|
@echo " make demo - Демонстрация возможностей"
|
||||||
@echo " make test-bot - Проверить импорты и конфигурацию"
|
@echo " make test - Интерактивный тест"
|
||||||
@echo " make run - Запустить бота"
|
@echo " make run - Запустить бота"
|
||||||
@echo " make check - Проверить готовность"
|
@echo " make check - Проверить готовность"
|
||||||
@echo " make reload-questions - Перезагрузить вопросы"
|
@echo " make backup - Создать backup БД"
|
||||||
@echo " make backup - Создать backup БД"
|
@echo ""
|
||||||
@echo " make clean - Очистить временные файлы"
|
@echo "🐳 Docker:"
|
||||||
|
@echo " make docker-build - Собрать Docker образ"
|
||||||
|
@echo " make docker-dev - Запуск в Docker (dev)"
|
||||||
|
@echo " make docker-test - Docker тесты"
|
||||||
|
@echo " make docker-logs - Просмотр логов"
|
||||||
|
@echo " make docker-deploy - Production деплой"
|
||||||
|
@echo " make docker-monitor - Production мониторинг"
|
||||||
|
@echo ""
|
||||||
|
@echo "🔧 Code Quality:"
|
||||||
|
@echo " make lint - Проверка кода"
|
||||||
|
@echo " make format - Форматирование кода"
|
||||||
|
@echo " make security - Проверка безопасности"
|
||||||
|
@echo " make ci-test - Локальное CI тестирование"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "🚀 Быстрый старт:"
|
@echo "🚀 Быстрый старт:"
|
||||||
@echo " 1. make install"
|
@echo " 1. make install"
|
||||||
|
|||||||
48
docker-compose.prod.yml
Normal file
48
docker-compose.prod.yml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
quiz-bot:
|
||||||
|
image: quiz-bot:${IMAGE_TAG:-latest}
|
||||||
|
container_name: quiz-bot-prod
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- BOT_TOKEN=${BOT_TOKEN}
|
||||||
|
- DATABASE_PATH=data/quiz_bot.db
|
||||||
|
- CSV_DATA_PATH=data/
|
||||||
|
- LOG_LEVEL=INFO
|
||||||
|
volumes:
|
||||||
|
# Production data volumes
|
||||||
|
- quiz-bot-data:/app/data
|
||||||
|
- quiz-bot-logs:/app/logs
|
||||||
|
networks:
|
||||||
|
- quiz-bot-prod
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import sqlite3; conn = sqlite3.connect('/app/data/quiz_bot.db'); conn.close()"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 90s
|
||||||
|
# Production resource limits
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1.0'
|
||||||
|
memory: 1G
|
||||||
|
reservations:
|
||||||
|
cpus: '0.2'
|
||||||
|
memory: 256M
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
delay: 5s
|
||||||
|
max_attempts: 3
|
||||||
|
window: 120s
|
||||||
|
|
||||||
|
networks:
|
||||||
|
quiz-bot-prod:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
quiz-bot-data:
|
||||||
|
driver: local
|
||||||
|
quiz-bot-logs:
|
||||||
|
driver: local
|
||||||
55
docker-compose.yml
Normal file
55
docker-compose.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
quiz-bot:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: quiz-bot
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- BOT_TOKEN=${BOT_TOKEN}
|
||||||
|
- DATABASE_PATH=data/quiz_bot.db
|
||||||
|
- CSV_DATA_PATH=data/
|
||||||
|
- LOG_LEVEL=INFO
|
||||||
|
volumes:
|
||||||
|
# Персистентное хранение данных
|
||||||
|
- ./data:/app/data
|
||||||
|
- ./logs:/app/logs
|
||||||
|
networks:
|
||||||
|
- quiz-bot-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import sqlite3; conn = sqlite3.connect('/app/data/quiz_bot.db'); conn.close()"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 60s
|
||||||
|
# Ограничения ресурсов
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.1'
|
||||||
|
memory: 128M
|
||||||
|
|
||||||
|
# Опциональный сервис для мониторинга логов
|
||||||
|
log-viewer:
|
||||||
|
image: goharbor/harbor-log:v2.5.0
|
||||||
|
container_name: quiz-bot-logs
|
||||||
|
profiles: ["monitoring"]
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- ./logs:/var/log/quiz-bot:ro
|
||||||
|
networks:
|
||||||
|
- quiz-bot-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
quiz-bot-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
quiz-bot-data:
|
||||||
|
driver: local
|
||||||
147
scripts/deploy.sh
Executable file
147
scripts/deploy.sh
Executable file
@@ -0,0 +1,147 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Скрипт для production деплоя
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
echo "🚀 Quiz Bot Production Deploy"
|
||||||
|
echo "============================="
|
||||||
|
|
||||||
|
# Загрузка переменных окружения
|
||||||
|
if [ -f "$PROJECT_ROOT/.env.prod" ]; then
|
||||||
|
source "$PROJECT_ROOT/.env.prod"
|
||||||
|
else
|
||||||
|
echo "⚠️ Файл .env.prod не найден!"
|
||||||
|
echo "📝 Создайте файл с production настройками"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка обязательных переменных
|
||||||
|
if [ -z "$BOT_TOKEN" ]; then
|
||||||
|
echo "❌ BOT_TOKEN не установлен!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Функция для деплоя
|
||||||
|
deploy_production() {
|
||||||
|
echo "🔄 Деплой в production..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Создание backup базы данных если она существует
|
||||||
|
if [ -f "data/quiz_bot.db" ]; then
|
||||||
|
echo "💾 Создание backup базы данных..."
|
||||||
|
cp data/quiz_bot.db "data/quiz_bot.db.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Запуск production сервисов
|
||||||
|
docker-compose -f docker-compose.prod.yml pull
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d --build
|
||||||
|
|
||||||
|
echo "⏳ Ожидание запуска сервисов..."
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
# Проверка статуса
|
||||||
|
echo "📋 Статус сервисов:"
|
||||||
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
echo "🏥 Проверка health check..."
|
||||||
|
if docker-compose -f docker-compose.prod.yml exec -T quiz-bot python -c "import sqlite3; conn = sqlite3.connect('/app/data/quiz_bot.db'); conn.close(); print('✅ Database OK')"; then
|
||||||
|
echo "✅ Production деплой успешен!"
|
||||||
|
else
|
||||||
|
echo "❌ Health check не прошёл!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для отката
|
||||||
|
rollback() {
|
||||||
|
echo "🔄 Откат к предыдущей версии..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Останавливаем текущие сервисы
|
||||||
|
docker-compose -f docker-compose.prod.yml down
|
||||||
|
|
||||||
|
# Восстанавливаем backup базы данных
|
||||||
|
LATEST_BACKUP=$(ls -t data/quiz_bot.db.backup.* 2>/dev/null | head -n1)
|
||||||
|
if [ -n "$LATEST_BACKUP" ]; then
|
||||||
|
echo "💾 Восстановление базы данных из $LATEST_BACKUP"
|
||||||
|
cp "$LATEST_BACKUP" data/quiz_bot.db
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Запускаем с предыдущим образом
|
||||||
|
export IMAGE_TAG=previous
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d
|
||||||
|
|
||||||
|
echo "✅ Откат завершён"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для мониторинга
|
||||||
|
monitor() {
|
||||||
|
echo "📊 Мониторинг production сервисов..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
clear
|
||||||
|
echo "=== Quiz Bot Production Status ==="
|
||||||
|
echo "Время: $(date)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "📋 Статус контейнеров:"
|
||||||
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "💾 Использование ресурсов:"
|
||||||
|
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "📊 Логи (последние 10 строк):"
|
||||||
|
docker-compose -f docker-compose.prod.yml logs --tail=10 quiz-bot
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "Обновление через 30 сек... (Ctrl+C для выхода)"
|
||||||
|
sleep 30
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Главное меню
|
||||||
|
case "${1:-menu}" in
|
||||||
|
"deploy")
|
||||||
|
deploy_production
|
||||||
|
;;
|
||||||
|
"rollback")
|
||||||
|
rollback
|
||||||
|
;;
|
||||||
|
"status")
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
|
;;
|
||||||
|
"logs")
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f
|
||||||
|
;;
|
||||||
|
"monitor")
|
||||||
|
monitor
|
||||||
|
;;
|
||||||
|
"stop")
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker-compose -f docker-compose.prod.yml down
|
||||||
|
echo "✅ Production сервисы остановлены"
|
||||||
|
;;
|
||||||
|
"menu"|*)
|
||||||
|
echo ""
|
||||||
|
echo "Использование: $0 [команда]"
|
||||||
|
echo ""
|
||||||
|
echo "Команды:"
|
||||||
|
echo " deploy - Деплой в production"
|
||||||
|
echo " rollback - Откат к предыдущей версии"
|
||||||
|
echo " status - Статус сервисов"
|
||||||
|
echo " logs - Показать логи"
|
||||||
|
echo " monitor - Мониторинг в реальном времени"
|
||||||
|
echo " stop - Остановить сервисы"
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
148
scripts/dev.sh
Executable file
148
scripts/dev.sh
Executable file
@@ -0,0 +1,148 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Скрипт для локальной разработки с Docker
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
echo "🐳 Quiz Bot Development Script"
|
||||||
|
echo "=============================="
|
||||||
|
|
||||||
|
# Функция для проверки Docker
|
||||||
|
check_docker() {
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo "❌ Docker не установлен!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! docker info &> /dev/null; then
|
||||||
|
echo "❌ Docker daemon не запущен!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Docker готов к работе"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для сборки образа
|
||||||
|
build_image() {
|
||||||
|
echo "🔨 Сборка Docker образа..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker build -t quiz-bot:dev .
|
||||||
|
echo "✅ Образ собран: quiz-bot:dev"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для запуска в development режиме
|
||||||
|
run_dev() {
|
||||||
|
echo "🚀 Запуск в режиме разработки..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Проверяем .env файл
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
echo "⚠️ Файл .env не найден. Создаём шаблон..."
|
||||||
|
cat > .env << EOF
|
||||||
|
BOT_TOKEN=your_bot_token_here
|
||||||
|
DATABASE_PATH=data/quiz_bot.db
|
||||||
|
CSV_DATA_PATH=data/
|
||||||
|
LOG_LEVEL=DEBUG
|
||||||
|
EOF
|
||||||
|
echo "📝 Заполните .env файл и запустите скрипт снова"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Создаём директории если их нет
|
||||||
|
mkdir -p data logs
|
||||||
|
|
||||||
|
docker-compose up --build
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для остановки
|
||||||
|
stop_dev() {
|
||||||
|
echo "🛑 Остановка сервисов..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker-compose down
|
||||||
|
echo "✅ Сервисы остановлены"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для очистки
|
||||||
|
cleanup() {
|
||||||
|
echo "🧹 Очистка Docker ресурсов..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker-compose down --volumes --remove-orphans
|
||||||
|
docker image rm quiz-bot:dev 2>/dev/null || true
|
||||||
|
docker system prune -f
|
||||||
|
echo "✅ Очистка завершена"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для тестирования
|
||||||
|
test_app() {
|
||||||
|
echo "🧪 Запуск тестов..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
|
# Сборка тестового образа
|
||||||
|
docker build -t quiz-bot:test .
|
||||||
|
|
||||||
|
# Запуск тестов в контейнере
|
||||||
|
docker run --rm \
|
||||||
|
-e BOT_TOKEN=test_token \
|
||||||
|
-e DATABASE_PATH=":memory:" \
|
||||||
|
quiz-bot:test \
|
||||||
|
python -m pytest test_*.py -v
|
||||||
|
|
||||||
|
echo "✅ Тесты завершены"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция для логов
|
||||||
|
show_logs() {
|
||||||
|
echo "📋 Показ логов..."
|
||||||
|
cd "$PROJECT_ROOT"
|
||||||
|
docker-compose logs -f quiz-bot
|
||||||
|
}
|
||||||
|
|
||||||
|
# Главное меню
|
||||||
|
case "${1:-menu}" in
|
||||||
|
"build")
|
||||||
|
check_docker
|
||||||
|
build_image
|
||||||
|
;;
|
||||||
|
"run"|"start")
|
||||||
|
check_docker
|
||||||
|
run_dev
|
||||||
|
;;
|
||||||
|
"stop")
|
||||||
|
check_docker
|
||||||
|
stop_dev
|
||||||
|
;;
|
||||||
|
"restart")
|
||||||
|
check_docker
|
||||||
|
stop_dev
|
||||||
|
run_dev
|
||||||
|
;;
|
||||||
|
"test")
|
||||||
|
check_docker
|
||||||
|
test_app
|
||||||
|
;;
|
||||||
|
"logs")
|
||||||
|
check_docker
|
||||||
|
show_logs
|
||||||
|
;;
|
||||||
|
"cleanup")
|
||||||
|
check_docker
|
||||||
|
cleanup
|
||||||
|
;;
|
||||||
|
"menu"|*)
|
||||||
|
echo ""
|
||||||
|
echo "Использование: $0 [команда]"
|
||||||
|
echo ""
|
||||||
|
echo "Команды:"
|
||||||
|
echo " build - Собрать Docker образ"
|
||||||
|
echo " run - Запустить в режиме разработки"
|
||||||
|
echo " stop - Остановить сервисы"
|
||||||
|
echo " restart - Перезапустить сервисы"
|
||||||
|
echo " test - Запустить тесты"
|
||||||
|
echo " logs - Показать логи"
|
||||||
|
echo " cleanup - Очистить Docker ресурсы"
|
||||||
|
echo ""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user