From 4f57d594c9e8758df4219b31cf8de505267c305d Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Thu, 8 Jan 2026 22:16:39 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B2=20docker:=20entrypoint.sh=20=D0=B8?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D1=80=D0=B0=D0=B7=D0=B2=D0=B5=D1=80=D1=82?= =?UTF-8?q?=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- myproject/docker/DEPLOY_NAS.md | 52 +++++++++++++++------------------- myproject/docker/entrypoint.sh | 43 ++++++++++++++-------------- 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/myproject/docker/DEPLOY_NAS.md b/myproject/docker/DEPLOY_NAS.md index c8658fd..d8a65f2 100644 --- a/myproject/docker/DEPLOY_NAS.md +++ b/myproject/docker/DEPLOY_NAS.md @@ -102,10 +102,10 @@ REDIS_DB=0 # Celery CELERY_BROKER_URL=redis://redis:6379/0 -# Tenant Admin (создаётся при первом запуске) -TENANT_ADMIN_EMAIL=admin@example.com -TENANT_ADMIN_PASSWORD=ваш-админ-пароль -TENANT_ADMIN_NAME=Admin +# Platform Admin (администратор платформы - создаётся автоматически) +PLATFORM_ADMIN_EMAIL=admin@mix.smaa.by +PLATFORM_ADMIN_PASSWORD=ваш-надёжный-пароль-минимум-16-символов +PLATFORM_ADMIN_NAME=Platform Admin # Django-tenants PUBLIC_SCHEMA_DOMAIN=mix.smaa.by @@ -171,8 +171,9 @@ docker-compose logs -f При первом запуске автоматически: 1. Создаётся база данных PostgreSQL 2. Применяются миграции Django -3. Создаётся суперпользователь: `slamfromm@gmail.com` / `GKh^768&T9` -4. Собираются статические файлы +3. Собираются статические файлы +4. Создаётся public tenant +5. **Создаётся PlatformAdmin** из переменных `PLATFORM_ADMIN_*` в `.env.docker` ### Проверка работоспособности: ```bash @@ -258,34 +259,27 @@ server { ## Создание тенантов (магазинов) -После запуска системы, войдите в админку `https://mix.smaa.by/admin/` и создайте: +**Рекомендуемый способ:** Через форму регистрации и активацию в админке. -1. **Client (Тенант)** - новый магазин -2. **Domain** - привяжите домен, например `shop1.mix.smaa.by` +1. Пользователь заполняет форму на `https://mix.smaa.by/register/` +2. PlatformAdmin входит в `https://mix.smaa.by/admin/` +3. В разделе "Заявки на регистрацию" нажимает "Активировать" -### Через Django shell: -```bash -docker-compose exec web python manage.py shell -``` +При активации автоматически: +- Создаётся тенант и домен +- Применяются миграции +- Создаётся владелец (CustomUser) +- Инициализируются данные (склад, статусы и т.д.) +- Отправляется email с ссылкой для установки пароля -```python -from tenants.models import Client, Domain +### Архитектура пользователей -# Создаём тенант -tenant = Client( - schema_name='shop1', - name='Магазин 1', -) -tenant.save() +| Модель | Schema | Доступ | +|--------|--------|--------| +| `PlatformAdmin` | public | Django Admin везде | +| `CustomUser` | tenant | Только фронтенд | -# Привязываем домен -domain = Domain( - domain='shop1.mix.smaa.by', - tenant=tenant, - is_primary=True -) -domain.save() -``` +PlatformAdmin может войти в Django Admin любого тенанта для техподдержки. ## Полезные команды diff --git a/myproject/docker/entrypoint.sh b/myproject/docker/entrypoint.sh index 9c1c2c7..53494a2 100644 --- a/myproject/docker/entrypoint.sh +++ b/myproject/docker/entrypoint.sh @@ -148,32 +148,33 @@ run_migrations() { python /app/docker/create_public_tenant.py } -# Создание суперпользователя если не существует -create_superuser() { - echo "Creating superuser if not exists..." +# Создание PlatformAdmin если не существует +create_platform_admin() { + echo "Creating PlatformAdmin if not exists..." python manage.py shell << EOF -from django.contrib.auth import get_user_model -from django.db import connection -from django_tenants.utils import schema_context +from platform_admin.models import PlatformAdmin import os -User = get_user_model() +# Создаём PlatformAdmin из переменных окружения +email = os.environ.get('PLATFORM_ADMIN_EMAIL', 'admin@platform.com') +password = os.environ.get('PLATFORM_ADMIN_PASSWORD') +name = os.environ.get('PLATFORM_ADMIN_NAME', 'Platform Admin') -# Создаём суперпользователя в public схеме из переменных окружения -with schema_context('public'): - email = os.environ.get('TENANT_ADMIN_EMAIL', 'admin@example.com') - password = os.environ.get('TENANT_ADMIN_PASSWORD', 'changeme') - first_name = os.environ.get('TENANT_ADMIN_NAME', 'Admin') - - if not User.objects.filter(email=email).exists(): - user = User.objects.create_superuser( +if not password: + print('WARNING: PLATFORM_ADMIN_PASSWORD not set. Skipping PlatformAdmin creation.') + print('Create PlatformAdmin manually via Django shell:') + print(' from platform_admin.models import PlatformAdmin') + print(' PlatformAdmin.objects.create_superuser(email="...", name="...", password="...")') +else: + if not PlatformAdmin.objects.filter(email=email).exists(): + admin = PlatformAdmin.objects.create_superuser( email=email, - password=password, - name=first_name + name=name, + password=password ) - print(f'Superuser {email} created successfully!') + print(f'PlatformAdmin {email} created successfully!') else: - print(f'Superuser {email} already exists.') + print(f'PlatformAdmin {email} already exists.') EOF } @@ -199,7 +200,7 @@ case "$1" in wait_for_redis setup_directories run_migrations - create_superuser + create_platform_admin echo "Starting Gunicorn..." exec gunicorn myproject.wsgi:application \ --bind 0.0.0.0:8000 \ @@ -228,7 +229,7 @@ case "$1" in migrate) wait_for_postgres run_migrations - create_superuser + create_platform_admin ;; collectstatic) wait_for_postgres