From 8551d58d085ae2f2fff75103bc2cf58a71cb6eb8 Mon Sep 17 00:00:00 2001 From: emelinda Date: Thu, 23 Jul 2026 18:21:11 +0300 Subject: [PATCH] Update frontend image in `.env.example` for contour compatibility --- .env.example | 2 ++ aero/pyproject.toml | 2 ++ aero/roles/sarex_stack/tasks/main.yml | 48 +++++++++++++++++++++++++++ docker-compose.yaml | 8 +++++ nginx/templates/default.conf.template | 33 +++++++++++------- 5 files changed, 81 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index db17c71..5eb9c69 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,8 @@ SAREX_POSTGRES_PASSWORD=sarex # Приложения ходят в БД под ними, а не под суперпользователем. Без одинарных кавычек. SAREX_DJANGO_DB_USER=django SAREX_DJANGO_DB_PASSWORD=django-secret +# Расширения PostgreSQL для базы django (создаёт postgres-init суперпользователем) +SAREX_DJANGO_DB_EXTENSIONS=ltree SAREX_PROCESSING_DB_USER=processing SAREX_PROCESSING_DB_PASSWORD=processing-secret SAREX_BIM_DB_USER=bim diff --git a/aero/pyproject.toml b/aero/pyproject.toml index f289b54..47a489b 100644 --- a/aero/pyproject.toml +++ b/aero/pyproject.toml @@ -36,6 +36,8 @@ deploy-check = "ansible-playbook deploy.yml --check --diff" gen-env = "ansible-playbook deploy.yml --tags env" # docker login в приватный реестр по ключу json_key login = "ansible-playbook deploy.yml --tags login" +# сгенерировать логин+пароль и создать Django-суперпользователя в backend +superuser = "ansible-playbook deploy.yml --tags superuser" lint = "ansible-lint" # Полная подготовка окружения: uv sync + установка коллекций diff --git a/aero/roles/sarex_stack/tasks/main.yml b/aero/roles/sarex_stack/tasks/main.yml index f4e33f8..1b51f1b 100644 --- a/aero/roles/sarex_stack/tasks/main.yml +++ b/aero/roles/sarex_stack/tasks/main.yml @@ -125,3 +125,51 @@ chdir: "{{ deploy_dir }}" when: sarex_compose_up | bool changed_when: true + +# --- Django-суперпользователь: генерация логина+пароля, создание ----------- +# Логин и пароль генерируются один раз и персистятся в secrets_store +# (переиспользуются при повторе — идемпотентно). +- name: Сгенерировать логин суперпользователя + ansible.builtin.set_fact: + superuser_name: "{{ lookup('password', secrets_store ~ '/' ~ inventory_hostname ~ '/SAREX_SUPERUSER_NAME chars=ascii_lowercase,digits length=10') }}" + no_log: true + tags: [superuser] + +- name: Сгенерировать пароль суперпользователя + ansible.builtin.set_fact: + superuser_password: "{{ lookup('password', secrets_store ~ '/' ~ inventory_hostname ~ '/SAREX_SUPERUSER_PASSWORD chars=ascii_letters,digits length=' ~ secret_length) }}" + no_log: true + tags: [superuser] + +- name: Создать/обновить Django-суперпользователя в backend + ansible.builtin.command: + argv: + - "{{ compose_cmd.split()[0] }}" + - exec + - -e + - "SU_NAME={{ superuser_name }}" + - -e + - "SU_PASS={{ superuser_password }}" + - -e + - "SU_EMAIL={{ superuser_name }}@{{ platform_domain }}" + - sarex-backend + - python + - manage.py + - shell + - -c + - >- + import os; + from django.contrib.auth import get_user_model; + U = get_user_model(); + u, c = U.objects.get_or_create(username=os.environ['SU_NAME'], defaults={'email': os.environ['SU_EMAIL']}); + u.is_staff = True; u.is_superuser = True; u.set_password(os.environ['SU_PASS']); u.save(); + print('created' if c else 'updated') + register: superuser_result + changed_when: true + no_log: true + tags: [superuser] + +- name: Показать учётные данные суперпользователя + ansible.builtin.debug: + msg: "Django superuser → login: {{ superuser_name }} password: {{ superuser_password }}" + tags: [superuser] diff --git a/docker-compose.yaml b/docker-compose.yaml index 5b2d4e9..745e180 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -147,6 +147,13 @@ services: provision "$$PROC_DB" "$$PROC_USER" "$$PROC_PASSWORD" provision "$$BIM_DB" "$$BIM_USER" "$$BIM_PASSWORD" provision "$$WORKSPACE_DB" "$$WORKSPACE_USER" "$$WORKSPACE_PASSWORD" + + # Расширения PostgreSQL в базе django: CREATE EXTENSION может только + # суперпользователь. Django-миграции (CreateExtension) идут с IF NOT + # EXISTS → после этого станут no-op и не упадут на правах. + for ext in $$DJANGO_EXTENSIONS; do + q -c "CREATE EXTENSION IF NOT EXISTS \"$$ext\"" && echo "extension $$ext ready in $$DJANGO_DB" + done environment: PGPASSWORD: ${SAREX_POSTGRES_PASSWORD:-sarex} SUPER_USER: ${SAREX_POSTGRES_USER:-sarex} @@ -155,6 +162,7 @@ services: DJANGO_DB: ${SAREX_POSTGRES_DB:-sarex_db} DJANGO_USER: ${SAREX_DJANGO_DB_USER:-django} DJANGO_PASSWORD: ${SAREX_DJANGO_DB_PASSWORD:-django-secret} + DJANGO_EXTENSIONS: ${SAREX_DJANGO_DB_EXTENSIONS:-ltree} # processing PROC_DB: ${SAREX_PROCESSING_DB:-workflow_db} PROC_USER: ${SAREX_PROCESSING_DB_USER:-processing} diff --git a/nginx/templates/default.conf.template b/nginx/templates/default.conf.template index 04f3d62..4b33573 100644 --- a/nginx/templates/default.conf.template +++ b/nginx/templates/default.conf.template @@ -27,7 +27,7 @@ map $http_upgrade $connection_upgrade { } upstream backend { server backend:8000; } -# upstream frontend { server frontend:80; } # frontend пока не поднят +upstream frontend { server frontend:80; } upstream minio_s3 { server minio:9000; } upstream minio_console { server minio:9001; } upstream rabbitmq_mgmt { server rabbitmq:15672; } @@ -55,6 +55,15 @@ server { return 200 "ok\n"; } + # Рантайм-конфиг фронта. Прод-сборка по умолчанию уходит в zitadel, которого + # тут нет, — форсим классический вход через backend (auth_type=original). + # Отдаём сами: в образе frontend этого файла нет (был бы 404). + location = /static/config.json { + default_type application/json; + add_header Cache-Control "no-store"; + return 200 '{"auth_type":"original"}'; + } + # Django backend: REST API + админка location /api/ { proxy_pass http://backend; } location /admin/ { proxy_pass http://backend; } @@ -96,17 +105,17 @@ server { # proxy_pass http://minio_s3; # } - # Frontend SPA (host-приложение само отдаёт статику и роутинг) (TODO: в работе) - # location / { - # 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_http_version 1.1; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection $connection_upgrade; - # proxy_pass http://frontend; - # } + # Frontend SPA (host-приложение само отдаёт статику и роутинг) + location / { + 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_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_pass http://frontend; + } } # ======================= Admin: RabbitMQ management UI ======================