feat: add production deployment baseline
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Не выпущено
|
## Не выпущено
|
||||||
|
|
||||||
|
- Добавлен production deployment baseline для Search API и OpenSearch с
|
||||||
|
постоянными хранилищами и healthcheck.
|
||||||
- Добавлено восстановление незавершённой разметки из `localStorage` после перезагрузки страницы.
|
- Добавлено восстановление незавершённой разметки из `localStorage` после перезагрузки страницы.
|
||||||
- Добавлена внутренняя лаборатория проверки поисковой выдачи: просмотр документов,
|
- Добавлена внутренняя лаборатория проверки поисковой выдачи: просмотр документов,
|
||||||
оценка релевантности 0–3, комментарии и SQLite-экспорт подписанных снимков.
|
оценка релевантности 0–3, комментарии и SQLite-экспорт подписанных снимков.
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ Telegram-бот — только часть рабочего окружения
|
|||||||
## Текущее состояние
|
## Текущее состояние
|
||||||
|
|
||||||
Сейчас реализованы Telegram-бот-секретарь версии `0.2.2` и backend версии
|
Сейчас реализованы Telegram-бот-секретарь версии `0.2.2` и backend версии
|
||||||
`0.8.1`: добавлено сохранение черновика разметки в браузере.
|
`0.8.2`: добавлен production deployment baseline для Search API и OpenSearch.
|
||||||
размеченном наборе запросов.
|
размеченном наборе запросов.
|
||||||
|
|
||||||
| Компонент | Версия | Состояние |
|
| Компонент | Версия | Состояние |
|
||||||
|---|---:|---|
|
|---|---:|---|
|
||||||
| Telegram-бот | `0.2.2` | на Synology работает `0.2.1`; обновление после слияния |
|
| Telegram-бот | `0.2.2` | на Synology работает `0.2.1`; обновление после слияния |
|
||||||
| Backend | `0.8.1` | добавлено сохранение черновика разметки |
|
| Backend | `0.8.2` | добавлен production deployment baseline |
|
||||||
| Frontend | — | ещё не создан |
|
| Frontend | — | ещё не создан |
|
||||||
| Сбор и обработка правовых данных | `0.8.0` | добавлены relevance set и оценка выдачи |
|
| Сбор и обработка правовых данных | `0.8.0` | добавлены relevance set и оценка выдачи |
|
||||||
| RAG и база знаний | — | ещё не созданы |
|
| RAG и база знаний | — | ещё не созданы |
|
||||||
@@ -59,4 +59,4 @@ python3 -m unittest discover -s tools/telegram-bot -v
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Акылдаш · Telegram-бот v0.2.2 · Backend v0.8.1 · Frontend — не создан
|
Акылдаш · Telegram-бот v0.2.2 · Backend v0.8.2 · Frontend — не создан
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Backend Акылдаш
|
# Backend Акылдаш
|
||||||
|
|
||||||
Версия: `0.8.1`
|
Версия: `0.8.2`
|
||||||
|
|
||||||
Первая backend-область проекта — загрузка правовых документов из официального
|
Первая backend-область проекта — загрузка правовых документов из официального
|
||||||
Open Data API ЦБД Минюста Кыргызской Республики. Код расположен в
|
Open Data API ЦБД Минюста Кыргызской Республики. Код расположен в
|
||||||
@@ -240,4 +240,4 @@ PYTHONPATH=backend python3 -m search.query "ЖЧК ачуу тартиби" --la
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Акылдаш · Backend v0.8.1 · Frontend — не создан
|
Акылдаш · Backend v0.8.2 · Frontend — не создан
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from datetime import datetime, timezone
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Callable, Iterable
|
from typing import Callable, Iterable
|
||||||
|
|
||||||
APP_VERSION = "0.8.1"
|
APP_VERSION = "0.8.2"
|
||||||
API_BASE_URL = "https://cbd.minjust.gov.kg/api/v1/OpenData/"
|
API_BASE_URL = "https://cbd.minjust.gov.kg/api/v1/OpenData/"
|
||||||
LANGUAGES = {"Rus": "ru", "Kyr": "ky"}
|
LANGUAGES = {"Rus": "ru", "Kyr": "ky"}
|
||||||
IMAGE_LANGUAGES = {"Russian": "ru", "Kyrgyz": "ky"}
|
IMAGE_LANGUAGES = {"Russian": "ru", "Kyrgyz": "ky"}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from pathlib import Path
|
|||||||
from typing import Callable
|
from typing import Callable
|
||||||
from urllib.parse import urlsplit
|
from urllib.parse import urlsplit
|
||||||
|
|
||||||
APP_VERSION = "0.8.1"
|
APP_VERSION = "0.8.2"
|
||||||
SCHEMA_VERSION = "1"
|
SCHEMA_VERSION = "1"
|
||||||
NORMALIZER_VERSION = "1.0.0"
|
NORMALIZER_VERSION = "1.0.0"
|
||||||
LANGUAGES = ("ru", "ky")
|
LANGUAGES = ("ru", "ky")
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from typing import Iterator
|
|||||||
|
|
||||||
from search.catalog import authority_codes, source_code
|
from search.catalog import authority_codes, source_code
|
||||||
|
|
||||||
APP_VERSION = "0.8.1"
|
APP_VERSION = "0.8.2"
|
||||||
LANGUAGES = {"ru", "ky"}
|
LANGUAGES = {"ru", "ky"}
|
||||||
DEFAULT_MAPPING = Path(__file__).with_name("minjust-fragments-index.json")
|
DEFAULT_MAPPING = Path(__file__).with_name("minjust-fragments-index.json")
|
||||||
|
|
||||||
|
|||||||
8
deploy/production/.env.example
Normal file
8
deploy/production/.env.example
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Absolute path on the production host containing minjust-normalized/.
|
||||||
|
DATA_ROOT=/volume1/docker/akyldash/data
|
||||||
|
BACKEND_PORT=8080
|
||||||
|
SEARCH_INDEX=akyldash-fragments-current
|
||||||
|
OPENSEARCH_MEM_LIMIT=4g
|
||||||
|
OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g
|
||||||
|
# Generate with: openssl rand -hex 32
|
||||||
|
REVIEW_SECRET=replace-with-a-random-secret
|
||||||
11
deploy/production/Dockerfile.backend
Normal file
11
deploy/production/Dockerfile.backend
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY backend /app/backend
|
||||||
|
|
||||||
|
ENV PYTHONPATH=/app/backend
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD ["python", "-m", "search.api", "--host", "0.0.0.0", "--port", "8080", "--url", "http://opensearch:9200", "--index", "akyldash-fragments-current", "--data", "/app/data/minjust-normalized", "--reviews-db", "/app/data/search-reviews.sqlite3"]
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s CMD ["python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/review', timeout=3)"]
|
||||||
3
deploy/production/Dockerfile.opensearch
Normal file
3
deploy/production/Dockerfile.opensearch
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
FROM opensearchproject/opensearch:3.7.0
|
||||||
|
|
||||||
|
RUN /usr/share/opensearch/bin/opensearch-plugin install --batch analysis-icu
|
||||||
37
deploy/production/README.md
Normal file
37
deploy/production/README.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Production deployment
|
||||||
|
|
||||||
|
This compose project runs the Search API and its private OpenSearch node. It
|
||||||
|
binds the API only to `127.0.0.1`; publish it through an authenticated reverse
|
||||||
|
proxy or VPN. OpenSearch is not published outside the compose network.
|
||||||
|
|
||||||
|
The current compose intentionally disables the OpenSearch security plugin to
|
||||||
|
match the existing API client. Keep both services on a private host/network
|
||||||
|
until authenticated OpenSearch support is implemented.
|
||||||
|
|
||||||
|
## First deployment
|
||||||
|
|
||||||
|
1. Copy this directory to the host with the repository source.
|
||||||
|
2. Copy `.env.example` to `.env`, set an absolute `DATA_ROOT`, and replace
|
||||||
|
`REVIEW_SECRET` with a random value. Do not commit `.env`.
|
||||||
|
3. Put the normalized dataset under `$DATA_ROOT/minjust-normalized/`.
|
||||||
|
4. Check the rendered configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --env-file .env -f compose.yaml config
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Start the services:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose --env-file .env -f compose.yaml up -d --build
|
||||||
|
docker compose --env-file .env -f compose.yaml ps
|
||||||
|
curl -fsS http://127.0.0.1:${BACKEND_PORT:-8080}/review >/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Load the versioned index and switch its alias only after the import and
|
||||||
|
validation succeed. Back up `DATA_ROOT` and the `opensearch-data` volume
|
||||||
|
before the first import.
|
||||||
|
|
||||||
|
This is a deployment baseline, not a public internet exposure recipe. TLS,
|
||||||
|
authentication, backups, monitoring, and a production OpenSearch security
|
||||||
|
configuration must be provided by the host reverse proxy/operations setup.
|
||||||
64
deploy/production/compose.yaml
Normal file
64
deploy/production/compose.yaml
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
services:
|
||||||
|
opensearch:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: deploy/production/Dockerfile.opensearch
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
discovery.type: single-node
|
||||||
|
bootstrap.memory_lock: "true"
|
||||||
|
DISABLE_SECURITY_PLUGIN: "true"
|
||||||
|
OPENSEARCH_JAVA_OPTS: ${OPENSEARCH_JAVA_OPTS:--Xms2g -Xmx2g}
|
||||||
|
mem_limit: ${OPENSEARCH_MEM_LIMIT:-4g}
|
||||||
|
expose:
|
||||||
|
- "9200"
|
||||||
|
ulimits:
|
||||||
|
memlock:
|
||||||
|
soft: -1
|
||||||
|
hard: -1
|
||||||
|
nofile:
|
||||||
|
soft: 65536
|
||||||
|
hard: 65536
|
||||||
|
volumes:
|
||||||
|
- opensearch-data:/usr/share/opensearch/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:9200/_cluster/health || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 10
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: deploy/production/Dockerfile.backend
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
REVIEW_SECRET: ${REVIEW_SECRET:?set REVIEW_SECRET in .env}
|
||||||
|
command:
|
||||||
|
- python
|
||||||
|
- -m
|
||||||
|
- search.api
|
||||||
|
- --host
|
||||||
|
- 0.0.0.0
|
||||||
|
- --port
|
||||||
|
- "8080"
|
||||||
|
- --url
|
||||||
|
- http://opensearch:9200
|
||||||
|
- --index
|
||||||
|
- ${SEARCH_INDEX:-akyldash-fragments-current}
|
||||||
|
- --data
|
||||||
|
- /app/data/minjust-normalized
|
||||||
|
- --reviews-db
|
||||||
|
- /app/data/search-reviews.sqlite3
|
||||||
|
- --review-secret
|
||||||
|
- ${REVIEW_SECRET}
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:${BACKEND_PORT:-8080}:8080"
|
||||||
|
depends_on:
|
||||||
|
opensearch:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes:
|
||||||
|
- ${DATA_ROOT:?set DATA_ROOT in .env}:/app/data
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
opensearch-data:
|
||||||
Reference in New Issue
Block a user