# 🛍 ENF — Интернет-магазин одежды
**Django 5.2 + PostgreSQL 16 + Docker (Dev/Prod) + HTMX + Alpine.js**
ENF — интернет-магазин одежды на Django с современным фронтенд-подходом (HTMX + Alpine.js), PostgreSQL и полностью предсказуемой инфраструктурой запуска в Docker. Проект поддерживает отдельные окружения разработки и продакшена через раздельные настройки `settings/base.py`, `settings/dev.py`, `settings/prod.py` и отдельные env-файлы `.env.dev` / `.env.prod`.
---
## 🌟 Особенности проекта
- **Современный стек**: Django 5.2 + HTMX + Alpine.js
- **База данных**: PostgreSQL 16
- **Docker-контейнеризация** (dev и prod)
- **Раздельные окружения**: `dev` / `prod` через `DJANGO_SETTINGS_MODULE`
- **Кастомная модель пользователя**: `AUTH_USER_MODEL = 'users.CustomUser'`
- **Платёжные системы**:
- Stripe
- Heleket (крипто)
- **Безопасность в prod**:
- CSRF и secure cookies
- Security headers
- HSTS (при HTTPS)
- Ограниченные `ALLOWED_HOSTS`
- **Dev без сюрпризов**: никаких `Secure` cookies и HTTPS-ограничений в разработке
---
## 🧱 Структура проекта (после изменений)
Рекомендуемая структура файлов и настроек:
```text
enf/
├── enf/
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── dev.py
│ │ └── prod.py
│ ├── urls.py
│ ├── wsgi.py
│ └── asgi.py
│
├── docker/
│ └── nginx/
│ └── nginx.conf
│
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── Dockerfile
├── .env.dev
├── .env.prod
├── manage.py
├── requirements.txt
└── README.mdВ этой схеме файл
enf/settings.pyбольше не используется. Настройки берутся из пакетаenf/settings/через переменнуюDJANGO_SETTINGS_MODULE.
- Docker Engine (актуальная версия)
- Docker Compose v2
- Git
Проверка:
docker --version
docker compose version
git --versionСоздайте файл .env.dev в корне проекта:
DJANGO_SETTINGS_MODULE=enf.settings.dev
DEBUG=True
SECRET_KEY=dev-secret-key
POSTGRES_DB=enfdb
POSTGRES_USER=enfdb
POSTGRES_PASSWORD=enfdb
POSTGRES_HOST=db
POSTGRES_PORT=5432
STRIPE_SECRET_KEY=example
STRIPE_WEBHOOK_SECRET=example
HELEKET_API_KEY=example
HELEKET_SECRET_KEY=exampleВ dev используется
POSTGRES_HOST=db, потому что Django и PostgreSQL находятся в одной docker-сети.
docker compose -f docker-compose.dev.yml up --buildОставьте этот терминал работать (будут логи).
Во втором терминале:
docker compose -f docker-compose.dev.yml exec web python manage.py migratedocker compose -f docker-compose.dev.yml exec web python manage.py createsuperuser- Сайт: http://localhost:8000
- Админка: http://localhost:8000/admin
# Запуск dev
docker compose -f docker-compose.dev.yml up
# Запуск dev в фоне
docker compose -f docker-compose.dev.yml up -d
# Остановка
docker compose -f docker-compose.dev.yml down
# Остановка с удалением volume (полный сброс БД)
docker compose -f docker-compose.dev.yml down -v
# Логи web
docker compose -f docker-compose.dev.yml logs -f web
# Логи db
docker compose -f docker-compose.dev.yml logs -f db# Проверка конфигурации
docker compose -f docker-compose.dev.yml exec web python manage.py check
# Django shell
docker compose -f docker-compose.dev.yml exec web python manage.py shell
# Создание миграций
docker compose -f docker-compose.dev.yml exec web python manage.py makemigrations
# Применение миграций
docker compose -f docker-compose.dev.yml exec web python manage.py migrateЭтот режим возможен, но не рекомендуется, так как ломает идею единообразной среды. Если всё же нужно: в этом режиме Docker DNS (
db) не работает, значитPOSTGRES_HOSTдолжен быть127.0.0.1илиlocalhost.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
export DJANGO_SETTINGS_MODULE=enf.settings.dev
export POSTGRES_HOST=127.0.0.1
python manage.py migrate
python manage.py runserverНужно пробросить порт у db:
ports:
- "5432:5432"И затем в .env для локального запуска:
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432docker compose exec web python manage.py makemigrations
docker compose exec web python manage.py migrate
docker compose exec web python manage.py createsuperuser
docker compose exec web python manage.py check
docker compose exec web python manage.py collectstatic --noinput
docker exec -it enf-web-1 python manage.py shell
docker compose logssettings/base.py— общие настройки проектаsettings/dev.py— dev-конфигурация (HTTP, без Secure cookies, разрешённые хосты шире)settings/prod.py— prod-конфигурация (HTTPS, Secure cookies, HSTS, строгие хосты)
Выбор окружения выполняется через переменную:
DJANGO_SETTINGS_MODULE=enf.settings.dev
# или
DJANGO_SETTINGS_MODULE=enf.settings.prodКлючевые принципы:
DEBUG=True- HTTP
- безопасные флаги cookie выключены
ALLOWED_HOSTSмаксимально либеральный (обычно['*'])
Пример:
DJANGO_SETTINGS_MODULE=enf.settings.dev
DEBUG=True
SECRET_KEY=dev-secret-key
POSTGRES_DB=enfdb
POSTGRES_USER=enfdb
POSTGRES_PASSWORD=enfdb
POSTGRES_HOST=db
POSTGRES_PORT=5432Ключевые принципы:
DEBUG=False- HTTPS
- secure cookies включены
ALLOWED_HOSTS— домены проекта- сертификаты обслуживаются Nginx
Пример:
DJANGO_SETTINGS_MODULE=enf.settings.prod
DEBUG=False
SECRET_KEY=super-secret-prod-key
POSTGRES_DB=enfdb
POSTGRES_USER=enfdb
POSTGRES_PASSWORD=strong-password
POSTGRES_HOST=db
POSTGRES_PORT=5432webзапускается черезrunserverдля быстрой разработки- docker compose -f docker-compose.dev.yml up -d
- docker compose -f docker-compose.dev.yml build --no-cache
db— PostgreSQL- том для postgres сохраняет данные между перезапусками
Пример логики:
webзависит отdbпо healthcheck- приложение доступно на
http://localhost:8000
Prod обычно включает:
web(gunicorn)dbnginx(TLS, статика, прокси)
После старта в prod обязательно:
migratecollectstatic
- HTTP
- без
Securecookies - без HSTS
- минимальные ограничения (удобство разработки)
- HTTPS
CSRF_COOKIE_SECURE=TrueSESSION_COOKIE_SECURE=TrueSECURE_HSTS_SECONDS=31536000(+ includeSubDomains/preload при необходимости)ALLOWED_HOSTSстрого ограничен доменамиCSRF_TRUSTED_ORIGINSсодержитhttps://...
В продакшене Nginx выполняет:
- TLS termination (сертификаты Let’s Encrypt/другие)
- проксирование запросов на
web - раздачу
static/иmedia/
Если используешь Let’s Encrypt (пример):
sudo certbot --nginx -d domen.com -d www.domen.comВ dev Nginx обычно не нужен.
Если требуется полностью пересоздать PostgreSQL (например, после изменений в архитектуре или env):
docker compose -f docker-compose.dev.yml down -v
docker compose -f docker-compose.dev.yml up --build
docker compose -f docker-compose.dev.yml build --no-cache
docker compose -f docker-compose.dev.yml exec web python manage.py migrate# ОБЯЗАТЕЛЬНАЯ пересборка (правильно)
docker compose -f docker-compose.dev.yml down -v
docker compose -f docker-compose.dev.yml build --no-cache
docker compose -f docker-compose.dev.yml up -d
# Контрольная проверка (после сборки)
docker exec -it enf-web-1 python manage.py shell
# Пример:
from PIL import features
features.check("webp")
features.check("avif")-
Убедитесь, что вы используете
.env.devиDJANGO_SETTINGS_MODULE=enf.settings.dev -
Запуск:
docker compose -f docker-compose.dev.yml up --build
-
Миграции:
docker compose -f docker-compose.dev.yml exec web python manage.py migrate -
Суперпользователь:
docker compose -f docker-compose.dev.yml exec web python manage.py createsuperuser -
Проверка:
docker compose -f docker-compose.dev.yml exec web python manage.py check -
Открыть:
could not translate host name "db"Django запущен не в Docker, аPOSTGRES_HOST=dbотносится к Docker DNS.- Не работает login/CSRF в dev
Включены
CSRF_COOKIE_SECURE=True/SESSION_COOKIE_SECURE=Trueпри работе по HTTP. - 404 на статику в prod
Не сделан
collectstaticили неверно смонтированы volumes в Nginx.
Внешний гайд (репозиторий):
https://github.com/s6ptember/for-deploy-guide.git
- В одном проекте не рекомендуется параллельно держать MySQL/MariaDB и PostgreSQL без необходимости.
- Для PostgreSQL рекомендуется использовать отдельный volume под данные и не смешивать его с другими проектами.
- В dev лучше избегать Nginx и Gunicorn (они нужны в prod).
Уточняется владельцем проекта. Проект для личного и коммерческого использования. Ответственность за платежные интеграции и данные клиентов несёт владелец проекта. Если вы скачали этот проект, вы стали его владельцем.