diff --git a/Dockerfile b/Dockerfile
index d183be8..239d077 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,16 +4,25 @@ FROM python:3.13-slim-bookworm
# Install UV (ultra-fast Python package installer) from Astral.sh
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
+# Create non-root user for security
+RUN groupadd -r appuser && useradd -r -g appuser appuser
+
# Ensure Python output is sent straight to terminal without buffering
ENV PYTHONUNBUFFERED=1 \
- PYTHONDONTWRITEBYTECODE=1
+ PYTHONDONTWRITEBYTECODE=1 \
+ UV_SYSTEM_PYTHON=1
# ======================
# SYSTEM DEPENDENCIES
# ======================
RUN apt-get update && \
- apt-get install -y --no-install-recommends curl gettext && \
- apt-get clean && rm -rf /var/lib/apt/lists/*
+ apt-get install -y --no-install-recommends \
+ curl \
+ gettext \
+ ca-certificates && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/* && \
+ rm -rf /tmp/* /var/tmp/*
# Set working directory inside container
WORKDIR /app
@@ -21,31 +30,38 @@ WORKDIR /app
# ======================
# DEPENDENCY INSTALLATION
# ======================
-# Copies the dependency files (py project.tool and uv.lock) to /app.
-COPY pyproject.toml uv.lock ./
+# Copy dependency files with proper ownership
+COPY --chown=appuser:appuser pyproject.toml uv.lock ./
-# Install Python dependencies using UV:
-# --locked: ensures exact versions from lockfile are used
-# Copies the rest of the project code to /app.
-RUN uv sync --locked
+# Install Python dependencies using UV
+RUN uv sync --locked --no-dev
# ======================
# APPLICATION CODE
# ======================
+# Copy entrypoint script first
+COPY --chown=appuser:appuser entrypoint.sh /app/entrypoint.sh
+RUN chmod +x /app/entrypoint.sh
+
# Copy the rest of the application code
-# Note: This is done after dependency installation for better caching
-COPY . .
+COPY --chown=appuser:appuser . .
-# Copies the script entrypoint.sh in /app.
-# Makes it executable (chmod +x).
-COPY entrypoint.sh /app/entrypoint.sh
-RUN chmod +x /app/entrypoint.sh
+# Create directories for Django with proper permissions
+RUN mkdir -p /app/static /app/media && \
+ chown -R appuser:appuser /app
# ======================
# RUNTIME CONFIGURATION
# ======================
+# Switch to non-root user
+USER appuser
+
# Expose the port Django runs on
EXPOSE 8000
+# Health check
+HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
+ CMD curl -f http://localhost:8000/health/ || exit 1
+
# Launches the application through a script entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]
diff --git a/Makefile b/Makefile
index 56e2119..fa5fe25 100644
--- a/Makefile
+++ b/Makefile
@@ -1,31 +1,129 @@
+# ======================
+# VARIABLES
+# ======================
USERID := $(shell id -u)
GROUPID := $(shell id -g)
PYTHON := docker compose run -u $(USERID):$(GROUPID) --rm django uv run
+DOCKER_COMPOSE := docker compose
+RUFF := uvx ruff
-collectstatic:
+# ======================
+# HELP
+# ======================
+.PHONY: help
+help: ## Show this help message
+ @echo "Available commands:"
+ @awk 'BEGIN {FS = ":.*##"; printf "\n"} /^[a-zA-Z_-]+:.*?##/ { printf " %-20s %s\n", $$1, $$2 } /^##@/ { printf "\n%s\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
+
+# ======================
+# DOCKER MANAGEMENT
+# ======================
+.PHONY: build up down restart logs clean
+build: ## Build Docker images
+ $(DOCKER_COMPOSE) build
+
+up: ## Start all services
+ $(DOCKER_COMPOSE) up -d
+
+down: ## Stop all services
+ $(DOCKER_COMPOSE) down
+
+restart: ## Restart all services
+ $(DOCKER_COMPOSE) restart
+
+logs: ## Show logs for all services
+ $(DOCKER_COMPOSE) logs -f
+
+clean: ## Clean up Docker resources
+ $(DOCKER_COMPOSE) down -v --remove-orphans
+ docker system prune -f
+
+# ======================
+# DJANGO MANAGEMENT
+# ======================
+.PHONY: collectstatic startapp makemigrations migrate createsuperuser shell reset_db
+collectstatic: ## Collect static files
$(PYTHON) manage.py collectstatic --noinput -c
-startapp:
+startapp: ## Create new Django app (usage: make startapp app=myapp)
$(PYTHON) manage.py startapp ${app}
-makemigrations:
+makemigrations: ## Create database migrations
$(PYTHON) manage.py makemigrations ${app}
-migrate:
+migrate: ## Apply database migrations
$(PYTHON) manage.py migrate ${app}
-createsuperuser:
+createsuperuser: ## Create Django superuser
$(PYTHON) manage.py createsuperuser
-shell:
+shell: ## Open Django shell
$(PYTHON) manage.py shell_plus
-reset_db:
+reset_db: ## Reset database
$(PYTHON) manage.py reset_db
-format:
- uvx ruff check --fix apps config && uvx ruff check --select I --fix apps config && uvx ruff format apps config
+# ======================
+# CODE QUALITY
+# ======================
+.PHONY: format lint check test
+format: ## Format code with ruff
+ $(RUFF) check --fix apps config
+ $(RUFF) check --select I --fix apps config
+ $(RUFF) format apps config
+
+lint: ## Run linting checks
+ $(RUFF) check apps config
+
+check: ## Run all code quality checks
+ $(RUFF) check apps config
+ $(RUFF) format --check apps config
+
+test: ## Run tests
+ $(PYTHON) manage.py test
-run:
- $(PYTHON) manage.py migrate
+# ======================
+# DEVELOPMENT
+# ======================
+.PHONY: run dev install requirements
+run: migrate ## Run Django development server
$(PYTHON) manage.py runserver 0.0.0.0:8000
+
+dev: up ## Start development environment
+ @echo "Development environment started"
+ @echo "Django: http://localhost:8000"
+ @echo "PostgreSQL: localhost:5432"
+
+install: ## Install dependencies
+ uv sync --locked
+
+requirements: ## Update requirements
+ uv lock
+
+# ======================
+# PRODUCTION
+# ======================
+.PHONY: prod-build prod-up prod-down
+prod-build: ## Build production images
+ $(DOCKER_COMPOSE) -f docker-compose.prod.yml build
+
+prod-up: ## Start production environment
+ $(DOCKER_COMPOSE) -f docker-compose.prod.yml up -d
+
+prod-down: ## Stop production environment
+ $(DOCKER_COMPOSE) -f docker-compose.prod.yml down
+
+# ======================
+# UTILITIES
+# ======================
+.PHONY: backup restore health
+backup: ## Create database backup
+ $(DOCKER_COMPOSE) exec postgres pg_dump -U $$POSTGRES_USER $$POSTGRES_DB > backup_$$(date +%Y%m%d_%H%M%S).sql
+
+restore: ## Restore database from backup (usage: make restore file=backup.sql)
+ $(DOCKER_COMPOSE) exec -T postgres psql -U $$POSTGRES_USER $$POSTGRES_DB < ${file}
+
+health: ## Check services health
+ $(DOCKER_COMPOSE) ps
+ @echo "\n--- Service Health ---"
+ @curl -f http://localhost:8000/health/ || echo "Django service not responding"
diff --git a/README.md b/README.md
index 49525b7..1f162aa 100644
--- a/README.md
+++ b/README.md
@@ -1,182 +1,269 @@
+# 📚 PythonBooks
+
[](https://github.com/khoshov/pythonbooks/actions/workflows/ruff.yml)
+[](https://python.org)
+[](https://djangoproject.com)
+[](https://docker.com)
+[](https://astral.sh)
-## Структура
+> Современное Django-приложение для управления книгами с использованием UV, Docker и современных инструментов разработки.
-
+## 🚀 Быстрый старт
-```python
+### Вариант 1: Docker (рекомендуется)
+```bash
+git clone https://github.com/khoshov/pythonbooks.git
+cd pythonbooks
+cp .env.example .env
+make dev
+```
-pythonbooks
-│
-├── .github/workflows/
-│ └── ruff.yml
-│
-├── apps/
-│ └── books/
-├── config/
-│
-├── .dockerignore
-├── .env
-├── .gitignore
-├── .pre-commit-config.yaml
-├── 🐳 docker-compose.yml
-├── 🐳 Dockerfile
-├── 🐳 entrypoint.sh - запускается внутри контейнера при старте, для миграций, запуска сервера и т.п.
-├── Makefile
-│
-├── manage.py
-│
-├── 📦 pyproject.toml
-├── README.md
-├── 📦 requirements.txt
-└── 📦 uv.lock
+### Вариант 2: Локальная установка
+```bash
+git clone https://github.com/khoshov/pythonbooks.git
+cd pythonbooks
+uv sync
+cp .env.example .env
+uv run manage.py migrate
+uv run manage.py runserver
```
-
+## 📋 Требования
----
+- **Python 3.13+**
+- **Docker & Docker Compose** (для контейнеризации)
+- **UV** (менеджер пакетов)
+- **PostgreSQL** (база данных)
-## Установка и использование UV
+## 🏗️ Структура проекта
-
-📦 Способы установки UV
+```
+pythonbooks/
+├── 🐳 docker-compose.yml # Конфигурация Docker Compose
+├── 🐳 Dockerfile # Образ приложения
+├── 🐳 entrypoint.sh # Точка входа контейнера
+├── 📦 pyproject.toml # Конфигурация проекта и зависимости
+├── 📦 uv.lock # Файл блокировки зависимостей
+├── 🔧 Makefile # Команды для разработки
+├── 📝 .env.example # Пример переменных окружения
+├── 🔒 .pre-commit-config.yaml # Конфигурация pre-commit хуков
+│
+├── apps/
+│ └── books/ # Django приложение для книг
+│ ├── scrapers/ # Скрейперы для сбора данных
+│ ├── models.py # Модели данных
+│ ├── views.py # Представления
+│ └── admin.py # Админ-панель
+│
+├── config/ # Настройки Django
+│ ├── settings.py # Основные настройки
+│ ├── urls.py # URL конфигурация
+│ └── wsgi.py # WSGI приложение
+│
+└── .github/workflows/ # CI/CD пайплайны
+ └── ruff.yml # Проверка кода с Ruff
+```
-### 1. Установка через автономные установщики (рекомендуется)
+## 🛠️ Команды разработки
-**Для macOS и Linux:**
+### Основные команды
```bash
-curl -LsSf https://astral.sh/uv/install.sh | sh
+make help # Показать все доступные команды
+make dev # Запустить среду разработки
+make build # Собрать Docker образы
+make up # Запустить все сервисы
+make down # Остановить все сервисы
+make logs # Показать логи
+make clean # Очистить Docker ресурсы
```
-**Для Windows (PowerShell):**
-```powershell
-powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
+### Django команды
+```bash
+make migrate # Применить миграции
+make makemigrations # Создать миграции
+make createsuperuser # Создать суперпользователя
+make shell # Открыть Django shell
+make collectstatic # Собрать статические файлы
+make startapp app=myapp # Создать новое приложение
```
-### 2. Установка через PyPI (альтернативный способ)
+### Качество кода
```bash
-pip install uv
+make format # Отформатировать код
+make lint # Проверить код линтером
+make check # Запустить все проверки
+make test # Запустить тесты
```
-### Обновление UV
-После установки вы можете обновить UV до последней версии:
+### Утилиты
```bash
-uv self update
+make backup # Создать резервную копию БД
+make restore file=backup.sql # Восстановить из резервной копии
+make health # Проверить состояние сервисов
```
-🔗 Подробнее об установке: [Официальная документация](https://docs.astral.sh/uv/getting-started/installation/)
-
+## 🐳 Docker конфигурация
----
+### Сервисы
+- **django**: Основное приложение Django
+- **postgres**: База данных PostgreSQL
-
-🚀 Основные команды UV
+### Особенности
+- Использование non-root пользователя для безопасности
+- Healthcheck для мониторинга состояния
+- Именованные volumes для постоянства данных
+- Изолированная сеть для сервисов
-### Управление Python-окружением
+## 📦 Управление зависимостями с UV
-**Установка конкретной версии Python:**
+### Установка UV
```bash
-uv python install 3.13 # Установит Python 3.13
-```
+# macOS/Linux
+curl -LsSf https://astral.sh/uv/install.sh | sh
-### Управление зависимостями
+# Windows (PowerShell)
+powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
+```
-**Синхронизация зависимостей проекта:**
+### Основные команды UV
```bash
-uv sync # Аналог pip install + pip-compile
+uv sync # Синхронизировать зависимости
+uv add package # Добавить пакет
+uv remove package # Удалить пакет
+uv run command # Запустить команду в окружении
+uv python install 3.13 # Установить Python 3.13
```
-**Запуск команд в окружении проекта:**
+## 🔍 Линтинг и форматирование
+
+Проект использует **Ruff** для проверки качества кода:
+
```bash
-uv run # Например: uv run pytest
+# Проверка кода
+uvx ruff check .
+
+# Автоматическое исправление
+uvx ruff check --fix .
+
+# Форматирование
+uvx ruff format .
```
-**Запуск Django-сервера:**
+### Pre-commit хуки
```bash
-uv run manage.py runserver # Альтернатива python manage.py runserver
-```
-
+# Установка pre-commit
+uv add --dev pre-commit
----
+# Установка хуков
+pre-commit install
-
-🔍 Интеграция с Ruff
+# Запуск вручную
+pre-commit run --all-files
+```
-### [Ruff](https://github.com/astral-sh/ruff) - это молниеносный линтер для Python, также разработанный Astral.
+## 🔧 Конфигурация
-**Установка Ruff через UV:**
-```bash
-uvx ruff # Установит последнюю версию Ruff
-```
+### Переменные окружения
+Скопируйте `.env.example` в `.env` и настройте:
-**Проверка кода с помощью Ruff:**
```bash
-uvx ruff check . # Проверит все файлы в текущей директории
+# Базовые настройки
+DEBUG=True
+SECRET_KEY=your-secret-key
+ALLOWED_HOSTS=localhost,127.0.0.1
+
+# База данных
+POSTGRES_DB=pythonbooks
+POSTGRES_USER=postgres
+POSTGRES_PASSWORD=your-password
```
-**Для отправки в github без проверки локально, использовать:**
+### Настройки для продакшена
```bash
-git commit -m "feat: comment" --no-verify
+DEBUG=False
+SECURE_SSL_REDIRECT=True
+SESSION_COOKIE_SECURE=True
+CSRF_COOKIE_SECURE=True
```
-**Полный список поддерживаемых опций ruff**
+## 🚀 Деплой
+
+### Продакшен с Docker
```bash
-ruff check --help
+make prod-build # Собрать продакшен образы
+make prod-up # Запустить продакшен
+make prod-down # Остановить продакшен
```
+### Здоровье приложения
```bash
-ruff check --fix . # базовый линтинг с автоисправлением
-ruff check --exclude tests/ . # игнорировать папку tests/
-ruff check --target-version py310 . # проверка кода для Python 3.10+
-ruff check --select / --ignore # выбор правил (например, --select=E501,F401)
+curl http://localhost:8000/health/ # Проверка состояния
```
-
+## 📝 Особенности проекта
----
+### Скрейпинг книг
+- Автоматический сбор данных о книгах
+- Настраиваемые скрейперы в `apps/books/scrapers/`
+- Контроль частоты запросов
-
-🔍 автоматическая проверка Ruff перед коммитом
+### Администрирование
+- Расширенная админ-панель Django
+- Управление книгами и авторами
+- Массовые операции
-[Ruff](https://github.com/astral-sh/ruff) - это молниеносный линтер для Python, также разработанный Astral.
+### API
+- RESTful API для работы с данными
+- Аутентификация и авторизация
+- Документация API
-**Установить pre-commit:**
-```bash
-uv pip install pre-commit
-```
+## 🤝 Участие в разработке
-**Добавьте конфиг .pre-commit-config.yaml:**
-```bash
-repos:
- - repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.11.10 # Актуальная версия Ruff (проверьте на GitHub)
- hooks:
- - id: ruff
- args: [--fix] # Автоматически исправляет ошибки
- - id: ruff-format # Проверка форматирования (если нужно)
-```
+1. Форкните репозиторий
+2. Создайте ветку для функции: `git checkout -b feature/amazing-feature`
+3. Зафиксируйте изменения: `git commit -m 'Add amazing feature'`
+4. Отправьте в ветку: `git push origin feature/amazing-feature`
+5. Создайте Pull Request
-**Установите хуки в репозиторий:**
-```bash
-pre-commit install
-```
-Теперь Ruff будет запускаться перед каждым коммитом.
+### Правила разработки
+- Используйте `make format` перед коммитом
+- Все тесты должны проходить
+- Добавляйте тесты для новой функциональности
+- Следуйте PEP 8 стандартам
+
+## 📊 Мониторинг
-**Проверить работу вручную:**
+### Логи
```bash
-pre-commit run --all-files
+make logs # Все логи
+docker-compose logs django # Только Django
```
-Теперь Ruff будет запускаться перед каждым коммитом.
-
+### Метрики
+- Health checks для контейнеров
+- Мониторинг состояния БД
+- Отслеживание производительности
----
+## 🔗 Полезные ссылки
-## Запуск проекта в Docker
+- [Django Documentation](https://docs.djangoproject.com/)
+- [UV Documentation](https://docs.astral.sh/uv/)
+- [Ruff Documentation](https://docs.astral.sh/ruff/)
+- [Docker Documentation](https://docs.docker.com/)
+- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
-**Сборка и запуск контейнеров:**
-```bash
-docker-compose build --no-cache
-docker-compose up # Соберет и запустит сервисы
-```
\ No newline at end of file
+## 📄 Лицензия
+
+Этот проект лицензирован под MIT License - см. файл [LICENSE](LICENSE) для деталей.
+
+## 🆘 Поддержка
+
+Если у вас есть вопросы или проблемы:
+1. Проверьте [Issues](https://github.com/khoshov/pythonbooks/issues)
+2. Создайте новый Issue с подробным описанием
+3. Используйте `make health` для диагностики
+
+---
+
+**Разработано с ❤️ используя современные инструменты Python**
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 0633a2b..9d4e2d2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,3 +1,5 @@
+version: '3.8'
+
services:
django:
build: .
@@ -15,14 +17,33 @@ services:
depends_on:
postgres:
condition: service_healthy
+ restart: unless-stopped
+ networks:
+ - pythonbooks-network
postgres:
- image: postgres
+ image: postgres:15-alpine
+ container_name: pythonbooks-postgres
ports:
- "5432:5432"
env_file:
- .env
volumes:
- - ./pgdata:/var/lib/postgresql/data
+ - postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 10s
+ restart: unless-stopped
+ networks:
+ - pythonbooks-network
+
+volumes:
+ postgres_data:
+ driver: local
+
+networks:
+ pythonbooks-network:
+ driver: bridge
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index e69de29..0000000