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_PASSWORD=
|
||||
|
||||
# Подключение к PostgreSQL
|
||||
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
|
||||
|
||||
.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:
|
||||
@$(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, миграции, сервер
|
||||
|
||||
|
|
@ -57,5 +57,14 @@ test: install ## офлайн-тесты
|
|||
check-lk: install .env ## проверка lk_api на реальном аккаунте
|
||||
$(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 и кэши
|
||||
$(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`)
|
||||
открывать только на тестовой машине.
|
||||
|
||||
## 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 накатывает схему)
|
||||
tests/ — офлайн-тесты (pytest, без сети)
|
||||
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