mirror of
https://github.com/EDeev/mospolytech-mcp.git
synced 2026-10-07 20:49:52 +03:00
Добавление контейнеризации
This commit is contained in:
parent
7065fb3a8d
commit
18e15bf95f
6 changed files with 122 additions and 3 deletions
10
.dockerignore
Normal file
10
.dockerignore
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
.git
|
||||||
|
.venv
|
||||||
|
.env
|
||||||
|
.pytest_cache
|
||||||
|
.claude
|
||||||
|
docs
|
||||||
|
tests
|
||||||
|
scripts
|
||||||
|
**/__pycache__
|
||||||
|
**/*.egg-info
|
||||||
|
|
@ -2,5 +2,8 @@
|
||||||
MPU_LOGIN=
|
MPU_LOGIN=
|
||||||
MPU_PASSWORD=
|
MPU_PASSWORD=
|
||||||
|
|
||||||
# Подключение к PostgreSQL
|
|
||||||
DATABASE_URL=
|
DATABASE_URL=
|
||||||
|
|
||||||
|
POSTGRES_USER=
|
||||||
|
POSTGRES_PASSWORD=
|
||||||
|
POSTGRES_DB=
|
||||||
|
|
|
||||||
23
Dockerfile
Normal file
23
Dockerfile
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
FROM python:3.14-slim
|
||||||
|
|
||||||
|
ENV PYTHONUNBUFFERED=1 \
|
||||||
|
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
||||||
|
PIP_NO_CACHE_DIR=1
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY pyproject.toml ./
|
||||||
|
RUN python -c "import tomllib; [print(d) for d in tomllib.load(open('pyproject.toml', 'rb'))['project']['dependencies']]" \
|
||||||
|
| pip install -r /dev/stdin
|
||||||
|
|
||||||
|
COPY README.md alembic.ini ./
|
||||||
|
COPY src ./src
|
||||||
|
COPY alembic ./alembic
|
||||||
|
RUN pip install --no-deps .
|
||||||
|
|
||||||
|
RUN useradd --create-home --uid 1000 mcp
|
||||||
|
USER mcp
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "alembic upgrade head && exec python -m mospolytech_mcp.server --http --host 0.0.0.0 --port 8000"]
|
||||||
13
Makefile
13
Makefile
|
|
@ -15,10 +15,10 @@ HOST ?= 0.0.0.0
|
||||||
PORT ?= 8000
|
PORT ?= 8000
|
||||||
|
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
.PHONY: help up setup install check-env migrate run run-http test check-lk clean
|
.PHONY: help up setup install check-env migrate run run-http test check-lk clean docker-up docker-down docker-logs
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@$(SYS_PYTHON) -X utf8 -c "import re, sys; [print(' make {:<10} {}'.format(*m.groups())) for m in re.finditer(r'^([a-z-]+):.*?## (.*)', open(sys.argv[1], encoding='utf-8').read(), re.M)]" $(firstword $(MAKEFILE_LIST))
|
@$(SYS_PYTHON) -X utf8 -c "import re, sys; [print(' make {:<12} {}'.format(*m.groups())) for m in re.finditer(r'^([a-z-]+):.*?## (.*)', open(sys.argv[1], encoding='utf-8').read(), re.M)]" $(firstword $(MAKEFILE_LIST))
|
||||||
|
|
||||||
up: migrate run ## всё сразу: окружение, .env, миграции, сервер
|
up: migrate run ## всё сразу: окружение, .env, миграции, сервер
|
||||||
|
|
||||||
|
|
@ -57,5 +57,14 @@ test: install ## офлайн-тесты
|
||||||
check-lk: install .env ## проверка lk_api на реальном аккаунте
|
check-lk: install .env ## проверка lk_api на реальном аккаунте
|
||||||
$(PY) scripts/check_lk_api.py
|
$(PY) scripts/check_lk_api.py
|
||||||
|
|
||||||
|
docker-up:
|
||||||
|
docker compose up --build -d
|
||||||
|
|
||||||
|
docker-down:
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
docker-logs:
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
clean: ## удалить .venv и кэши
|
clean: ## удалить .venv и кэши
|
||||||
$(SYS_PYTHON) -c "import shutil; [shutil.rmtree(p, ignore_errors=True) for p in ('.venv', '.pytest_cache')]"
|
$(SYS_PYTHON) -c "import shutil; [shutil.rmtree(p, ignore_errors=True) for p in ('.venv', '.pytest_cache')]"
|
||||||
|
|
|
||||||
40
README.md
40
README.md
|
|
@ -149,6 +149,44 @@ Connect — в списке инструментов появится `list_grou
|
||||||
прямо оттуда. Авторизации на сервере нет, так что наружу (`0.0.0.0`)
|
прямо оттуда. Авторизации на сервере нет, так что наружу (`0.0.0.0`)
|
||||||
открывать только на тестовой машине.
|
открывать только на тестовой машине.
|
||||||
|
|
||||||
|
## Docker
|
||||||
|
|
||||||
|
Тот же сервер, но в контейнере и со своей PostgreSQL рядом — так он живёт
|
||||||
|
на ВМ начиная с ЛР3. Нужны Docker и docker compose v2, `.env` и venv не
|
||||||
|
нужны:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-up
|
||||||
|
make docker-logs
|
||||||
|
make docker-down
|
||||||
|
```
|
||||||
|
|
||||||
|
Что происходит:
|
||||||
|
|
||||||
|
- `Dockerfile` собирает образ из исходников: `python:3.14-slim`, отдельным
|
||||||
|
слоем зависимости из `pyproject.toml`, потом сам пакет. При старте
|
||||||
|
контейнер накатывает миграции (`alembic upgrade head`) и запускает сервер
|
||||||
|
в HTTP-режиме на `0.0.0.0:8000` — снаружи это `http://<адрес>:8000/mcp`.
|
||||||
|
- `docker-compose.yaml` поднимает два сервиса: `db` (`postgres:17-alpine`)
|
||||||
|
и `mcp` (наш образ). Сервер стартует только после того, как БД ответила на
|
||||||
|
`pg_isready`, и ходит к ней по имени `db` внутри сети compose — наружу
|
||||||
|
порт PostgreSQL не выставлен. `DATABASE_URL` для контейнера compose
|
||||||
|
собирает сам из `POSTGRES_*`; `.env` в образ не попадает (`.dockerignore`).
|
||||||
|
- Файлы БД лежат в volume `pgdata`, поэтому `docker compose down` и
|
||||||
|
повторный `up` данные не теряют. Снести вместе с данными —
|
||||||
|
`docker compose down -v`.
|
||||||
|
|
||||||
|
Логин, пароль и имя БД по умолчанию `mospolytech_mcp`; переопределяются через
|
||||||
|
`POSTGRES_USER`/`POSTGRES_PASSWORD`/`POSTGRES_DB` в `.env` — compose читает
|
||||||
|
его сам, а `DATABASE_URL` оттуда для контейнера не используется.
|
||||||
|
|
||||||
|
Посмотреть, что кэш реально лёг в контейнерную БД (это же удобно показывать
|
||||||
|
после рестарта):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose exec db psql -U mospolytech_mcp -c "select id, jsonb_array_length(groups), fetched_at from groups_cache"
|
||||||
|
```
|
||||||
|
|
||||||
## Структура репозитория
|
## Структура репозитория
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
@ -166,4 +204,6 @@ src/mospolytech_mcp/
|
||||||
alembic/ — миграции БД (alembic upgrade head накатывает схему)
|
alembic/ — миграции БД (alembic upgrade head накатывает схему)
|
||||||
tests/ — офлайн-тесты (pytest, без сети)
|
tests/ — офлайн-тесты (pytest, без сети)
|
||||||
scripts/ — ручные проверочные скрипты (против реального ЛК)
|
scripts/ — ручные проверочные скрипты (против реального ЛК)
|
||||||
|
Dockerfile — образ сервера (сборка из исходников, миграции + HTTP-режим на старте)
|
||||||
|
docker-compose.yaml — сервер + PostgreSQL с volume для данных
|
||||||
```
|
```
|
||||||
|
|
|
||||||
34
docker-compose.yaml
Normal file
34
docker-compose.yaml
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: postgres:17-alpine
|
||||||
|
container_name: mospolytech-db
|
||||||
|
hostname: db
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-mospolytech_mcp}
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-mospolytech_mcp}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mospolytech_mcp}
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 10
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
mcp:
|
||||||
|
build: .
|
||||||
|
image: mospolytech-mcp
|
||||||
|
container_name: mospolytech-mcp
|
||||||
|
hostname: mcp
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgresql+psycopg://${POSTGRES_USER:-mospolytech_mcp}:${POSTGRES_PASSWORD:-mospolytech_mcp}@db:5432/${POSTGRES_DB:-mospolytech_mcp}
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
Loading…
Add table
Reference in a new issue