Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 160 additions & 0 deletions SYNC_UPSTREAM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Синхронизация с Upstream MemOS

## Архитектура

```
┌─────────────────────────────────────────────────────────────┐
│ MemTensor/MemOS (upstream) │
│ Оригинал │
└─────────────────────────┬───────────────────────────────────┘
│ git fetch upstream
┌─────────────────────────────────────────────────────────────┐
│ anatolykoptev/MemOS (fork) │
│ ┌────────────────────┐ ┌─────────────────────────────┐ │
│ │ src/memos/ │ │ overlays/krolik/ │ │
│ │ (base MemOS) │ │ (auth, rate-limit, admin) │ │
│ │ │ │ │ │
│ │ ← syncs with │ │ ← НАШИ кастомизации │ │
│ │ upstream │ │ (никогда не конфликтуют) │ │
│ └────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
│ Dockerfile.krolik
┌─────────────────────────────────────────────────────────────┐
│ krolik-server (production) │
│ src/memos/ + overlays merged at build │
└─────────────────────────────────────────────────────────────┘
```

## Регулярная синхронизация (еженедельно)

```bash
cd ~/CascadeProjects/piternow_project/MemOS

# 1. Получить изменения upstream
git fetch upstream

# 2. Посмотреть что нового
git log --oneline upstream/main..main # Наши коммиты
git log --oneline main..upstream/main # Новое в upstream

# 3. Merge upstream (overlays/ не затрагивается)
git checkout main
git merge upstream/main

# 4. Если конфликты (редко, только в src/):
# - Разрешить конфликты
# - git add .
# - git commit

# 5. Push в наш fork
git push origin main
```

## Обновление production (krolik-server)

После синхронизации форка:

```bash
cd ~/krolik-server

# Пересобрать с новым MemOS
docker compose build --no-cache memos-api

# Перезапустить
docker compose up -d memos-api

# Проверить логи
docker logs -f memos-api
```

## Добавление новых фич в overlay

```bash
# 1. Создать файл в overlays/krolik/
vim overlays/krolik/api/middleware/new_feature.py

# 2. Импортировать в server_api_ext.py
vim overlays/krolik/api/server_api_ext.py

# 3. Commit в наш fork
git add overlays/
git commit -m "feat(krolik): add new_feature middleware"
git push origin main
```

## Важные правила

### ✅ Делать:
- Все кастомизации в `overlays/krolik/`
- Багфиксы в `src/` которые полезны upstream — создавать PR
- Регулярно синхронизировать с upstream

### ❌ НЕ делать:
- Модифицировать файлы в `src/memos/` напрямую
- Форкать API в overlay вместо расширения
- Игнорировать обновления upstream > 2 недель

## Структура overlays

```
overlays/
└── krolik/
└── api/
├── middleware/
│ ├── __init__.py
│ ├── auth.py # API Key auth (PostgreSQL)
│ └── rate_limit.py # Redis sliding window
├── routers/
│ ├── __init__.py
│ └── admin_router.py # /admin/keys CRUD
├── utils/
│ ├── __init__.py
│ └── api_keys.py # Key generation
└── server_api_ext.py # Entry point
```

## Environment Variables (Krolik)

```bash
# Authentication
AUTH_ENABLED=true
MASTER_KEY_HASH=<sha256-hash>
INTERNAL_SERVICE_SECRET=<secret>

# Rate Limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT=100
RATE_WINDOW_SEC=60
REDIS_URL=redis://redis:6379

# PostgreSQL (for API keys)
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_USER=memos
POSTGRES_PASSWORD=<password>
POSTGRES_DB=memos

# CORS
CORS_ORIGINS=https://krolik.hully.one,https://memos.hully.one
```

## Миграция из текущего krolik-server

Текущий `krolik-server/services/memos-core/` содержит смешанный код.
После перехода на overlay pattern:

1. **krolik-server** будет использовать `Dockerfile.krolik` из форка
2. **Локальные изменения** удаляются из krolik-server
3. **Все кастомизации** живут в `MemOS/overlays/krolik/`

```yaml
# docker-compose.yml (krolik-server)
services:
memos-api:
build:
context: ../MemOS # Используем форк напрямую
dockerfile: docker/Dockerfile.krolik
# ... остальная конфигурация
```
65 changes: 65 additions & 0 deletions docker/Dockerfile.krolik
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# MemOS with Krolik Security Extensions
#
# This Dockerfile builds MemOS with authentication, rate limiting, and admin API.
# It uses the overlay pattern to keep customizations separate from base code.

FROM python:3.11-slim

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
build-essential \
libffi-dev \
python3-dev \
curl \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN groupadd -r memos && useradd -r -g memos -u 1000 memos

WORKDIR /app

# Use official Hugging Face
ENV HF_ENDPOINT=https://huggingface.co

# Copy base MemOS source
COPY src/ ./src/
COPY pyproject.toml ./

# Install base dependencies
RUN pip install --upgrade pip && \
pip install --no-cache-dir poetry && \
poetry config virtualenvs.create false && \
poetry install --no-dev --extras "tree-mem mem-scheduler"

# Install additional dependencies for Krolik
RUN pip install --no-cache-dir \
sentence-transformers \
torch \
transformers \
psycopg2-binary \
redis

# Apply Krolik overlay (AFTER base install to allow easy updates)
COPY overlays/krolik/ ./src/memos/

# Create data directory
RUN mkdir -p /data/memos && chown -R memos:memos /data/memos
RUN chown -R memos:memos /app

# Set Python path
ENV PYTHONPATH=/app/src

# Switch to non-root user
USER memos

EXPOSE 8000

# Healthcheck
HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=60s \
CMD curl -f http://localhost:8000/health || exit 1

# Use extended entry point with security features
CMD ["gunicorn", "memos.api.server_api_ext:app", "--preload", "-w", "2", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:8000", "--timeout", "120"]
86 changes: 86 additions & 0 deletions overlays/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# MemOS Overlays

Overlays are deployment-specific customizations that extend the base MemOS without modifying core files.

## Structure

```
overlays/
└── krolik/ # Deployment name
└── api/
├── middleware/
│ ├── __init__.py
│ ├── auth.py # API Key authentication
│ └── rate_limit.py # Redis rate limiting
├── routers/
│ ├── __init__.py
│ └── admin_router.py # API key management
├── utils/
│ ├── __init__.py
│ └── api_keys.py # Key generation utilities
└── server_api_ext.py # Extended entry point
```

## How It Works

1. **Base MemOS** provides core functionality (memory operations, embeddings, etc.)
2. **Overlays** add deployment-specific features without modifying base files
3. **Dockerfile** merges overlays on top of base during build

## Dockerfile Usage

```dockerfile
# Clone base MemOS
RUN git clone --depth 1 https://github.com/anatolykoptev/MemOS.git /app

# Install base dependencies
RUN pip install -r /app/requirements.txt

# Apply overlay (copies files into src/memos/)
RUN cp -r /app/overlays/krolik/* /app/src/memos/

# Use extended entry point
CMD ["gunicorn", "memos.api.server_api_ext:app", ...]
```

## Syncing with Upstream

```bash
# 1. Fetch upstream changes
git fetch upstream

# 2. Merge upstream into main (preserves overlays)
git merge upstream/main

# 3. Resolve conflicts if any (usually none in overlays/)
git status

# 4. Push to fork
git push origin main
```

## Adding New Overlays

1. Create directory: `overlays/<deployment-name>/`
2. Add customizations following the same structure
3. Create `server_api_ext.py` as entry point
4. Update Dockerfile to use the new overlay

## Security Features (krolik overlay)

### API Key Authentication
- SHA-256 hashed keys stored in PostgreSQL
- Master key for admin operations
- Scoped permissions (read, write, admin)
- Internal service bypass for container-to-container

### Rate Limiting
- Redis-based sliding window algorithm
- In-memory fallback for development
- Per-key or per-IP limiting
- Configurable via environment variables

### Admin API
- `/admin/keys` - Create, list, revoke API keys
- `/admin/health` - Auth system status
- Protected by admin scope or master key
13 changes: 13 additions & 0 deletions overlays/krolik/api/middleware/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Krolik middleware extensions for MemOS."""

from .auth import verify_api_key, require_scope, require_admin, require_read, require_write
from .rate_limit import RateLimitMiddleware

__all__ = [
"verify_api_key",
"require_scope",
"require_admin",
"require_read",
"require_write",
"RateLimitMiddleware",
]
Loading