diff --git a/.env.example b/.env.example index 035f6d7..2040b3b 100644 --- a/.env.example +++ b/.env.example @@ -21,6 +21,9 @@ SAREX_JWT_PRIVATE_KEY=changeme SAREX_JWT_PUBLIC_KEY=changeme SAREX_PROCESSING_DB_USER=processing SAREX_PROCESSING_DB_PASSWORD=processing-secret +# Расширения PostgreSQL для workflow_db (создаёт postgres-init суперпользователем; +# роль processing прав на CREATE EXTENSION не имеет). Нужны миграциям workflows-api. +SAREX_PROCESSING_DB_EXTENSIONS=uuid-ossp ltree hstore SAREX_BIM_DB_USER=bim SAREX_BIM_DB_PASSWORD=bim-secret SAREX_WORKSPACE_DB_USER=workspace diff --git a/aero/pyproject.toml b/aero/pyproject.toml index c674df3..cb6b1d4 100644 --- a/aero/pyproject.toml +++ b/aero/pyproject.toml @@ -44,6 +44,43 @@ login = "ansible-playbook deploy.yml --tags login" superuser = "ansible-playbook deploy.yml -e sarex_create_superuser=true --tags superuser" lint = "ansible-lint" +# --- Операционные задачи на хосте (без полного деплоя) ---------------------- +# Поднять/пересоздать сервисы приложения (docker compose up -d sarex_services). +# Только тег up: не трогает файлы/.env/сертификаты/login, лишь применяет стек. +up = "ansible-playbook deploy.yml -e sarex_compose_up=true --tags up" + +[tool.poe.tasks.ps] +cmd = "ansible docker_hosts -m ansible.builtin.shell -a 'docker compose ps chdir=/root/sarex'" +help = "Статус стека на хосте (docker compose ps)" + +[tool.poe.tasks.pull] +cmd = "ansible docker_hosts -m ansible.builtin.shell -a 'docker compose pull ${service} chdir=/root/sarex'" +help = "Стянуть образы: uv run poe pull [service]" +[[tool.poe.tasks.pull.args]] +name = "service" +positional = true +default = "" + +[tool.poe.tasks.logs] +cmd = "ansible docker_hosts -m ansible.builtin.shell -a 'docker compose logs --no-color --tail ${tail} ${service} chdir=/root/sarex'" +help = "Логи сервиса(ов): uv run poe logs [service] [--tail N]" +[[tool.poe.tasks.logs.args]] +name = "service" +positional = true +default = "" +[[tool.poe.tasks.logs.args]] +name = "tail" +options = ["--tail"] +default = "80" + +[tool.poe.tasks.restart] +cmd = "ansible docker_hosts -m ansible.builtin.shell -a 'docker compose restart ${service} chdir=/root/sarex'" +help = "Перезапустить сервис: uv run poe restart " +[[tool.poe.tasks.restart.args]] +name = "service" +positional = true +required = true + # Подготовка окружения: uv sync + установка коллекций [tool.poe.tasks.setup] sequence = ["sync", "galaxy"] diff --git a/aero/roles/sarex_stack/handlers/main.yml b/aero/roles/sarex_stack/handlers/main.yml new file mode 100644 index 0000000..5d30e18 --- /dev/null +++ b/aero/roles/sarex_stack/handlers/main.yml @@ -0,0 +1,20 @@ +--- +# Пересоздание контейнеров при изменении их bind-mount конфигов. +# docker compose up -d НЕ пересоздаёт контейнер, если поменялся только +# смонтированный файл (шаблон nginx, production.py) — контент тома он не +# отслеживает. Поэтому на изменение конфига форсим --force-recreate конкретного +# сервиса. Срабатывает только когда стек реально поднимается (sarex_compose_up), +# иначе на обычном deploy без up мы бы стартовали контейнеры. +- name: Recreate nginx + ansible.builtin.command: + cmd: "{{ compose_cmd }} up -d --force-recreate --no-deps nginx" + chdir: "{{ deploy_dir }}" + when: sarex_compose_up | bool + +- name: Recreate backend and celery + # Оба монтируют ./backend/production.py (celery — ещё и через тот же файл), + # поэтому пересоздаём вместе. + ansible.builtin.command: + cmd: "{{ compose_cmd }} up -d --force-recreate --no-deps backend celery" + chdir: "{{ deploy_dir }}" + when: sarex_compose_up | bool diff --git a/aero/roles/sarex_stack/tasks/main.yml b/aero/roles/sarex_stack/tasks/main.yml index dade3fd..db80b9b 100644 --- a/aero/roles/sarex_stack/tasks/main.yml +++ b/aero/roles/sarex_stack/tasks/main.yml @@ -17,19 +17,23 @@ # nginx монтирует ./nginx/templates и ./nginx/certs — без шаблонов nginx не # стартует, поэтому копируем конфигурацию рядом с compose. +# Изменение шаблона → handler пересоздаёт nginx (envsubst рендерит на старте). - name: Скопировать шаблоны nginx ansible.builtin.copy: src: "{{ deploy_src_root }}/nginx/templates/" dest: "{{ deploy_dir }}/nginx/templates/" mode: "0644" + notify: Recreate nginx # backend монтирует ./backend/uwsgi.ini (http-socket + 4 воркера) и -# ./backend/production.py (классическая JWT-аутентификация) +# ./backend/production.py (классическая JWT-аутентификация). +# Изменение конфигов → handler пересоздаёт backend и celery. - name: Скопировать конфиги backend (uwsgi.ini, production.py) ansible.builtin.copy: src: "{{ deploy_src_root }}/backend/" dest: "{{ deploy_dir }}/backend/" mode: "0644" + notify: Recreate backend and celery # --- Секреты: генерация с персистом на control-node (идемпотентно) -------- - name: Сгенерировать/загрузить пароли (persist в secrets_store, gitignored) diff --git a/docker-compose.yaml b/docker-compose.yaml index e0065ee..90c5125 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -154,6 +154,14 @@ services: for ext in $$DJANGO_EXTENSIONS; do q -c "CREATE EXTENSION IF NOT EXISTS \"$$ext\"" && echo "extension $$ext ready in $$DJANGO_DB" done + + # Расширения для processing (workflow_db) — ОТДЕЛЬНАЯ база, поэтому явно + # -d PROC_DB. Роль processing не суперпользователь → CREATE EXTENSION в + # её миграциях (uuid-ossp/ltree/hstore) падает; заводим суперпользователем. + for ext in $$PROC_EXTENSIONS; do + psql -v ON_ERROR_STOP=1 -h postgres -U "$$SUPER_USER" -d "$$PROC_DB" \ + -c "CREATE EXTENSION IF NOT EXISTS \"$$ext\"" && echo "extension $$ext ready in $$PROC_DB" + done environment: PGPASSWORD: ${SAREX_POSTGRES_PASSWORD:-sarex} SUPER_USER: ${SAREX_POSTGRES_USER:-sarex} @@ -167,6 +175,7 @@ services: PROC_DB: ${SAREX_PROCESSING_DB:-workflow_db} PROC_USER: ${SAREX_PROCESSING_DB_USER:-processing} PROC_PASSWORD: ${SAREX_PROCESSING_DB_PASSWORD:-processing-secret} + PROC_EXTENSIONS: ${SAREX_PROCESSING_DB_EXTENSIONS:-uuid-ossp ltree hstore} # bim BIM_DB: ${SAREX_BIM_DB:-bim_db} BIM_USER: ${SAREX_BIM_DB_USER:-bim} @@ -305,6 +314,13 @@ services: # проксирует их в s3-proxy (CORS+Range). Из apps/django/base/backend-deployment.yaml. SERVER_USE_DJANGO_STORAGE: "1" SERVER_DJANGO_URLS: "1" + # processing (workflows-api): backend ходит в processing-api за workflow'ами. + # WORKFLOWSSETTINGS.host строит COMPARISON/DOCUMENTATION/PDM_FILES_API_URL. + # По умолчанию use=False и host=api.sarex.io — переопределяем на наш стек. + WORKFLOWS_USE: "1" + WORKFLOWS_HOST: http://processing-api:8080 + WORKFLOWS_BASE_HOST: http://backend:8000 + WORKFLOWS_PREFIX: /internal/v1 tty: true ports: - "8000:8000" # HTTP API (uWSGI http-socket), migrate выполняется в entrypoint