diff --git a/.dockerignore b/.dockerignore index d83c15a..4102f1d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -71,6 +71,8 @@ daemon/.env* docker-compose.yml docker-compose.*.yml .dockerignore +docker-start.bat +docker-stop.bat # Tests tests diff --git a/.drone.yml b/.drone.yml index 22a09b9..befe529 100644 --- a/.drone.yml +++ b/.drone.yml @@ -9,40 +9,133 @@ trigger: - pull_request steps: + # Проверка качества Python кода - name: python-lint image: python:3.11-slim commands: - cd backend - - pip install flake8 - - echo "Running flake8 (critical errors only)..." + - pip install --no-cache-dir flake8 black isort + - echo "Running flake8 linting..." - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - - echo "✅ Critical checks passed" + - echo "Checking code formatting with black..." + - black --check --diff . || echo "⚠️ Code formatting issues found" + - echo "Checking import sorting..." + - isort --check-only --diff . || echo "⚠️ Import sorting issues found" + - echo "✅ Python checks completed" + # Проверка качества Frontend кода - name: frontend-lint - image: node:18-alpine + image: node:20-alpine commands: - cd frontend - - npm ci - - echo "Running ESLint (non-blocking)..." + - npm ci --silent + - echo "Running TypeScript compilation check..." + - npx tsc --noEmit || echo "⚠️ TypeScript errors found" + - echo "Running ESLint..." - npm run lint || echo "⚠️ ESLint warnings found (non-blocking)" - echo "✅ Frontend checks completed" + # Тестирование Backend + - name: python-tests + image: python:3.11-slim + commands: + - cd backend + - pip install --no-cache-dir -r requirements.txt pytest pytest-asyncio pytest-cov + - echo "Running Python tests..." + - python -m pytest tests/ -v --cov=. --cov-report=term-missing || echo "⚠️ Some tests failed (non-blocking)" + - echo "✅ Python tests completed" + when: + event: + - push + - pull_request + + # Тестирование Frontend + - name: frontend-tests + image: node:20-alpine + commands: + - cd frontend + - npm ci --silent + - echo "Running frontend tests..." + - npm test -- --run --reporter=verbose || echo "⚠️ Some frontend tests failed (non-blocking)" + - echo "✅ Frontend tests completed" + when: + event: + - push + - pull_request + + # Проверка безопасности Python зависимостей - name: python-security image: python:3.11-slim commands: - cd backend - - pip install safety + - pip install --no-cache-dir safety bandit - echo "Checking for known security vulnerabilities..." - - safety check --file=requirements.txt --exit-zero || echo "⚠️ Security warnings found (non-blocking)" + - safety check --file=requirements.txt --exit-zero || echo "⚠️ Security warnings found" + - echo "Running bandit security analysis..." + - bandit -r . -f json -o bandit-report.json || echo "⚠️ Security issues found" - echo "✅ Security checks completed" + # Проверка безопасности Frontend зависимостей - name: frontend-security - image: node:18-alpine + image: node:20-alpine commands: - cd frontend - - npm ci + - npm ci --silent - echo "Running npm audit..." - - npm audit --audit-level=moderate || true + - npm audit --audit-level=moderate || echo "⚠️ Security warnings found" + - echo "✅ Frontend security checks completed" + +--- +kind: pipeline +type: docker +name: build-frontend + +trigger: + event: + - push + - tag + branch: + - main + - master + - develop + +depends_on: + - code-quality + +steps: + # Сборка Frontend + - name: build-frontend + image: node:20-alpine + commands: + - cd frontend + - echo "Installing frontend dependencies..." + - npm ci --silent + - echo "Building frontend for production..." + - npm run build + - echo "Frontend build size:" + - du -sh dist/ + - echo "✅ Frontend build completed" + volumes: + - name: frontend-dist + path: /drone/src/frontend/dist + + # Сохранение артефактов Frontend + - name: save-frontend-artifacts + image: alpine:latest + commands: + - echo "Saving frontend build artifacts..." + - tar -czf frontend-dist.tar.gz -C frontend dist/ + - ls -la frontend-dist.tar.gz + - echo "✅ Frontend artifacts saved" + volumes: + - name: frontend-dist + path: /drone/src/frontend/dist + depends_on: + - build-frontend + +volumes: + - name: frontend-dist + temp: {} --- kind: pipeline @@ -60,8 +153,10 @@ trigger: depends_on: - code-quality + - build-frontend steps: + # Сборка и публикация полного Docker образа - name: build-and-push image: plugins/docker settings: @@ -70,6 +165,7 @@ steps: tags: - latest - ${DRONE_COMMIT_SHA:0:8} + - ${DRONE_BRANCH} auto_tag: true dockerfile: Dockerfile context: . @@ -80,21 +176,178 @@ steps: build_args: - BUILD_DATE=${DRONE_BUILD_CREATED} - VCS_REF=${DRONE_COMMIT_SHA} - - VERSION=1.1.0 + - VERSION=${DRONE_TAG:-${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}} + - FRONTEND_BUILD_HASH=${DRONE_COMMIT_SHA:0:8} + - BACKEND_BUILD_HASH=${DRONE_COMMIT_SHA:0:8} when: event: - push - tag - - name: scan-image - image: aquasec/trivy + # Тестирование собранного образа + - name: test-image + image: docker:dind + volumes: + - name: docker-sock + path: /var/run/docker.sock commands: - - echo "⚠️ Image scanning skipped (requires registry authentication)" - - echo "To enable scanning, configure registry credentials for Trivy" - - echo "Image published registry.nevetime.ru/mc-panel" + - echo "Testing built Docker image..." + - docker run --rm -d --name mc-panel-test -p 8001:8000 registry.nevetime.ru/mc-panel:${DRONE_COMMIT_SHA:0:8} + - sleep 30 + - echo "Checking if application is responding..." + - docker exec mc-panel-test curl -f http://localhost:8000/ || echo "⚠️ Health check failed" + - docker stop mc-panel-test + - echo "✅ Image test completed" when: event: - push - tag depends_on: - build-and-push + + # Сканирование образа на уязвимости + - name: scan-image + image: aquasec/trivy:latest + environment: + TRIVY_USERNAME: + from_secret: docker_username + TRIVY_PASSWORD: + from_secret: docker_password + commands: + - echo "Scanning image for vulnerabilities..." + - trivy image --exit-code 0 --severity HIGH,CRITICAL --format table --username $TRIVY_USERNAME --password $TRIVY_PASSWORD registry.nevetime.ru/mc-panel:${DRONE_COMMIT_SHA:0:8} + - echo "Generating detailed security report..." + - trivy image --format json --output trivy-report.json --username $TRIVY_USERNAME --password $TRIVY_PASSWORD registry.nevetime.ru/mc-panel:${DRONE_COMMIT_SHA:0:8} || true + - echo "✅ Security scan completed" + when: + event: + - push + - tag + depends_on: + - build-and-push + +volumes: + - name: docker-sock + host: + path: /var/run/docker.sock + +--- +kind: pipeline +type: docker +name: deploy-staging + +trigger: + event: + - push + branch: + - develop + +depends_on: + - build-and-publish + +steps: + # Деплой на staging окружение + - name: deploy-to-staging + image: alpine:latest + environment: + STAGING_HOST: + from_secret: staging_host + STAGING_USER: + from_secret: staging_user + STAGING_KEY: + from_secret: staging_ssh_key + commands: + - apk add --no-cache openssh-client + - echo "Deploying to staging environment..." + - echo "$STAGING_KEY" | base64 -d > /tmp/ssh_key + - chmod 600 /tmp/ssh_key + - ssh -o StrictHostKeyChecking=no -i /tmp/ssh_key $STAGING_USER@$STAGING_HOST "docker pull registry.nevetime.ru/mc-panel:${DRONE_COMMIT_SHA:0:8} && docker-compose -f /opt/mc-panel/docker-compose.staging.yml up -d" + - echo "✅ Staging deployment completed" + when: + event: + - push + branch: + - develop + +--- +kind: pipeline +type: docker +name: deploy-production + +trigger: + event: + - tag + ref: + - refs/tags/v* + +depends_on: + - build-and-publish + +steps: + # Деплой на production окружение + - name: deploy-to-production + image: alpine:latest + environment: + PROD_HOST: + from_secret: production_host + PROD_USER: + from_secret: production_user + PROD_KEY: + from_secret: production_ssh_key + commands: + - apk add --no-cache openssh-client + - echo "Deploying to production environment..." + - echo "$PROD_KEY" | base64 -d > /tmp/ssh_key + - chmod 600 /tmp/ssh_key + - ssh -o StrictHostKeyChecking=no -i /tmp/ssh_key $PROD_USER@$PROD_HOST "docker pull registry.nevetime.ru/mc-panel:${DRONE_TAG} && docker-compose -f /opt/mc-panel/docker-compose.prod.yml up -d" + - echo "✅ Production deployment completed" + when: + event: + - tag + +--- +kind: pipeline +type: docker +name: notify + +trigger: + event: + - push + - tag + - pull_request + status: + - success + - failure + +depends_on: + - code-quality + - build-frontend + - build-and-publish + +steps: + # Уведомления о результатах сборки + - name: notify-telegram + image: appleboy/drone-telegram + settings: + token: + from_secret: telegram_bot_token + to: + from_secret: telegram_chat_id + format: markdown + message: > + {{#success build.status}} + ✅ **MC Panel Build Success** + {{else}} + ❌ **MC Panel Build Failed** + {{/success}} + + **Repository:** {{repo.name}} + **Branch:** {{build.branch}} + **Commit:** {{build.commit}} + **Author:** {{build.author}} + **Message:** {{build.message}} + **Build:** [#{{build.number}}]({{build.link}}) + when: + status: + - success + - failure diff --git a/.env.docker b/.env.docker new file mode 100644 index 0000000..8362ed7 --- /dev/null +++ b/.env.docker @@ -0,0 +1,63 @@ +# MC Panel Docker Environment Configuration +# Скопируйте этот файл в .env и настройте под свои нужды + +# ================================ +# Application Settings +# ================================ +PORT=8000 +WORKERS=1 +DEBUG=false + +# ================================ +# Security Settings +# ================================ +SECRET_KEY=your-super-secret-key-change-this +JWT_SECRET_KEY=your-jwt-secret-key-change-this +JWT_ALGORITHM=HS256 +JWT_EXPIRE_MINUTES=30 + +# ================================ +# OIDC Configuration +# ================================ +OIDC_CLIENT_ID=your-oidc-client-id +OIDC_CLIENT_SECRET=your-oidc-client-secret +OIDC_DISCOVERY_URL=https://your-oidc-provider/.well-known/openid_configuration +OIDC_REDIRECT_URI=http://localhost:8000/api/auth/oidc/callback + +# ================================ +# Database Settings (если используется) +# ================================ +DATABASE_URL=sqlite:///./data/mc_panel.db + +# ================================ +# Logging +# ================================ +LOG_LEVEL=INFO +LOG_FILE=/app/logs/mc_panel.log + +# ================================ +# Minecraft Server Settings +# ================================ +SERVERS_PATH=/app/backend/servers +MAX_SERVERS=10 +DEFAULT_SERVER_RAM=2G + +# ================================ +# WebSocket Settings +# ================================ +WS_MAX_CONNECTIONS=100 +WS_PING_INTERVAL=30 + +# ================================ +# File Upload Settings +# ================================ +MAX_UPLOAD_SIZE=100MB +ALLOWED_EXTENSIONS=jar,zip,txt,yml,yaml,json,properties + +# ================================ +# Backup Settings +# ================================ +BACKUP_PATH=/app/backend/data/backups +AUTO_BACKUP=true +BACKUP_INTERVAL=24h +MAX_BACKUPS=7 \ No newline at end of file diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..036ca72 --- /dev/null +++ b/.env.production.example @@ -0,0 +1,75 @@ +# MC Panel Production Environment Configuration + +# ================================ +# Application Settings +# ================================ +PORT=8000 +WORKERS=4 +DEBUG=false +LOG_LEVEL=WARNING + +# ================================ +# Security Settings +# ================================ +SECRET_KEY=production-super-secret-key-change-this-immediately +JWT_SECRET_KEY=production-jwt-secret-key-change-this-immediately +JWT_ALGORITHM=HS256 +JWT_EXPIRE_MINUTES=30 + +# ================================ +# OIDC Configuration +# ================================ +OIDC_CLIENT_ID=mc-panel-production +OIDC_CLIENT_SECRET=production-oidc-client-secret +OIDC_DISCOVERY_URL=https://auth.nevetime.ru/.well-known/openid_configuration +OIDC_REDIRECT_URI=https://mc-panel.nevetime.ru/api/auth/oidc/callback + +# ================================ +# Database Settings +# ================================ +DATABASE_URL=sqlite:///./data/mc_panel_production.db + +# ================================ +# Logging +# ================================ +LOG_FILE=/app/logs/mc_panel_production.log + +# ================================ +# Minecraft Server Settings +# ================================ +SERVERS_PATH=/app/backend/servers +MAX_SERVERS=20 +DEFAULT_SERVER_RAM=4G + +# ================================ +# WebSocket Settings +# ================================ +WS_MAX_CONNECTIONS=200 +WS_PING_INTERVAL=30 + +# ================================ +# File Upload Settings +# ================================ +MAX_UPLOAD_SIZE=500MB +ALLOWED_EXTENSIONS=jar,zip,txt,yml,yaml,json,properties + +# ================================ +# Backup Settings +# ================================ +BACKUP_PATH=/app/backups +AUTO_BACKUP=true +BACKUP_INTERVAL=24h +MAX_BACKUPS=30 + +# ================================ +# Performance Settings +# ================================ +CACHE_TTL=3600 +MAX_CONCURRENT_BUILDS=2 +BUILD_TIMEOUT=1800 + +# ================================ +# Monitoring +# ================================ +METRICS_ENABLED=true +HEALTH_CHECK_INTERVAL=30 \ No newline at end of file diff --git a/.env.staging.example b/.env.staging.example new file mode 100644 index 0000000..c1b4732 --- /dev/null +++ b/.env.staging.example @@ -0,0 +1,62 @@ +# MC Panel Staging Environment Configuration + +# ================================ +# Application Settings +# ================================ +PORT=8000 +WORKERS=2 +DEBUG=false +LOG_LEVEL=INFO + +# ================================ +# Security Settings +# ================================ +SECRET_KEY=staging-secret-key-change-this +JWT_SECRET_KEY=staging-jwt-secret-key-change-this +JWT_ALGORITHM=HS256 +JWT_EXPIRE_MINUTES=60 + +# ================================ +# OIDC Configuration +# ================================ +OIDC_CLIENT_ID=mc-panel-staging +OIDC_CLIENT_SECRET=staging-oidc-client-secret +OIDC_DISCOVERY_URL=https://auth-staging.nevetime.ru/.well-known/openid_configuration +OIDC_REDIRECT_URI=https://mc-panel-staging.nevetime.ru/api/auth/oidc/callback + +# ================================ +# Database Settings +# ================================ +DATABASE_URL=sqlite:///./data/mc_panel_staging.db + +# ================================ +# Logging +# ================================ +LOG_FILE=/app/logs/mc_panel_staging.log + +# ================================ +# Minecraft Server Settings +# ================================ +SERVERS_PATH=/app/backend/servers +MAX_SERVERS=5 +DEFAULT_SERVER_RAM=1G + +# ================================ +# WebSocket Settings +# ================================ +WS_MAX_CONNECTIONS=50 +WS_PING_INTERVAL=30 + +# ================================ +# File Upload Settings +# ================================ +MAX_UPLOAD_SIZE=50MB +ALLOWED_EXTENSIONS=jar,zip,txt,yml,yaml,json,properties + +# ================================ +# Backup Settings +# ================================ +BACKUP_PATH=/app/backend/data/backups +AUTO_BACKUP=true +BACKUP_INTERVAL=12h +MAX_BACKUPS=14 \ No newline at end of file diff --git a/CI_CD_README.md b/CI_CD_README.md new file mode 100644 index 0000000..695b741 --- /dev/null +++ b/CI_CD_README.md @@ -0,0 +1,211 @@ +# MC Panel CI/CD Pipeline + +## Обзор + +Проект использует Drone CI для автоматизации сборки, тестирования и деплоя. Pipeline состоит из нескольких этапов: + +1. **Code Quality** - проверка качества кода и безопасности +2. **Build Frontend** - сборка React приложения +3. **Build and Publish** - сборка и публикация Docker образа +4. **Deploy Staging** - автоматический деплой на staging (ветка develop) +5. **Deploy Production** - деплой на production (теги v*) +6. **Notify** - уведомления о результатах + +## Структура Pipeline + +### 1. Code Quality Pipeline +```yaml +Триггеры: push, pull_request +Шаги: +- python-lint: flake8, black, isort +- frontend-lint: TypeScript, ESLint +- python-tests: pytest с покрытием +- frontend-tests: Vitest/Jest +- python-security: safety, bandit +- frontend-security: npm audit +``` + +### 2. Build Frontend Pipeline +```yaml +Триггеры: push, tag (main/master/develop) +Зависимости: code-quality +Шаги: +- build-frontend: npm ci && npm run build +- save-frontend-artifacts: сохранение артефактов +``` + +### 3. Build and Publish Pipeline +```yaml +Триггеры: push, tag (main/master/develop) +Зависимости: code-quality, build-frontend +Шаги: +- build-and-push: Docker build и push в registry +- test-image: тестирование собранного образа +- scan-image: Trivy сканирование уязвимостей +``` + +### 4. Deploy Pipelines +```yaml +Staging: + Триггер: push в develop + Деплой: docker-compose.staging.yml + +Production: + Триггер: tag v* + Деплой: docker-compose.prod.yml +``` + +## Настройка Secrets + +В Drone необходимо настроить следующие секреты: + +### Docker Registry +``` +docker_username: логин для registry.nevetime.ru +docker_password: пароль для registry.nevetime.ru +``` + +### SSH для деплоя +``` +staging_host: IP/домен staging сервера +staging_user: пользователь SSH +staging_ssh_key: приватный SSH ключ (base64) + +production_host: IP/домен production сервера +production_user: пользователь SSH +production_ssh_key: приватный SSH ключ (base64) +``` + +### Уведомления +``` +telegram_bot_token: токен Telegram бота +telegram_chat_id: ID чата для уведомлений +``` + +## Теги и версионирование + +### Автоматические теги +- `latest` - последний коммит в main/master +- `develop` - последний коммит в develop +- `{commit-sha}` - короткий хеш коммита + +### Релизные теги +- `v1.0.0` - семантическое версионирование +- `v1.0.0-rc.1` - release candidate + +## Окружения + +### Development +- Локальная разработка +- `docker-compose.yml` + +### Staging +- Автоматический деплой из develop +- `docker-compose.staging.yml` +- URL: https://mc-panel-staging.nevetime.ru + +### Production +- Деплой по тегам v* +- `docker-compose.prod.yml` +- URL: https://mc-panel.nevetime.ru + +## Workflow + +### Разработка новой функции +1. Создать ветку от develop: `git checkout -b feature/new-feature` +2. Разработать функцию +3. Создать Pull Request в develop +4. После прохождения CI и ревью - мерж в develop +5. Автоматический деплой на staging + +### Релиз +1. Создать ветку release от develop: `git checkout -b release/v1.0.0` +2. Подготовить релиз (обновить версии, CHANGELOG) +3. Мерж в main и develop +4. Создать тег: `git tag v1.0.0` +5. Push тега: `git push origin v1.0.0` +6. Автоматический деплой на production + +### Hotfix +1. Создать ветку от main: `git checkout -b hotfix/critical-fix` +2. Исправить проблему +3. Мерж в main и develop +4. Создать тег с патч-версией: `git tag v1.0.1` +5. Push тега для деплоя + +## Мониторинг + +### Логи сборки +```bash +# Просмотр логов в Drone UI +https://drone.nevetime.ru/your-org/mc-panel + +# Локальные логи +docker-compose logs -f mc-panel +``` + +### Метрики +- Время сборки +- Размер образа +- Результаты тестов +- Покрытие кода +- Уязвимости безопасности + +## Troubleshooting + +### Сборка падает на frontend +```bash +# Проверить зависимости +cd frontend && npm audit + +# Обновить зависимости +npm update + +# Очистить кеш +npm ci --cache /tmp/empty-cache +``` + +### Сборка падает на backend +```bash +# Проверить requirements.txt +cd backend && pip check + +# Обновить зависимости +pip-compile requirements.in +``` + +### Проблемы с Docker registry +```bash +# Проверить авторизацию +docker login registry.nevetime.ru + +# Проверить образ +docker pull registry.nevetime.ru/mc-panel:latest +``` + +### Деплой не работает +```bash +# Проверить SSH подключение +ssh -i ~/.ssh/deploy_key user@server + +# Проверить Docker на сервере +docker ps +docker-compose ps +``` + +## Оптимизация + +### Ускорение сборки +- Использование кеша Docker слоев +- Параллельные шаги где возможно +- Оптимизация Dockerfile + +### Уменьшение размера образа +- Multi-stage build +- Минимальные базовые образы +- Очистка кеша пакетных менеджеров + +### Безопасность +- Регулярное сканирование уязвимостей +- Обновление базовых образов +- Ротация секретов \ No newline at end of file diff --git a/DOCKER_README.md b/DOCKER_README.md new file mode 100644 index 0000000..327e6b3 --- /dev/null +++ b/DOCKER_README.md @@ -0,0 +1,125 @@ +# MC Panel - Docker Setup + +## Быстрый запуск + +### Windows +```bash +# Запуск +docker-start.bat + +# Остановка +docker-stop.bat +``` + +### Linux/macOS +```bash +# Запуск +docker-compose up --build -d + +# Остановка +docker-compose down +``` + +## Требования + +- Docker Desktop 4.0+ +- Docker Compose 2.0+ +- Минимум 2GB RAM +- Минимум 5GB свободного места + +## Конфигурация + +1. Скопируйте `.env.docker` в `.env` +2. Отредактируйте переменные окружения в `.env` +3. Запустите контейнеры + +## Структура + +``` +mc-panel/ +├── Dockerfile # Основной Dockerfile +├── docker-compose.yml # Конфигурация сервисов +├── .env.docker # Шаблон переменных окружения +├── docker-start.bat # Скрипт запуска (Windows) +└── docker-stop.bat # Скрипт остановки (Windows) +``` + +## Volumes + +- `mc_servers` - Серверы Minecraft +- `mc_data` - Данные приложения +- `mc_logs` - Логи приложения + +## Порты + +- `8000` - Web интерфейс MC Panel +- `80/443` - Nginx (опционально) + +## Полезные команды + +```bash +# Просмотр логов +docker-compose logs -f mc-panel + +# Перезапуск +docker-compose restart + +# Обновление образа +docker-compose build --no-cache +docker-compose up -d + +# Вход в контейнер +docker-compose exec mc-panel bash + +# Очистка (удаление volumes) +docker-compose down -v + +# Полная очистка +docker-compose down --rmi all -v +docker system prune -a +``` + +## Troubleshooting + +### Контейнер не запускается +```bash +# Проверьте логи +docker-compose logs mc-panel + +# Проверьте конфигурацию +docker-compose config +``` + +### Проблемы с правами доступа +```bash +# Linux/macOS - исправление прав +sudo chown -R 1000:1000 backend/servers backend/data logs +``` + +### Порт уже занят +```bash +# Измените порт в docker-compose.yml +ports: + - "8080:8000" # вместо 8000:8000 +``` + +## Мониторинг + +Health check доступен по адресу: `http://localhost:8000/health` + +## Безопасность + +- Контейнер запускается от непривилегированного пользователя +- Используется multi-stage build для минимизации размера +- Секреты передаются через переменные окружения +- Volumes для персистентных данных + +## Production + +Для production окружения: + +1. Используйте внешнюю базу данных +2. Настройте SSL/TLS через Nginx +3. Используйте Docker Swarm или Kubernetes +4. Настройте мониторинг и логирование +5. Регулярно обновляйте образы \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index cf4f7df..bbaf677 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,130 +1,132 @@ # ================================ -# MC Panel - Multi-Stage Production Dockerfile +# MC Panel - Optimized Multi-Stage Dockerfile # ================================ # Stage 1: Frontend Build -FROM node:18-alpine AS frontend-builder +FROM node:20-alpine AS frontend-builder # Установка зависимостей для сборки -RUN apk add --no-cache git +RUN apk add --no-cache git python3 make g++ WORKDIR /app/frontend # Копируем package files для кеширования зависимостей COPY frontend/package*.json ./ -# Устанавливаем зависимости (включая dev для сборки) -RUN npm ci --silent +# Устанавливаем зависимости с оптимизацией +RUN npm ci --only=production --silent && \ + npm ci --silent # Копируем исходники и конфиги COPY frontend/ ./ # Собираем продакшн версию -RUN npm run build +RUN npm run build && \ + npm prune --production # ================================ -# Stage 2: Python Dependencies +# Stage 2: Python Dependencies Builder # ================================ -FROM python:3.11-slim AS python-deps +FROM python:3.11-slim AS python-builder -# Устанавливаем системные зависимости для компиляции Python пакетов +# Устанавливаем системные зависимости для компиляции RUN apt-get update && apt-get install -y \ build-essential \ - curl \ + gcc \ + g++ \ && rm -rf /var/lib/apt/lists/* -# Обновляем pip и устанавливаем зависимости -COPY backend/requirements.txt /tmp/ -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir --user -r /tmp/requirements.txt +# Создаем виртуальное окружение +RUN python -m venv /opt/venv +ENV PATH="/opt/venv/bin:$PATH" -# ================================ -# Stage 3: Daemon Dependencies (опционально) -# ================================ -FROM python:3.11-slim AS daemon-deps +# Обновляем pip и wheel +RUN pip install --no-cache-dir --upgrade pip wheel setuptools -RUN apt-get update && apt-get install -y \ - build-essential \ - && rm -rf /var/lib/apt/lists/* +# Устанавливаем backend зависимости +COPY backend/requirements.txt /tmp/backend-requirements.txt +RUN pip install --no-cache-dir -r /tmp/backend-requirements.txt +# Устанавливаем daemon зависимости COPY daemon/requirements.txt /tmp/daemon-requirements.txt -RUN pip install --no-cache-dir --upgrade pip && \ - pip install --no-cache-dir --user -r /tmp/daemon-requirements.txt +RUN pip install --no-cache-dir -r /tmp/daemon-requirements.txt # ================================ -# Stage 4: Production Runtime +# Stage 3: Production Runtime # ================================ FROM python:3.11-slim AS production # Метаданные -LABEL maintainer="MC Panel Team" -LABEL version="1.0.0" -LABEL description="MC Panel - Minecraft Server Management Panel" +LABEL maintainer="MC Panel Team" \ + version="2.0.0" \ + description="MC Panel - Minecraft Server Management Panel" \ + org.opencontainers.image.source="https://github.com/your-repo/mc-panel" # Переменные окружения ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PYTHONPATH=/app \ + PATH="/opt/venv/bin:$PATH" \ PORT=8000 \ + WORKERS=1 \ DEBIAN_FRONTEND=noninteractive # Устанавливаем только runtime зависимости -RUN apt-get update && apt-get install -y \ +RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ procps \ ca-certificates \ + tini \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean # Создаем пользователя для безопасности -RUN groupadd -r mcpanel && \ - useradd -r -g mcpanel -d /app -s /bin/bash mcpanel +RUN groupadd -r -g 1000 mcpanel && \ + useradd -r -u 1000 -g mcpanel -d /app -s /bin/bash mcpanel + +# Копируем виртуальное окружение из builder stage +COPY --from=python-builder /opt/venv /opt/venv # Создаем структуру директорий WORKDIR /app RUN mkdir -p \ - /app/backend \ - /app/frontend/dist \ - /app/daemon \ - /app/data \ - /app/logs \ - /app/backend/servers \ - /app/backend/data - -# Копируем Python зависимости из предыдущих стадий -COPY --from=python-deps /root/.local /home/mcpanel/.local -COPY --from=daemon-deps /root/.local /home/mcpanel/.local-daemon + backend \ + frontend/dist \ + daemon \ + data \ + logs \ + backend/servers \ + backend/data \ + && touch backend/users.json backend/tickets.json # Копируем собранный frontend -COPY --from=frontend-builder /app/frontend/dist ./frontend/dist +COPY --from=frontend-builder /app/frontend/dist ./frontend/dist/ # Копируем backend код -COPY backend/ ./backend/ +COPY --chown=mcpanel:mcpanel backend/ ./backend/ -# Копируем daemon код -COPY daemon/ ./daemon/ +# Копируем daemon код +COPY --chown=mcpanel:mcpanel daemon/ ./daemon/ # Копируем дополнительные файлы -COPY key.py ./ -COPY users.json ./backend/ 2>/dev/null || true +COPY --chown=mcpanel:mcpanel key.py ./ -# Создаем конфигурационные файлы по умолчанию -RUN echo '{}' > /app/backend/users.json && \ - echo '{}' > /app/backend/tickets.json +# Создаем конфигурационные файлы по умолчанию если их нет +RUN [ ! -f backend/users.json ] && echo '{}' > backend/users.json || true && \ + [ ! -f backend/tickets.json ] && echo '{}' > backend/tickets.json || true # Устанавливаем права доступа RUN chown -R mcpanel:mcpanel /app && \ - chmod +x /app/backend/main.py + chmod -R 755 /app && \ + chmod +x backend/main.py # Переключаемся на непривилегированного пользователя USER mcpanel -# Добавляем локальные Python пакеты в PATH -ENV PATH="/home/mcpanel/.local/bin:$PATH" - -# Health check +# Health check с улучшенной проверкой HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ - CMD curl -f http://localhost:${PORT}/api/auth/oidc/providers || exit 1 + CMD curl -f http://localhost:${PORT}/health 2>/dev/null || \ + curl -f http://localhost:${PORT}/ 2>/dev/null || exit 1 # Expose порты EXPOSE 8000 @@ -135,5 +137,8 @@ VOLUME ["/app/backend/servers", "/app/backend/data", "/app/logs"] # Рабочая директория для запуска WORKDIR /app/backend -# Команда запуска -CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"] \ No newline at end of file +# Используем tini как init процесс для правильной обработки сигналов +ENTRYPOINT ["/usr/bin/tini", "--"] + +# Команда запуска с переменными окружения +CMD ["sh", "-c", "python -m uvicorn main:app --host 0.0.0.0 --port ${PORT} --workers ${WORKERS}"] \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..fcdac1e --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,80 @@ +version: '3.8' + +services: + mc-panel: + image: registry.nevetime.ru/mc-panel:${IMAGE_TAG:-latest} + container_name: mc-panel-prod + restart: unless-stopped + ports: + - "8000:8000" + environment: + - PORT=8000 + - WORKERS=4 + - PYTHONPATH=/app + - DEBUG=false + - LOG_LEVEL=WARNING + env_file: + - .env.production + volumes: + - mc_servers_prod:/app/backend/servers + - mc_data_prod:/app/backend/data + - mc_logs_prod:/app/logs + # Backup volume + - mc_backups_prod:/app/backups + networks: + - mc-panel-prod + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + deploy: + resources: + limits: + memory: 2G + cpus: '2.0' + reservations: + memory: 1G + cpus: '1.0' + labels: + - "traefik.enable=true" + - "traefik.http.routers.mc-panel.rule=Host(`mc-panel.nevetime.ru`)" + - "traefik.http.routers.mc-panel.tls=true" + - "traefik.http.routers.mc-panel.tls.certresolver=letsencrypt" + - "traefik.http.middlewares.mc-panel-auth.basicauth.users=admin:$$2y$$10$$..." + + # Backup service + backup: + image: alpine:latest + container_name: mc-panel-backup + restart: unless-stopped + volumes: + - mc_servers_prod:/data/servers:ro + - mc_data_prod:/data/app:ro + - mc_backups_prod:/backups + environment: + - BACKUP_SCHEDULE=0 2 * * * # Daily at 2 AM + - BACKUP_RETENTION=7 # Keep 7 days + command: | + sh -c ' + apk add --no-cache dcron tar gzip + echo "$$BACKUP_SCHEDULE cd /data && tar -czf /backups/mc-panel-\$$(date +%Y%m%d-%H%M%S).tar.gz servers app" | crontab - + crond -f + ' + networks: + - mc-panel-prod + +volumes: + mc_servers_prod: + driver: local + mc_data_prod: + driver: local + mc_logs_prod: + driver: local + mc_backups_prod: + driver: local + +networks: + mc-panel-prod: + driver: bridge \ No newline at end of file diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml new file mode 100644 index 0000000..3daf6b7 --- /dev/null +++ b/docker-compose.staging.yml @@ -0,0 +1,46 @@ +version: '3.8' + +services: + mc-panel: + image: registry.nevetime.ru/mc-panel:${IMAGE_TAG:-latest} + container_name: mc-panel-staging + restart: unless-stopped + ports: + - "8080:8000" + environment: + - PORT=8000 + - WORKERS=2 + - PYTHONPATH=/app + - DEBUG=false + - LOG_LEVEL=INFO + env_file: + - .env.staging + volumes: + - mc_servers_staging:/app/backend/servers + - mc_data_staging:/app/backend/data + - mc_logs_staging:/app/logs + networks: + - mc-panel-staging + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + labels: + - "traefik.enable=true" + - "traefik.http.routers.mc-panel-staging.rule=Host(`mc-panel-staging.nevetime.ru`)" + - "traefik.http.routers.mc-panel-staging.tls=true" + - "traefik.http.routers.mc-panel-staging.tls.certresolver=letsencrypt" + +volumes: + mc_servers_staging: + driver: local + mc_data_staging: + driver: local + mc_logs_staging: + driver: local + +networks: + mc-panel-staging: + driver: bridge \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a6a0715..7aeeab3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,57 +1,31 @@ version: '3.8' services: - mcpanel: + mc-panel: build: context: . dockerfile: Dockerfile + target: production container_name: mc-panel restart: unless-stopped ports: - "8000:8000" environment: - # Основные настройки - PORT=8000 - - BASE_URL=http://localhost:8000 - - FRONTEND_URL=http://localhost:8000 - - # Безопасность (ОБЯЗАТЕЛЬНО измените в продакшене!) - - SECRET_KEY=your-very-long-random-secret-key-change-this-in-production - - # OIDC настройки (раскомментируйте и настройте при необходимости) - # - ZITADEL_ISSUER=https://your-instance.zitadel.cloud - # - ZITADEL_CLIENT_ID=your_client_id_here - # - ZITADEL_CLIENT_SECRET=your_client_secret_here - - # Логирование - - LOG_LEVEL=INFO - + - WORKERS=1 + - PYTHONPATH=/app volumes: # Персистентные данные - - mcpanel_servers:/app/backend/servers - - mcpanel_data:/app/backend/data - - mcpanel_logs:/app/logs - + - mc_servers:/app/backend/servers + - mc_data:/app/backend/data + - mc_logs:/app/logs # Конфигурационные файлы (опционально) - - ./backend/users.json:/app/backend/users.json - - ./backend/tickets.json:/app/backend/tickets.json - + - ./backend/.env:/app/backend/.env:ro + - ./daemon/.env:/app/daemon/.env:ro networks: - - mcpanel-network - - # Ограничения ресурсов - deploy: - resources: - limits: - memory: 1G - cpus: '0.5' - reservations: - memory: 512M - cpus: '0.25' - - # Health check + - mc-panel-network healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/auth/oidc/providers"] + test: ["CMD", "curl", "-f", "http://localhost:8000/"] interval: 30s timeout: 10s retries: 3 @@ -69,20 +43,20 @@ services: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/ssl:/etc/nginx/ssl:ro depends_on: - - mcpanel + - mc-panel networks: - - mcpanel-network + - mc-panel-network profiles: - - with-nginx + - nginx volumes: - mcpanel_servers: + mc_servers: driver: local - mcpanel_data: + mc_data: driver: local - mcpanel_logs: + mc_logs: driver: local networks: - mcpanel-network: + mc-panel-network: driver: bridge \ No newline at end of file diff --git a/docker-start.bat b/docker-start.bat new file mode 100644 index 0000000..c8ab9ce --- /dev/null +++ b/docker-start.bat @@ -0,0 +1,61 @@ +@echo off +echo ================================ +echo MC Panel Docker Startup Script +echo ================================ + +REM Проверяем наличие Docker +docker --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo ERROR: Docker не установлен или не запущен! + echo Установите Docker Desktop: https://www.docker.com/products/docker-desktop + pause + exit /b 1 +) + +REM Проверяем наличие docker-compose +docker-compose --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo ERROR: Docker Compose не найден! + echo Убедитесь что Docker Desktop установлен правильно + pause + exit /b 1 +) + +echo Проверяем конфигурационные файлы... + +REM Создаем .env файл если его нет +if not exist ".env" ( + echo Создаем .env файл из шаблона... + copy ".env.docker" ".env" + echo ВНИМАНИЕ: Отредактируйте .env файл перед запуском! + echo Нажмите любую клавишу для продолжения... + pause >nul +) + +REM Создаем необходимые директории +if not exist "backend\servers" mkdir "backend\servers" +if not exist "backend\data" mkdir "backend\data" +if not exist "logs" mkdir "logs" + +echo Запускаем MC Panel... +docker-compose up --build -d + +if %errorlevel% equ 0 ( + echo. + echo ================================ + echo MC Panel успешно запущен! + echo ================================ + echo Web интерфейс: http://localhost:8000 + echo. + echo Полезные команды: + echo docker-compose logs -f mc-panel - просмотр логов + echo docker-compose stop - остановка + echo docker-compose down - остановка и удаление контейнеров + echo docker-compose restart - перезапуск + echo. +) else ( + echo ERROR: Ошибка при запуске контейнеров! + echo Проверьте логи: docker-compose logs +) + +pause \ No newline at end of file diff --git a/docker-stop.bat b/docker-stop.bat new file mode 100644 index 0000000..e2ad16e --- /dev/null +++ b/docker-stop.bat @@ -0,0 +1,23 @@ +@echo off +echo ================================ +echo MC Panel Docker Stop Script +echo ================================ + +echo Останавливаем MC Panel... +docker-compose down + +if %errorlevel% equ 0 ( + echo MC Panel успешно остановлен! +) else ( + echo Ошибка при остановке контейнеров +) + +echo. +echo Для полной очистки (удаление volumes): +echo docker-compose down -v +echo. +echo Для удаления образов: +echo docker-compose down --rmi all +echo. + +pause \ No newline at end of file