Merge pull request 'feat: add production deployment baseline' (#28) from feature/production-deployment-baseline into main
Reviewed-on: #28
This commit was merged in pull request #28.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Добавлен production deployment baseline для Search API и OpenSearch с
|
||||
постоянными хранилищами и healthcheck.
|
||||
- Добавлено восстановление незавершённой разметки из `localStorage` после перезагрузки страницы.
|
||||
- Добавлена внутренняя лаборатория проверки поисковой выдачи: просмотр документов,
|
||||
оценка релевантности 0–3, комментарии и SQLite-экспорт подписанных снимков.
|
||||
|
||||
@@ -10,13 +10,13 @@ Telegram-бот — только часть рабочего окружения
|
||||
## Текущее состояние
|
||||
|
||||
Сейчас реализованы 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`; обновление после слияния |
|
||||
| Backend | `0.8.1` | добавлено сохранение черновика разметки |
|
||||
| Backend | `0.8.2` | добавлен production deployment baseline |
|
||||
| Frontend | — | ещё не создан |
|
||||
| Сбор и обработка правовых данных | `0.8.0` | добавлены relevance set и оценка выдачи |
|
||||
| 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 Акылдаш
|
||||
|
||||
Версия: `0.8.1`
|
||||
Версия: `0.8.2`
|
||||
|
||||
Первая backend-область проекта — загрузка правовых документов из официального
|
||||
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 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/"
|
||||
LANGUAGES = {"Rus": "ru", "Kyr": "ky"}
|
||||
IMAGE_LANGUAGES = {"Russian": "ru", "Kyrgyz": "ky"}
|
||||
|
||||
@@ -23,7 +23,7 @@ from pathlib import Path
|
||||
from typing import Callable
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
APP_VERSION = "0.8.1"
|
||||
APP_VERSION = "0.8.2"
|
||||
SCHEMA_VERSION = "1"
|
||||
NORMALIZER_VERSION = "1.0.0"
|
||||
LANGUAGES = ("ru", "ky")
|
||||
|
||||
@@ -17,7 +17,7 @@ from typing import Iterator
|
||||
|
||||
from search.catalog import authority_codes, source_code
|
||||
|
||||
APP_VERSION = "0.8.1"
|
||||
APP_VERSION = "0.8.2"
|
||||
LANGUAGES = {"ru", "ky"}
|
||||
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