1
0
Fork 0
mirror of https://github.com/EDeev/mospolytech-mcp.git synced 2026-10-07 20:49:52 +03:00

Добавление контейнеризации

This commit is contained in:
RayStar-k 2026-09-23 22:15:01 +03:00
parent 7065fb3a8d
commit 18e15bf95f
6 changed files with 122 additions and 3 deletions

10
.dockerignore Normal file
View file

@ -0,0 +1,10 @@
.git
.venv
.env
.pytest_cache
.claude
docs
tests
scripts
**/__pycache__
**/*.egg-info

View file

@ -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
View 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"]

View file

@ -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')]"

View file

@ -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
View 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: