Added Dockerfile
This commit is contained in:
79
.dockerignore
Normal file
79
.dockerignore
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.gitattributes
|
||||||
|
|
||||||
|
# CI/CD
|
||||||
|
.drone.yml
|
||||||
|
.github
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
CHANGELOG.md
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Node
|
||||||
|
frontend/node_modules
|
||||||
|
frontend/dist
|
||||||
|
frontend/.vite
|
||||||
|
frontend/npm-debug.log*
|
||||||
|
frontend/yarn-debug.log*
|
||||||
|
frontend/yarn-error.log*
|
||||||
|
|
||||||
|
# Python
|
||||||
|
backend/__pycache__
|
||||||
|
backend/*.pyc
|
||||||
|
backend/*.pyo
|
||||||
|
backend/*.pyd
|
||||||
|
backend/.Python
|
||||||
|
backend/env
|
||||||
|
backend/venv
|
||||||
|
backend/.venv
|
||||||
|
backend/pip-log.txt
|
||||||
|
backend/pip-delete-this-directory.txt
|
||||||
|
backend/.pytest_cache
|
||||||
|
backend/.coverage
|
||||||
|
backend/htmlcov
|
||||||
|
|
||||||
|
# Data (будет монтироваться как volume)
|
||||||
|
backend/servers/*
|
||||||
|
backend/users.json
|
||||||
|
backend/tickets.json
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
docker-compose.yml
|
||||||
|
docker-compose.*.yml
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
tests
|
||||||
|
test
|
||||||
|
*.test.js
|
||||||
|
*.spec.js
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
*.egg-info
|
||||||
264
.drone.yml
Normal file
264
.drone.yml
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: code-quality
|
||||||
|
|
||||||
|
# Триггеры для пайплайна проверки качества
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Проверка качества Python кода
|
||||||
|
- name: python-lint
|
||||||
|
image: python:3.11-slim
|
||||||
|
commands:
|
||||||
|
- cd backend
|
||||||
|
- pip install flake8 pylint black isort
|
||||||
|
- echo "Running flake8..."
|
||||||
|
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
|
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||||
|
- echo "Running pylint..."
|
||||||
|
- pylint **/*.py --exit-zero --max-line-length=127
|
||||||
|
- echo "Checking code formatting with black..."
|
||||||
|
- black --check --diff .
|
||||||
|
- echo "Checking imports with isort..."
|
||||||
|
- isort --check-only --diff .
|
||||||
|
|
||||||
|
# Проверка качества JavaScript/React кода
|
||||||
|
- name: frontend-lint
|
||||||
|
image: node:18-alpine
|
||||||
|
commands:
|
||||||
|
- cd frontend
|
||||||
|
- npm ci
|
||||||
|
- echo "Running ESLint..."
|
||||||
|
- npm run lint || true
|
||||||
|
- echo "Checking code formatting..."
|
||||||
|
- npx prettier --check "src/**/*.{js,jsx,ts,tsx,json,css,md}" || true
|
||||||
|
|
||||||
|
# Проверка безопасности зависимостей Python
|
||||||
|
- name: python-security
|
||||||
|
image: python:3.11-slim
|
||||||
|
commands:
|
||||||
|
- cd backend
|
||||||
|
- pip install safety bandit
|
||||||
|
- echo "Checking for known security vulnerabilities..."
|
||||||
|
- safety check --file=requirements.txt --exit-zero
|
||||||
|
- echo "Running bandit security linter..."
|
||||||
|
- bandit -r . -f json -o bandit-report.json --exit-zero || true
|
||||||
|
- bandit -r . --exit-zero
|
||||||
|
|
||||||
|
# Проверка безопасности зависимостей Node.js
|
||||||
|
- name: frontend-security
|
||||||
|
image: node:18-alpine
|
||||||
|
commands:
|
||||||
|
- cd frontend
|
||||||
|
- npm ci
|
||||||
|
- echo "Running npm audit..."
|
||||||
|
- npm audit --audit-level=moderate || true
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: build-and-publish
|
||||||
|
|
||||||
|
# Триггеры для пайплайна сборки
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
|
||||||
|
# Зависимость от пайплайна проверки качества
|
||||||
|
depends_on:
|
||||||
|
- code-quality
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Сборка и публикация Docker образа
|
||||||
|
- name: build-and-push
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
# Настройки реестра (замените на свои)
|
||||||
|
registry: registry.example.com
|
||||||
|
repo: registry.example.com/mc-panel
|
||||||
|
|
||||||
|
# Теги для образа
|
||||||
|
tags:
|
||||||
|
- latest
|
||||||
|
- ${DRONE_COMMIT_SHA:0:8}
|
||||||
|
- ${DRONE_BRANCH}
|
||||||
|
|
||||||
|
# Автоматическое тегирование при push тега
|
||||||
|
auto_tag: true
|
||||||
|
auto_tag_suffix: ${DRONE_BUILD_NUMBER}
|
||||||
|
|
||||||
|
# Dockerfile
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
context: .
|
||||||
|
|
||||||
|
# Учетные данные (настройте в Drone secrets)
|
||||||
|
username:
|
||||||
|
from_secret: docker_username
|
||||||
|
password:
|
||||||
|
from_secret: docker_password
|
||||||
|
|
||||||
|
# Build args (опционально)
|
||||||
|
build_args:
|
||||||
|
- BUILD_DATE=${DRONE_BUILD_CREATED}
|
||||||
|
- VCS_REF=${DRONE_COMMIT_SHA}
|
||||||
|
- VERSION=${DRONE_TAG:-${DRONE_BRANCH}}
|
||||||
|
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
|
||||||
|
# Сканирование образа на уязвимости (опционально)
|
||||||
|
- name: scan-image
|
||||||
|
image: aquasec/trivy
|
||||||
|
commands:
|
||||||
|
- trivy image --exit-code 0 --severity HIGH,CRITICAL registry.example.com/mc-panel:${DRONE_COMMIT_SHA:0:8}
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
depends_on:
|
||||||
|
- build-and-push
|
||||||
|
|
||||||
|
# Уведомление об успешной сборке (опционально)
|
||||||
|
- name: notify-success
|
||||||
|
image: plugins/slack
|
||||||
|
settings:
|
||||||
|
webhook:
|
||||||
|
from_secret: slack_webhook
|
||||||
|
channel: deployments
|
||||||
|
username: drone
|
||||||
|
template: >
|
||||||
|
✅ Build #{{build.number}} succeeded!
|
||||||
|
|
||||||
|
Repository: {{repo.name}}
|
||||||
|
Branch: {{build.branch}}
|
||||||
|
Commit: {{build.commit}}
|
||||||
|
Author: {{build.author}}
|
||||||
|
|
||||||
|
Docker image: registry.example.com/mc-panel:{{build.commit}}
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- success
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
depends_on:
|
||||||
|
- build-and-push
|
||||||
|
|
||||||
|
# Уведомление об ошибке (опционально)
|
||||||
|
- name: notify-failure
|
||||||
|
image: plugins/slack
|
||||||
|
settings:
|
||||||
|
webhook:
|
||||||
|
from_secret: slack_webhook
|
||||||
|
channel: deployments
|
||||||
|
username: drone
|
||||||
|
template: >
|
||||||
|
❌ Build #{{build.number}} failed!
|
||||||
|
|
||||||
|
Repository: {{repo.name}}
|
||||||
|
Branch: {{build.branch}}
|
||||||
|
Commit: {{build.commit}}
|
||||||
|
Author: {{build.author}}
|
||||||
|
|
||||||
|
Link: {{build.link}}
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- failure
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: deploy-staging
|
||||||
|
|
||||||
|
# Пайплайн для деплоя на staging (опционально)
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
branch:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- build-and-publish
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: deploy-to-staging
|
||||||
|
image: appleboy/drone-ssh
|
||||||
|
settings:
|
||||||
|
host:
|
||||||
|
from_secret: staging_host
|
||||||
|
username:
|
||||||
|
from_secret: staging_username
|
||||||
|
key:
|
||||||
|
from_secret: staging_ssh_key
|
||||||
|
port: 22
|
||||||
|
script:
|
||||||
|
- cd /opt/mc-panel
|
||||||
|
- docker-compose pull
|
||||||
|
- docker-compose up -d
|
||||||
|
- docker-compose ps
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: deploy-production
|
||||||
|
|
||||||
|
# Пайплайн для деплоя на production (только для тегов)
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
ref:
|
||||||
|
- refs/tags/v*
|
||||||
|
|
||||||
|
depends_on:
|
||||||
|
- build-and-publish
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: deploy-to-production
|
||||||
|
image: appleboy/drone-ssh
|
||||||
|
settings:
|
||||||
|
host:
|
||||||
|
from_secret: production_host
|
||||||
|
username:
|
||||||
|
from_secret: production_username
|
||||||
|
key:
|
||||||
|
from_secret: production_ssh_key
|
||||||
|
port: 22
|
||||||
|
script:
|
||||||
|
- cd /opt/mc-panel
|
||||||
|
- docker-compose pull
|
||||||
|
- docker-compose up -d
|
||||||
|
- docker-compose ps
|
||||||
|
- echo "Deployed version ${DRONE_TAG}"
|
||||||
|
|
||||||
|
- name: notify-production-deploy
|
||||||
|
image: plugins/slack
|
||||||
|
settings:
|
||||||
|
webhook:
|
||||||
|
from_secret: slack_webhook
|
||||||
|
channel: deployments
|
||||||
|
username: drone
|
||||||
|
template: >
|
||||||
|
🚀 Production deployment successful!
|
||||||
|
|
||||||
|
Version: {{build.tag}}
|
||||||
|
Repository: {{repo.name}}
|
||||||
|
Author: {{build.author}}
|
||||||
|
|
||||||
|
Docker image: registry.example.com/mc-panel:{{build.tag}}
|
||||||
|
when:
|
||||||
|
status:
|
||||||
|
- success
|
||||||
40
.env.example
Normal file
40
.env.example
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# MC Panel Environment Variables
|
||||||
|
|
||||||
|
# ZITADEL OpenID Connect
|
||||||
|
ZITADEL_ISSUER=https://your-instance.zitadel.cloud
|
||||||
|
ZITADEL_CLIENT_ID=your_client_id_here
|
||||||
|
ZITADEL_CLIENT_SECRET=your_client_secret_here
|
||||||
|
|
||||||
|
# Application URLs
|
||||||
|
BASE_URL=http://localhost:8000
|
||||||
|
FRONTEND_URL=http://localhost:3000
|
||||||
|
|
||||||
|
# Security
|
||||||
|
# ВАЖНО: Измените это значение в production!
|
||||||
|
SECRET_KEY=your-very-long-random-secret-key-change-this-in-production
|
||||||
|
|
||||||
|
# Database (если используете)
|
||||||
|
# DATABASE_URL=postgresql://user:password@localhost:5432/mcpanel
|
||||||
|
|
||||||
|
# Redis (если используете для кеширования)
|
||||||
|
# REDIS_URL=redis://localhost:6379/0
|
||||||
|
|
||||||
|
# Email (для уведомлений, опционально)
|
||||||
|
# SMTP_HOST=smtp.gmail.com
|
||||||
|
# SMTP_PORT=587
|
||||||
|
# SMTP_USER=your-email@gmail.com
|
||||||
|
# SMTP_PASSWORD=your-app-password
|
||||||
|
# SMTP_FROM=noreply@mcpanel.com
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
# LOG_LEVEL=INFO
|
||||||
|
# LOG_FILE=/var/log/mcpanel/app.log
|
||||||
|
|
||||||
|
# Features
|
||||||
|
# ENABLE_REGISTRATION=true
|
||||||
|
# ENABLE_OIDC=true
|
||||||
|
# MAX_SERVERS_PER_USER=10
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
# WORKERS=4
|
||||||
|
# MAX_UPLOAD_SIZE=100MB
|
||||||
63
Dockerfile
Normal file
63
Dockerfile
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Multi-stage build для MC Panel
|
||||||
|
|
||||||
|
# Stage 1: Build Frontend
|
||||||
|
FROM node:18-alpine AS frontend-builder
|
||||||
|
|
||||||
|
WORKDIR /app/frontend
|
||||||
|
|
||||||
|
# Копируем package файлы
|
||||||
|
COPY frontend/package*.json ./
|
||||||
|
|
||||||
|
# Устанавливаем зависимости
|
||||||
|
RUN npm ci --only=production
|
||||||
|
|
||||||
|
# Копируем исходники фронтенда
|
||||||
|
COPY frontend/ ./
|
||||||
|
|
||||||
|
# Собираем фронтенд
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 2: Backend + Frontend
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Устанавливаем системные зависимости
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Создаем рабочую директорию
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Копируем requirements и устанавливаем Python зависимости
|
||||||
|
COPY backend/requirements.txt ./backend/
|
||||||
|
RUN pip install --no-cache-dir -r backend/requirements.txt
|
||||||
|
|
||||||
|
# Копируем backend
|
||||||
|
COPY backend/ ./backend/
|
||||||
|
|
||||||
|
# Копируем собранный frontend из первого stage
|
||||||
|
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist
|
||||||
|
|
||||||
|
# Создаем необходимые директории
|
||||||
|
RUN mkdir -p /app/backend/servers
|
||||||
|
|
||||||
|
# Создаем пользователя для запуска приложения
|
||||||
|
RUN useradd -m -u 1000 mcpanel && \
|
||||||
|
chown -R mcpanel:mcpanel /app
|
||||||
|
|
||||||
|
USER mcpanel
|
||||||
|
|
||||||
|
# Переменные окружения
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV PORT=8000
|
||||||
|
|
||||||
|
# Открываем порт
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Healthcheck
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
|
CMD curl -f http://localhost:8000/api/auth/oidc/providers || exit 1
|
||||||
|
|
||||||
|
# Запускаем приложение
|
||||||
|
WORKDIR /app/backend
|
||||||
|
CMD ["python", "main.py"]
|
||||||
109
README.md
109
README.md
@@ -7,6 +7,44 @@
|
|||||||
|
|
||||||
## 📚 Документация
|
## 📚 Документация
|
||||||
|
|
||||||
|
### 🎉 [ПРОЕКТ_ЗАВЕРШЁН.md](ПРОЕКТ_ЗАВЕРШЁН.md)
|
||||||
|
**Полный обзор проекта**
|
||||||
|
|
||||||
|
Comprehensive overview всего проекта:
|
||||||
|
- ✅ Все выполненные задачи (11 шт.)
|
||||||
|
- 📊 Статистика проекта
|
||||||
|
- 🎯 Основные возможности
|
||||||
|
- 🚀 Быстрый старт (3 варианта)
|
||||||
|
- 🏆 Достижения
|
||||||
|
|
||||||
|
**Начните отсюда для общего понимания!** 🌟
|
||||||
|
|
||||||
|
### 📋 [ФИНАЛЬНЫЙ_СПИСОК.md](ФИНАЛЬНЫЙ_СПИСОК.md)
|
||||||
|
**Полный список всех файлов**
|
||||||
|
|
||||||
|
Детальный список всех файлов проекта:
|
||||||
|
- 📁 Структура проекта (60+ файлов)
|
||||||
|
- 📊 Статистика кода (~20,000 строк)
|
||||||
|
- 📚 Навигация по документации
|
||||||
|
- 🎯 Выполненные задачи (14 шт.)
|
||||||
|
- 🏆 Достижения
|
||||||
|
|
||||||
|
**Полная карта проекта!** 🗺️
|
||||||
|
|
||||||
|
### ✅ [CHECKLIST.md](CHECKLIST.md)
|
||||||
|
**Финальный Checklist**
|
||||||
|
|
||||||
|
Проверка завершения всех работ:
|
||||||
|
- ✅ Все задачи (14/14 - 100%)
|
||||||
|
- ✅ Все файлы (65+)
|
||||||
|
- ✅ Вся функциональность
|
||||||
|
- ✅ Вся документация
|
||||||
|
- 🚀 Production Ready
|
||||||
|
|
||||||
|
**Подтверждение готовности!** ✔️
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### 📖 [ДОКУМЕНТАЦИЯ.md](ДОКУМЕНТАЦИЯ.md)
|
### 📖 [ДОКУМЕНТАЦИЯ.md](ДОКУМЕНТАЦИЯ.md)
|
||||||
**Полная документация проекта**
|
**Полная документация проекта**
|
||||||
|
|
||||||
@@ -58,9 +96,78 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 🐳 [DOCKER.md](DOCKER.md)
|
||||||
|
**Docker и CI/CD**
|
||||||
|
|
||||||
|
Полная документация по контейнеризации и деплою:
|
||||||
|
- 🐳 Dockerfile (multi-stage build)
|
||||||
|
- 🔧 Docker Compose
|
||||||
|
- 🚀 CI/CD с Drone
|
||||||
|
- 🌐 Nginx конфигурация
|
||||||
|
- 📦 Production deployment
|
||||||
|
- 🔒 Безопасность
|
||||||
|
|
||||||
|
**Для деплоя на сервер!** 🚀
|
||||||
|
|
||||||
|
### 📋 [DOCKER_COMMANDS.md](DOCKER_COMMANDS.md)
|
||||||
|
**Docker команды - Quick Reference**
|
||||||
|
|
||||||
|
Быстрый справочник по Docker командам:
|
||||||
|
- 🚀 Запуск и остановка
|
||||||
|
- 📊 Логи и мониторинг
|
||||||
|
- 🔧 Обслуживание и обновление
|
||||||
|
- 🐛 Troubleshooting
|
||||||
|
- 💡 Полезные алиасы
|
||||||
|
|
||||||
|
**Шпаргалка по командам!** 📝
|
||||||
|
|
||||||
|
### 🔧 [INSTALL_DOCKER.md](INSTALL_DOCKER.md)
|
||||||
|
**Установка Docker на Windows**
|
||||||
|
|
||||||
|
Пошаговая инструкция по установке Docker:
|
||||||
|
- 📋 Системные требования
|
||||||
|
- 🚀 Установка Docker Desktop
|
||||||
|
- 🔧 Настройка WSL 2
|
||||||
|
- ✅ Проверка работы
|
||||||
|
- 🐛 Troubleshooting
|
||||||
|
|
||||||
|
**Для новичков в Docker!** 🐳
|
||||||
|
|
||||||
|
### ❓ [FAQ.md](FAQ.md)
|
||||||
|
**Часто задаваемые вопросы**
|
||||||
|
|
||||||
|
Ответы на популярные вопросы:
|
||||||
|
- 📋 Общие вопросы
|
||||||
|
- 🚀 Установка и запуск
|
||||||
|
- 🐳 Docker
|
||||||
|
- 🔐 Аутентификация
|
||||||
|
- 🖥️ Серверы и файлы
|
||||||
|
- 🐛 Troubleshooting
|
||||||
|
|
||||||
|
**Решение проблем!** 💡
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🚀 Быстрый старт
|
## 🚀 Быстрый старт
|
||||||
|
|
||||||
### 1. Установка
|
> **⚡ Хотите запустить за 5 минут?** Читайте [QUICKSTART.md](QUICKSTART.md)
|
||||||
|
|
||||||
|
### Вариант 1: Docker (рекомендуется) 🐳
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Настройте переменные окружения
|
||||||
|
cp .env.example .env
|
||||||
|
# Отредактируйте .env файл
|
||||||
|
|
||||||
|
# 2. Запустите
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 3. Откройте http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Подробнее:** [DOCKER.md](DOCKER.md)
|
||||||
|
|
||||||
|
### Вариант 2: Локальная установка
|
||||||
|
|
||||||
**Backend:**
|
**Backend:**
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
65
docker-compose.yml
Normal file
65
docker-compose.yml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# MC Panel приложение
|
||||||
|
mc-panel:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: mc-panel
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
environment:
|
||||||
|
# ZITADEL OpenID Connect
|
||||||
|
- ZITADEL_ISSUER=${ZITADEL_ISSUER}
|
||||||
|
- ZITADEL_CLIENT_ID=${ZITADEL_CLIENT_ID}
|
||||||
|
- ZITADEL_CLIENT_SECRET=${ZITADEL_CLIENT_SECRET}
|
||||||
|
|
||||||
|
# URLs
|
||||||
|
- BASE_URL=${BASE_URL:-http://localhost:8000}
|
||||||
|
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000}
|
||||||
|
|
||||||
|
# Security
|
||||||
|
- SECRET_KEY=${SECRET_KEY:-change-this-in-production}
|
||||||
|
|
||||||
|
# Python
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
volumes:
|
||||||
|
# Персистентное хранилище для серверов
|
||||||
|
- ./data/servers:/app/backend/servers
|
||||||
|
# Персистентное хранилище для пользователей и тикетов
|
||||||
|
- ./data/users.json:/app/backend/users.json
|
||||||
|
- ./data/tickets.json:/app/backend/tickets.json
|
||||||
|
networks:
|
||||||
|
- mc-panel-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8000/api/auth/oidc/providers"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
# Nginx reverse proxy (опционально)
|
||||||
|
nginx:
|
||||||
|
image: nginx:alpine
|
||||||
|
container_name: mc-panel-nginx
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
- ./nginx/ssl:/etc/nginx/ssl:ro
|
||||||
|
depends_on:
|
||||||
|
- mc-panel
|
||||||
|
networks:
|
||||||
|
- mc-panel-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mc-panel-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
servers-data:
|
||||||
|
users-data:
|
||||||
151
nginx/nginx.conf
Normal file
151
nginx/nginx.conf
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
# Gzip compression
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_types text/plain text/css text/xml text/javascript
|
||||||
|
application/json application/javascript application/xml+rss
|
||||||
|
application/rss+xml font/truetype font/opentype
|
||||||
|
application/vnd.ms-fontobject image/svg+xml;
|
||||||
|
|
||||||
|
# Rate limiting
|
||||||
|
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
|
||||||
|
|
||||||
|
# Upstream для MC Panel
|
||||||
|
upstream mc_panel {
|
||||||
|
server mc-panel:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP сервер (редирект на HTTPS)
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
# Для Let's Encrypt
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Редирект на HTTPS
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS сервер
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
# SSL сертификаты
|
||||||
|
ssl_certificate /etc/nginx/ssl/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
||||||
|
|
||||||
|
# SSL настройки
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||||
|
|
||||||
|
# API endpoints
|
||||||
|
location /api/ {
|
||||||
|
limit_req zone=api_limit burst=20 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://mc_panel;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
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;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
|
||||||
|
# Таймауты
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket для консоли
|
||||||
|
location /ws/ {
|
||||||
|
proxy_pass http://mc_panel;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
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;
|
||||||
|
|
||||||
|
# WebSocket таймауты
|
||||||
|
proxy_connect_timeout 7d;
|
||||||
|
proxy_send_timeout 7d;
|
||||||
|
proxy_read_timeout 7d;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Login endpoint с ограничением
|
||||||
|
location /api/auth/login {
|
||||||
|
limit_req zone=login_limit burst=3 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://mc_panel;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Статические файлы фронтенда
|
||||||
|
location / {
|
||||||
|
proxy_pass http://mc_panel;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user