ИС для автоматизации фитнес-кафе с публичным меню, заказами, техкартами, складом, live-статусами и backoffice.
Основной стек:
- Django 5
- PostgreSQL
- Redis
- Nginx
- Celery Worker
- Celery Beat
- Flower
- Tailwind CSS через
django-tailwind-cli, безnode - Docker и
docker compose .envи автоматическая генерацияDJANGO_SECRET_KEY- однократная подготовка через
do.py
Шаблон теперь работает в docker-first режиме.
Основной сценарий не создает .venv и не поднимает Django/Celery локально.
Весь runtime-стек запускается только в контейнерах.
Локальный Python нужен только для:
- запуска
do.py - переименования шаблона
- генерации
.env
Старые shell-скрипты под локальный .venv удалены.
Вспомогательные команды теперь тоже завязаны только на Docker.
Контейнерный runtime больше не зависит от do.py: bootstrap вынесен в отдельный одноразовый сервис bootstrap, а web только стартует Django.
Внешняя точка входа в приложение теперь идет через nginx, а сам Django-контейнер живет только во внутренней docker-сети.
Изначально используются такие имена:
- пакет проекта:
workspace - отображаемое имя проекта:
Workspace - основной app:
core
- Один раз подготовьте шаблон:
Linux/macOS:
python3 ./do.py --project-name PetTrace --app-name coreWindows:
python .\do.py --project-name PetTrace --app-name coreМожно и без аргументов. Если шаблон еще не переименован, do.py спросит имя проекта и app в консоли.
- После этого запускайте проект обычным Docker-способом:
docker compose up --buildДля фонового режима:
docker compose up -d --buildЕсли .env уже создан и rename уже выполнен, do.py больше не нужен для обычной работы.
Основной запуск:
docker compose up --buildЧто делает do.py:
- при необходимости переименовывает шаблон
- создает
.envиз.env.example - генерирует
DJANGO_SECRET_KEY - при конфликте старых docker volumes предлагает удалить только связанные legacy-ресурсы
- подготавливает проект к обычному запуску через
docker compose
После успешного rename скрипт пытается удалить унаследованный .git.
Если Windows блокирует .git, setup больше не падает: будет предупреждение, и папку можно удалить вручную позже.
Сейчас do.py всегда работает как разовый подготовительный скрипт и не держит runtime-стек.
Флаг --prepare-only оставлен только для обратной совместимости и эквивалентен обычному запуску do.py.
python3 ./do.py --prepare-onlyТеперь postgres и redis не публикуются наружу на хост.
Они доступны только внутри docker-сети проекта.
Наружу публикуются только:
NGINX_PORTдля основного сайтаFLOWER_BINDдля Flower
По умолчанию:
http://127.0.0.1/http://localhost/http://127.0.0.1:5555/
Сам web контейнер наружу не публикуется.
nginx проксирует запросы во внутренний Django-сервис, поэтому в браузере можно заходить без явного :8000.
Первый docker compose up --build сам:
- собирает образы
- поднимает
postgres,redis, одноразовыйbootstrap, затемnginx,web,celery_worker,celery_beat,flower - выполняет bootstrap Django в отдельном контейнере
bootstrap - запускает Tailwind watcher в dev-режиме
web больше не мигрирует БД сам при старте. Это сделано специально, чтобы:
- запуск через
docker compose up --buildработал безdo.py - bootstrap не прятался внутри
web - ошибка инициализации была видна в логах сервиса
bootstrap
Если bootstrap не проходит, сначала смотрите:
docker compose logs bootstrapЕсли в логе есть ошибка вида auth_user does not exist или сообщение про stale/corrupted migration state, почти всегда виноват старый volume PostgreSQL:
docker compose down -v --remove-orphans
docker compose up --buildЕсли нужен доступ к PostgreSQL или Redis с хоста, порты нужно добавить в docker-compose.yml вручную.
В dev-режиме контейнерный web сервис запускается через:
python manage.py tailwind runserverПоэтому:
- HTML подхватывается сразу
- обычные CSS/JS static-файлы подхватываются сразу
- Tailwind пересобирается автоматически
collectstaticдля разработки не нужен
Для dev-режима в шаблоне включен polling-based watch поверх django-tailwind-cli.
Это сделано специально, потому что штатный Tailwind watch на bind mount'ах и на Windows может пропускать изменения или оставлять в выходном CSS уже неиспользуемые классы.
Файл шаблона:
.env.exampleРабочий файл:
.envБазовые переменные:
PROJECT_NAMEPROJECT_SLUGDJANGO_ENVDJANGO_DEBUGDJANGO_SECRET_KEYDJANGO_ALLOWED_HOSTSDJANGO_CSRF_TRUSTED_ORIGINSDATABASE_URLPOSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_HOSTPOSTGRES_PORTREDIS_URLCELERY_BROKER_URLCELERY_RESULT_BACKENDNGINX_PORTFLOWER_BINDDATABASE_CONN_MAX_AGEDATABASE_CONN_HEALTH_CHECKSDJANGO_SESSION_COOKIE_SECUREDJANGO_CSRF_COOKIE_SECUREDJANGO_SECURE_SSL_REDIRECTDJANGO_SECURE_HSTS_SECONDSTAILWIND_CLI_SRC_CSS(src/workspace/tailwind.src.css)
По умолчанию .env.example уже настроен под docker-сеть:
POSTGRES_HOST=postgresREDIS_HOST=redisCOMPOSE_PROJECT_NAME=PROJECT_SLUGNGINX_PORT=80
Для runtime теперь есть две служебные точки:
/health/— liveness, быстрый ответ без зависимостей/ready/— readiness, проверка БД и cache backend
В docker compose добавлены healthcheck'и для web и nginx, поэтому nginx ждет именно готовый Django-контур, а не просто старт процесса.
Перед релизом можно прогнать preflight:
docker compose run --rm web python manage.py preflight_releaseКоманда:
- запускает
check --deploy - валидирует критичные env/runtime-настройки
- проверяет readiness БД и кеша
Если нужен только runtime без cache-пинга:
docker compose run --rm web python manage.py preflight_release --skip-cacheДля демонстрации подготовлен сидер, который разворачивает:
- 3 месяца операционной истории
- заказы, оплаты, частичные возвраты и split payment
- закупки, партии, инвентаризации и смены
- текущие live-заказы для стойки, кухни и публичного статуса
- демо-пользователей по ролям
Запуск:
python manage.py seed_demo_data --reset --months 3Демо-аккаунты:
director / freshbalance123operations / freshbalance123manager / freshbalance123barista / freshbalance123waiter / freshbalance123
В репозитории подготовлен production-контур:
- GitHub Actions:
.github/workflows/ci-cd.yml - прод-overrides compose:
docker-compose.prod.yml - systemd units:
deploy/systemd/ - скрипт раскатки:
scripts/deploy_prod.sh - пример Caddy site block:
deploy/caddy/freshbalance.Caddyfile
Ожидаемый цикл:
- push в
main - GitHub Actions прогоняет миграции, сидер, тесты и
preflight_release - workflow обновляет ветку
deploy/prod - серверный timer подтягивает
deploy/prodи запускаетscripts/deploy_prod.sh
Целевой production path:
/srv/freshbalanceСистемные unit-файлы:
freshbalance-stack.servicefreshbalance-deploy.servicefreshbalance-deploy.timer
Smoke-check после деплоя проверяет:
//health//ready//staff/login//backoffice/(redirect expected)
Переименование при запуске:
python3 ./do.py --project-name ITUWebsite --app-name coreПропустить rename:
python3 ./do.py --skip-renameТолько подготовить окружение:
python3 ./do.py --prepare-onlyСправка:
python3 ./do.py --helpОсновной запуск:
docker compose up --buildОсновной запуск в фоне:
docker compose up -d --buildОстановить стек:
docker compose downОстановить стек и удалить volumes текущего проекта:
docker compose down -vПосмотреть логи:
docker compose logs -fПосмотреть bootstrap отдельно:
docker compose logs bootstrapMakefile тоже переведен на docker-only режим.
make init выполняет разовую подготовку через do.py, а make up уже запускает обычный docker compose up --build.
Основные команды:
make init
make up
make up-d
make prepare
make bootstrap
make down
make reset
make logs
make psПолезные команды для Django:
make migrate
make makemigrations
make createsuperuser
make shell
make check
make tailwind-buildПроверки:
make lint
make testВсе management-команды теперь предполагаются внутри web контейнера.
Примеры:
docker compose exec web python manage.py createsuperuser
docker compose exec web python manage.py makemigrations
docker compose exec web python manage.py migrate
docker compose exec web python manage.py shellЕсли стек еще не запущен, можно использовать one-off контейнер:
docker compose run --rm web python manage.py checkСкрипт scripts/rename_template.py обновляет:
- пакет проекта в
src/workspace - основной app в
src/apps/core - контейнерный
manage.pyвsrc/manage.py - пути шаблонов app
- Python imports
- compose-related идентификаторы в конфигурации
- placeholder-строки в конфигурации и документации
Пример dry-run:
python3 ./scripts/rename_template.py --project-name PetTrace --app-name core --dry-runsrc/workspace— пакет Django-проектаsrc/workspace/settings— настройки проектаsrc/apps/core— основной app-шаблонsrc/manage.py— основная точка запуска Django внутри контейнераtemplates— общие шаблоныassets— Tailwind source и собранный CSSscripts— служебные скриптыdocker— docker runtime и конфигnginx
Команда python manage.py startapp blog внутри контейнера теперь по умолчанию создает app в src/apps/blog, а не в корне проекта.
Если проект уже переименован, а в Docker остался старый volume от предыдущего имени, do.py сам покажет только конфликтующие legacy-ресурсы и предложит удалить их по номерам.
Теперь это не останавливает setup.
do.py попробует удалить .git с повторной попыткой и правами на запись.
Если не получится, он просто выведет warning.
Измените NGINX_PORT или FLOWER_BIND в .env, затем перезапустите:
docker compose up --build