mirror of
https://github.com/MemeMeow-Studio/MemeMeow.git
synced 2026-10-17 04:41:01 +08:00
5ecda39843
- Implement tests for the ImageProcessingWorker to validate task deduplication and policy interactions. - Create tests for operation policy to ensure proper grant handling and error responses. - Add tests for reverse image provider response structure to validate empty and malformed results. - Develop comprehensive tests for scope resolution and service validation to ensure correct behavior in various scenarios.
199 lines
7.9 KiB
YAML
199 lines
7.9 KiB
YAML
services:
|
||
postgres:
|
||
image: pgvector/pgvector:pg16
|
||
restart: unless-stopped
|
||
environment:
|
||
POSTGRES_DB: ${POSTGRES_DB:-mememeow}
|
||
POSTGRES_USER: ${POSTGRES_USER:-mememeow}
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-mememeow}
|
||
ports:
|
||
- "127.0.0.1:5434:5432"
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||
interval: 3s
|
||
timeout: 3s
|
||
retries: 20
|
||
volumes:
|
||
- mememeow-postgres-data:/var/lib/postgresql/data
|
||
|
||
db-init:
|
||
build:
|
||
context: .
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
environment:
|
||
MEMEMEOW_DATABASE_URL: ${MEMEMEOW_DATABASE_URL_CONTAINER:-postgresql+psycopg://mememeow:mememeow@postgres:5432/mememeow}
|
||
working_dir: /app
|
||
command: ["alembic", "upgrade", "head"]
|
||
|
||
db-viewer:
|
||
profiles: ["db-viewer"]
|
||
image: adminer:4
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
environment:
|
||
ADMINER_DEFAULT_SERVER: postgres
|
||
ports:
|
||
- "127.0.0.1:${MEMEMEOW_DB_VIEWER_PORT:-8080}:8080"
|
||
|
||
mememeow-visual:
|
||
build:
|
||
context: .
|
||
dockerfile: docker/visual/Dockerfile
|
||
container_name: ${MEMEMEOW_VISUAL_CONTAINER_NAME:-mememeow-visual}
|
||
restart: unless-stopped
|
||
# 视觉端口只加入 Compose 网络,不发布到宿主机。
|
||
expose:
|
||
- "8276"
|
||
networks:
|
||
- visual-backend
|
||
environment:
|
||
MEMEMEOW_VISUAL_MODEL: ${MEMEMEOW_VISUAL_MODEL:-dinov2_vitb14}
|
||
MEMEMEOW_VISUAL_DIMENSIONS: ${MEMEMEOW_VISUAL_DIMENSIONS:-768}
|
||
MEMEMEOW_VISUAL_PREPROCESS_VERSION: ${MEMEMEOW_VISUAL_PREPROCESS_VERSION:-dinov2_vitb14-rgb224-first-frame-v1}
|
||
MEMEMEOW_VISUAL_MODEL_REPO: /opt/dinov2
|
||
MEMEMEOW_VISUAL_WEIGHTS_PATH: /models/dinov2_vitb14_pretrain.pth
|
||
MEMEMEOW_VISUAL_WEIGHTS_SHA256: ${MEMEMEOW_VISUAL_WEIGHTS_SHA256:-}
|
||
MEMEMEOW_VISUAL_INTERNAL_TOKEN: ${MEMEMEOW_VISUAL_INTERNAL_TOKEN:-}
|
||
MEMEMEOW_VISUAL_CPU_THREADS: ${MEMEMEOW_VISUAL_CPU_THREADS:-4}
|
||
MEMEMEOW_VISUAL_CPU_INTEROP_THREADS: ${MEMEMEOW_VISUAL_CPU_INTEROP_THREADS:-1}
|
||
MEMEMEOW_VISUAL_MAX_PIXELS: ${MEMEMEOW_VISUAL_MAX_PIXELS:-25000000}
|
||
volumes:
|
||
- type: bind
|
||
source: ${MEMEMEOW_VISUAL_WEIGHTS_DIR:-./data/models}
|
||
target: /models
|
||
read_only: true
|
||
bind:
|
||
create_host_path: true
|
||
- type: bind
|
||
source: ./data/images
|
||
target: /images
|
||
read_only: true
|
||
cpus: ${MEMEMEOW_VISUAL_CPU_QUOTA:-4.0}
|
||
mem_limit: ${MEMEMEOW_VISUAL_MEMORY_LIMIT:-8g}
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c 'import json,urllib.request; payload=json.load(urllib.request.urlopen(\"http://127.0.0.1:8276/health\", timeout=3)); raise SystemExit(0 if payload.get(\"status\") in (\"ok\", \"degraded\") else 1)' "]
|
||
interval: 15s
|
||
timeout: 5s
|
||
retries: 3
|
||
|
||
mememeow-agent-runtime:
|
||
build:
|
||
context: .
|
||
dockerfile: docker/agent/Dockerfile
|
||
container_name: ${MEMEMEOW_AGENT_CONTAINER_NAME:-mememeow-agent-runtime}
|
||
init: true
|
||
restart: unless-stopped
|
||
working_dir: /runtime/workspace
|
||
expose:
|
||
- "8277"
|
||
environment:
|
||
# token 首次由非 root executor 写入持久 named volume;API 只读同一文件。
|
||
MEMEMEOW_AGENT_EXECUTOR_TOKEN_FILE: /run/agent-executor-secret/token
|
||
MEMEMEOW_AGENT_EXECUTOR_HOST: 0.0.0.0
|
||
MEMEMEOW_AGENT_EXECUTOR_PORT: ${MEMEMEOW_AGENT_EXECUTOR_PORT:-8277}
|
||
MEMEMEOW_AGENT_EXECUTOR_MAX_TIMEOUT_SECONDS: ${MEMEMEOW_AGENT_EXECUTOR_MAX_TIMEOUT_SECONDS:-1800}
|
||
MEMEMEOW_OPENCODE_EXECUTABLE: opencode
|
||
MEMEMEOW_OPENCODE_MODEL: ${MEMEMEOW_OPENCODE_MODEL:-}
|
||
MEMEMEOW_OPENCODE_BASE_URL: ${MEMEMEOW_OPENCODE_BASE_URL:-}
|
||
MEMEMEOW_OPENCODE_API_KEY: ${MEMEMEOW_OPENCODE_API_KEY:-}
|
||
MEMEMEOW_OPENCODE_CONCURRENCY: ${MEMEMEOW_OPENCODE_CONCURRENCY:-1}
|
||
MEMEMEOW_AGENT_BACKPRESSURE: ${MEMEMEOW_AGENT_BACKPRESSURE:-32}
|
||
MEMEMEOW_AGENT_RESULT_MAX_BYTES: ${MEMEMEOW_AGENT_RESULT_MAX_BYTES:-1048576}
|
||
MEMEMEOW_AGENT_REVERSE_IMAGE_INTERNAL_URL: http://mememeow:8275/internal/reverse-image/search
|
||
MEMEMEOW_AGENT_VISUAL_SEARCH_INTERNAL_URL: http://mememeow:8275/internal/visual-search/match
|
||
volumes:
|
||
# named volume 的 owner 从镜像初始化,不会被全新 checkout 的 bind mount 覆盖为 root。
|
||
- mememeow-agent-runtime-data:/runtime
|
||
- mememeow-agent-executor-secret:/run/agent-executor-secret
|
||
- type: bind
|
||
source: ./data/images
|
||
target: /images
|
||
read_only: true
|
||
- type: bind
|
||
source: ./skills/research-meme-context
|
||
target: /skills/research-meme-context
|
||
read_only: true
|
||
networks:
|
||
- default
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "test \"$$(id -u)\" != 0 && python3 -m executor.probe"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 12
|
||
start_period: 5s
|
||
|
||
mememeow:
|
||
profiles: ["app"]
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
db-init:
|
||
condition: service_completed_successfully
|
||
mememeow-agent-runtime:
|
||
condition: service_healthy
|
||
mememeow-visual:
|
||
condition: service_healthy
|
||
build:
|
||
context: .
|
||
restart: unless-stopped
|
||
command: ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8275"]
|
||
ports:
|
||
- "127.0.0.1:8275:8275"
|
||
# 视觉权重缺失时 API 可以降级提供界面,因此探活只阻断 HTTP 未启动状态。
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "python -c 'import json,urllib.request; payload=json.load(urllib.request.urlopen(\"http://127.0.0.1:8275/health\", timeout=3)); raise SystemExit(0 if payload.get(\"status\") in (\"ok\", \"degraded\") else 1)' "]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 12
|
||
start_period: 15s
|
||
env_file:
|
||
- path: .env
|
||
required: false
|
||
environment:
|
||
MEMEMEOW_DATABASE_URL: ${MEMEMEOW_DATABASE_URL_CONTAINER:-postgresql+psycopg://mememeow:mememeow@postgres:5432/mememeow}
|
||
MEMEMEOW_IMAGE_ROOT: /app/data/images
|
||
MEMEMEOW_OPENCODE_RUNTIME_ROOT: /app/data/opencode
|
||
MEMEMEOW_AGENT_CONTAINER_NAME: ${MEMEMEOW_AGENT_CONTAINER_NAME:-mememeow-agent-runtime}
|
||
MEMEMEOW_AGENT_RUNTIME_MODE: executor
|
||
MEMEMEOW_AGENT_EXECUTOR_URL: http://mememeow-agent-runtime:8277
|
||
MEMEMEOW_AGENT_EXECUTOR_TOKEN_FILE: /run/agent-executor-secret/token
|
||
MEMEMEOW_AGENT_EXECUTOR_REQUEST_TIMEOUT_SECONDS: ${MEMEMEOW_AGENT_EXECUTOR_REQUEST_TIMEOUT_SECONDS:-1810}
|
||
MEMEMEOW_AGENT_EXECUTOR_MAX_TIMEOUT_SECONDS: ${MEMEMEOW_AGENT_EXECUTOR_MAX_TIMEOUT_SECONDS:-1800}
|
||
MEMEMEOW_AGENT_CALLBACK_SECRET: ${MEMEMEOW_AGENT_CALLBACK_SECRET:-}
|
||
MEMEMEOW_AGENT_CALLBACK_VERIFICATION_KEYS: ${MEMEMEOW_AGENT_CALLBACK_VERIFICATION_KEYS:-}
|
||
MEMEMEOW_AGENT_REVERSE_IMAGE_INTERNAL_URL: http://mememeow:8275/internal/reverse-image/search
|
||
MEMEMEOW_AGENT_VISUAL_SEARCH_INTERNAL_URL: http://mememeow:8275/internal/visual-search/match
|
||
MEMEMEOW_REVERSE_IMAGE_INTERNAL_URL: http://mememeow:8275/internal/reverse-image/search
|
||
MEMEMEOW_VISUAL_INTERNAL_URL: http://mememeow-visual:8276/internal/visual-embedding
|
||
MEMEMEOW_VISUAL_HEALTH_URL: http://mememeow-visual:8276/health
|
||
MEMEMEOW_VISUAL_SEARCH_INTERNAL_URL: http://mememeow:8275/internal/visual-search/match
|
||
MEMEMEOW_VISUAL_INTERNAL_TOKEN: ${MEMEMEOW_VISUAL_INTERNAL_TOKEN:-}
|
||
MEMEMEOW_OPENCODE_MODEL: ${MEMEMEOW_OPENCODE_MODEL:-}
|
||
MEMEMEOW_OPENCODE_BASE_URL: ${MEMEMEOW_OPENCODE_BASE_URL:-}
|
||
MEMEMEOW_OPENCODE_API_KEY: ${MEMEMEOW_OPENCODE_API_KEY:-}
|
||
volumes:
|
||
- mememeow-agent-runtime-data:/app/data/opencode
|
||
- type: volume
|
||
source: mememeow-agent-executor-secret
|
||
target: /run/agent-executor-secret
|
||
read_only: true
|
||
- type: bind
|
||
source: ./data/images
|
||
target: /app/data/images
|
||
networks:
|
||
- default
|
||
- visual-backend
|
||
|
||
networks:
|
||
visual-backend:
|
||
internal: true
|
||
|
||
volumes:
|
||
mememeow-postgres-data:
|
||
mememeow-agent-runtime-data:
|
||
# token 不落盘到 checkout 或宿主环境,只存在 Docker named volume。
|
||
mememeow-agent-executor-secret:
|