From d45487433c62e1cea300b15dc8056b760c489ba8 Mon Sep 17 00:00:00 2001 From: zenhouke <80815662+zenhouke@users.noreply.github.com> Date: Wed, 11 Feb 2026 22:58:05 +0800 Subject: [PATCH] feat: add Docker Compose deployment support (#38) - Add Docker Compose configuration for one-click deployment - Add Dockerfiles for server, agent, and web services - Add deployment script (deploy.sh) with automatic setup - Add comprehensive deployment documentation (DEPLOYMENT.md) - Use host Docker socket instead of DinD for better performance - Add Nginx configuration for web frontend - Add Makefile for common operations - Update README with Docker deployment quick start Features: - One-command deployment with ./deploy.sh - Automatic JWT secret generation - Health checks for all services - Data persistence with Docker volumes - Support for Bot container management via host Docker - Production-ready configuration examples Co-authored-by: root --- .dockerignore | 60 +++++++ DEPLOYMENT.md | 401 +++++++++++++++++++++++++++++++++++++++++++++ Dockerfile.agent | 28 ++++ Dockerfile.server | 33 ++++ Dockerfile.web | 33 ++++ README.md | 18 +- README_CN.md | 16 +- config.docker.toml | 54 ++++++ deploy.sh | 89 ++++++++++ docker-compose.yml | 137 ++++++++++++++++ nginx.conf | 64 ++++++++ 11 files changed, 930 insertions(+), 3 deletions(-) create mode 100644 .dockerignore create mode 100644 DEPLOYMENT.md create mode 100644 Dockerfile.agent create mode 100644 Dockerfile.server create mode 100644 Dockerfile.web create mode 100644 config.docker.toml create mode 100755 deploy.sh create mode 100644 docker-compose.yml create mode 100644 nginx.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..52ffe1fb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,60 @@ +# Git +.git +.gitignore +.gitattributes + +# Documentation +*.md +docs/ +assets/ + +# IDE +.vscode/ +.cursor/ +.idea/ + +# Dependencies +node_modules/ +**/node_modules/ + +# Build outputs +dist/ +**/dist/ +build/ +**/build/ +out/ + +# Logs +*.log +logs/ + +# Environment +.env +.env.local +.env.*.local + +# OS +.DS_Store +Thumbs.db + +# Temporary files +tmp/ +temp/ +*.tmp +*.swp +*.swo + +# Test +coverage/ +.nyc_output/ + +# Mise +.mise.toml.local + +# Data +data/ +*.db +*.sqlite + +# Docker +docker-compose.override.yml diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 00000000..42f37800 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,401 @@ +# Memoh Docker Deployment Guide + +Deploy Memoh AI Agent System with Docker Compose in one command. + +## Quick Start + +### 1. Clone the Repository +```bash +git clone https://github.com/memohai/Memoh.git +cd Memoh +``` + +### 2. One-Click Deployment +```bash +./deploy.sh +``` + +The script will automatically: +- Check Docker and Docker Compose installation +- Create `.env` configuration file (if not exists) +- Generate random JWT secret +- Create `config.toml` configuration file +- Build MCP image +- Start all services + +### 3. Access the Application +- Web UI: http://localhost +- API Service: http://localhost:8080 +- Agent Gateway: http://localhost:8081 + +Default admin credentials: +- Username: `admin` +- Password: `admin123` (change in `.env`) + +## Manual Deployment + +If you prefer not to use the automated script: + +```bash +# 1. Create configuration files +cp .env.example .env +cp config.docker.toml config.toml + +# 2. Edit configuration (Important!) +nano .env + +# 3. Generate JWT secret +openssl rand -base64 32 + +# 4. Build MCP image +docker build -f cmd/mcp/Dockerfile -t memoh-mcp:latest . + +# 5. Start services +docker compose up -d + +# 6. View logs +docker compose logs -f +``` + +## Architecture + +This deployment uses the host's Docker daemon to manage Bot containers: + +``` +Host Docker +├── memoh-postgres (PostgreSQL) +├── memoh-qdrant (Qdrant) +├── memoh-server (Main Service) ← Manages Bot containers via /var/run/docker.sock +├── memoh-agent (Agent Gateway) +├── memoh-web (Web Frontend) +└── memoh-bot-* (Bot containers, dynamically created by main service) +``` + +Advantages: +- ✅ Lightweight, no additional Docker daemon needed +- ✅ Better performance, uses host container runtime directly +- ✅ Easier to manage and debug +- ✅ Lower resource consumption + +## Common Commands + +### Using Make (Recommended) +```bash +make help # Show all commands +make deploy # One-click deployment +make logs # View logs +make restart # Restart services +make ps # View status +make backup # Backup data +make bots # View Bot containers +``` + +### Using Docker Compose +```bash +docker compose up -d # Start services +docker compose down # Stop services +docker compose logs -f # View logs +docker compose ps # View status +docker compose restart # Restart services +``` + +## Configuration + +### Environment Variables (.env) + +Key configuration items: + +```bash +# PostgreSQL password (must change) +POSTGRES_PASSWORD=your_secure_password + +# JWT secret (must change) +JWT_SECRET=your_random_jwt_secret + +# Admin account +ADMIN_USERNAME=admin +ADMIN_PASSWORD=your_admin_password +ADMIN_EMAIL=admin@yourdomain.com +``` + +### Application Configuration (config.toml) + +Main configuration items: + +```toml +[postgres] +host = "postgres" +password = "your_secure_password" # Must match POSTGRES_PASSWORD in .env + +[containerd] +socket_path = "unix:///var/run/docker.sock" # Use host Docker + +[qdrant] +base_url = "http://qdrant:6334" +``` + +## Service Overview + +| Service | Container Name | Ports | Description | +|---------|---------------|-------|-------------| +| postgres | memoh-postgres | - | PostgreSQL database (internal only) | +| qdrant | memoh-qdrant | - | Qdrant vector database (internal only) | +| docker-cli | memoh-docker-cli | - | Docker CLI (uses host Docker) | +| server | memoh-server | 8080 | Main service (Go) | +| agent | memoh-agent | 8081 | Agent Gateway (Bun) | +| web | memoh-web | 80 | Web frontend (Nginx) | + +## Data Persistence + +Data is stored in Docker volumes: + +```bash +# View volumes +docker volume ls | grep memoh + +# Backup database +docker compose exec postgres pg_dump -U memoh memoh > backup.sql +``` + +### Bot Container Management + +Bot containers are dynamically created by the main service and run directly on the host: + +```bash +# View all Bot containers +make bots +# or +docker ps -a | grep memoh-bot + +# View Bot logs +docker logs + +# Enter Bot container +docker exec -it sh + +# Stop Bot container +docker stop +``` + +## Backup and Restore + +### Backup +```bash +# Create backup directory +mkdir -p backups + +# Backup database +docker compose exec postgres pg_dump -U memoh memoh > backups/postgres_$(date +%Y%m%d).sql + +# Backup Bot data +docker run --rm -v memoh_memoh_bot_data:/data -v $(pwd)/backups:/backup alpine \ + tar czf /backup/bot_data_$(date +%Y%m%d).tar.gz -C /data . + +# Backup configuration files +tar czf backups/config_$(date +%Y%m%d).tar.gz config.toml .env +``` + +### Restore +```bash +# Restore database +docker compose exec -T postgres psql -U memoh memoh < backups/postgres_20240101.sql + +# Restore Bot data +docker run --rm -v memoh_memoh_bot_data:/data -v $(pwd)/backups:/backup alpine \ + tar xzf /backup/bot_data_20240101.tar.gz -C /data +``` + +## Troubleshooting + +### Services Won't Start +```bash +# View detailed logs +docker compose logs server + +# Check configuration +docker compose config + +# Rebuild +docker compose build --no-cache +docker compose up -d +``` + +### Database Connection Failed +```bash +# Check if database is ready +docker compose exec postgres pg_isready -U memoh + +# Test connection +docker compose exec postgres psql -U memoh -d memoh + +# View database logs +docker compose logs postgres +``` + +### Port Conflicts +```bash +# Check port usage +sudo netstat -tlnp | grep :8080 +sudo netstat -tlnp | grep :80 + +# Modify port mapping in docker-compose.yml +# Example: change "80:80" to "8000:80" +``` + +### Docker Socket Permission Issues +```bash +# Add user to docker group +sudo usermod -aG docker $USER +newgrp docker + +# Check permissions +ls -la /var/run/docker.sock +``` + +## Production Deployment + +### 1. Use HTTPS + +Create `docker-compose.override.yml`: +```yaml +services: + web: + ports: + - "443:443" + volumes: + - ./ssl:/etc/nginx/ssl:ro + - ./nginx-https.conf:/etc/nginx/conf.d/default.conf:ro +``` + +Create `nginx-https.conf`: +```nginx +server { + listen 80; + server_name your-domain.com; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /etc/nginx/ssl/cert.pem; + ssl_certificate_key /etc/nginx/ssl/key.pem; + + # SSL configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + # Other configurations same as nginx.conf + # ... +} +``` + +### 2. Resource Limits + +Edit `docker-compose.yml` to add resource limits: +```yaml +services: + server: + deploy: + resources: + limits: + cpus: '2' + memory: 2G + reservations: + cpus: '1' + memory: 1G +``` + +### 3. Security Recommendations + +Production environment recommendations: +- Use separate `.env` file +- Change all default passwords +- Use strong JWT secret +- Configure firewall rules +- Use HTTPS +- Regular data backups +- Limit containerd socket access permissions +- Run services as non-root user +- Configure log rotation + +## Performance Optimization + +### PostgreSQL Optimization +Create `postgres-custom.conf`: +``` +shared_buffers = 2GB +effective_cache_size = 6GB +maintenance_work_mem = 512MB +checkpoint_completion_target = 0.9 +wal_buffers = 16MB +``` + +Mount in `docker-compose.yml`: +```yaml +postgres: + volumes: + - ./postgres-custom.conf:/etc/postgresql/postgresql.conf:ro + command: postgres -c config_file=/etc/postgresql/postgresql.conf +``` + +### Network Optimization +```yaml +networks: + memoh-network: + driver: bridge + driver_opts: + com.docker.network.driver.mtu: 1500 +``` + +## Update Application + +```bash +# Pull latest code +git pull + +# Rebuild and restart +docker compose up -d --build + +# Or use Make +make update +``` + +## Complete Uninstall + +```bash +# Stop and remove all containers +docker compose down + +# Remove data volumes (Warning! This deletes all data) +docker compose down -v + +# Remove images +docker rmi memoh-mcp:latest +docker rmi $(docker images | grep memoh | awk '{print $3}') +``` + +## Security Considerations + +⚠️ Important Security Notes: + +1. **Docker Socket Access**: The main service container has access to the host Docker socket, which means the application can manage other containers on the host. Only run in trusted environments. +2. **Change Default Passwords**: Must change all default passwords in `.env` +3. **Strong JWT Secret**: Use a strong random JWT secret +4. **Firewall**: Configure firewall to only open necessary ports +5. **HTTPS**: Use HTTPS in production +6. **Regular Backups**: Regularly backup data +7. **Updates**: Regularly update images and dependencies + +## Get Help + +- Detailed Documentation: [DOCKER_DEPLOYMENT_CN.md](DOCKER_DEPLOYMENT_CN.md) (Chinese) +- GitHub Issues: https://github.com/memohai/Memoh/issues +- Telegram Group: https://t.me/memohai +- Email: business@memoh.net + +--- + +**That's it! Deploy Memoh in minutes!** diff --git a/Dockerfile.agent b/Dockerfile.agent new file mode 100644 index 00000000..e77893ae --- /dev/null +++ b/Dockerfile.agent @@ -0,0 +1,28 @@ +FROM oven/bun:1 AS builder + +WORKDIR /build + +COPY agent/package.json agent/bun.lock* ./ + +RUN bun install + +COPY agent/ ./ + +RUN bun run build + +FROM oven/bun:1-alpine + +WORKDIR /app + +RUN apk add --no-cache ca-certificates wget + +COPY --from=builder /build/dist /app/dist +COPY --from=builder /build/node_modules /app/node_modules +COPY --from=builder /build/package.json /app/package.json + +EXPOSE 8081 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8081/health || exit 1 + +CMD ["bun", "run", "dist/index.js"] diff --git a/Dockerfile.server b/Dockerfile.server new file mode 100644 index 00000000..f14c1c56 --- /dev/null +++ b/Dockerfile.server @@ -0,0 +1,33 @@ +FROM golang:1.25-alpine AS builder + +WORKDIR /build + +RUN apk add --no-cache git make + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ + go build -trimpath -ldflags "-s -w" \ + -o memoh-server ./cmd/agent/main.go + +FROM alpine:latest + +WORKDIR /app + +RUN apk add --no-cache ca-certificates tzdata wget + +COPY --from=builder /build/memoh-server /app/memoh-server + +COPY config.toml.example /app/config.toml.example + +RUN mkdir -p /var/lib/memoh/data + +EXPOSE 8080 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 + +CMD ["/app/memoh-server"] diff --git a/Dockerfile.web b/Dockerfile.web new file mode 100644 index 00000000..c19f54f2 --- /dev/null +++ b/Dockerfile.web @@ -0,0 +1,33 @@ +FROM node:25-alpine AS builder + +WORKDIR /build + +RUN npm install -g pnpm@10 + +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ + +COPY packages ./packages + +RUN pnpm install + +ARG VITE_API_URL=http://localhost:8080 +ARG VITE_AGENT_URL=http://localhost:8081 + +ENV VITE_API_URL=$VITE_API_URL +ENV VITE_AGENT_URL=$VITE_AGENT_URL + +WORKDIR /build/packages/web +RUN pnpm build + +FROM nginx:alpine + +COPY --from=builder /build/packages/web/dist /usr/share/nginx/html + +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 5037b521..f3c4314d 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,23 @@ Memoh Bot can distinguish and remember requests from multiple humans and bots, w Please refer to the [Roadmap Version 0.1](https://github.com/memohai/Memoh/issues/2) for more details. -## Development +## Quick Start -Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more details. +### Docker Deployment (Recommended) + +The fastest way to deploy Memoh: + +```bash +git clone https://github.com/memohai/Memoh.git +cd Memoh +./deploy.sh +``` + +Visit http://localhost after deployment. See [Docker Deployment Guide](README_DOCKER.md) for details. + +### Development + +Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for development setup. ## Star History diff --git a/README_CN.md b/README_CN.md index d7bff033..0af59b14 100644 --- a/README_CN.md +++ b/README_CN.md @@ -43,7 +43,21 @@ Memoh Bot 能够区分并记忆来自多个人类/Bot 的请求,可在任意 详情请参阅 [Roadmap Version 0.1](https://github.com/memohai/Memoh/issues/2)。 -## 开发 +## 快速开始 + +### Docker 部署(推荐) + +最快的部署方式: + +```bash +git clone https://github.com/memohai/Memoh.git +cd Memoh +./deploy.sh +``` + +部署完成后访问 http://localhost。详见 [Docker 部署指南](README_DOCKER.md)。 + +### 开发环境 详见 [CONTRIBUTING.md](CONTRIBUTING.md)。 diff --git a/config.docker.toml b/config.docker.toml new file mode 100644 index 00000000..f8d34c21 --- /dev/null +++ b/config.docker.toml @@ -0,0 +1,54 @@ +## Service configuration +[log] +level = "info" +format = "text" + +[server] +addr = ":8080" + +## Admin +[admin] +username = "admin" +password = "admin123" +email = "admin@memoh.local" + +## Auth configuration +[auth] +jwt_secret = "YZq8kXrW5dFpNt9mLxQvHbRjKsMnOePw" +jwt_expires_in = "168h" + +## Docker configuration (使用宿主机 Docker socket) +[containerd] +socket_path = "unix:///var/run/docker.sock" +namespace = "default" + +[mcp] +busybox_image = "memoh-mcp:latest" +snapshotter = "overlayfs" +data_root = "/var/lib/memoh/data" +data_mount = "/data" + +## Postgres configuration +[postgres] +host = "postgres" +port = 5432 +user = "memoh" +password = "memoh123" +database = "memoh" +sslmode = "disable" + +## Qdrant configuration +[qdrant] +base_url = "http://qdrant:6334" +api_key = "" +collection = "memory" +timeout_seconds = 10 + +## Agent Gateway +[agent_gateway] +host = "agent" +port = 8081 + +[brave] +api_key = "" +base_url = "https://api.search.brave.com/res/v1/" diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..b60a136b --- /dev/null +++ b/deploy.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +set -e + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN} Memoh Docker Compose Deployment${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" + +# Check Docker +if ! command -v docker &> /dev/null; then + echo -e "${RED}Error: Docker is not installed${NC}" + echo "Please install Docker first: https://docs.docker.com/get-docker/" + exit 1 +fi + +# Check Docker Compose +if ! docker compose version &> /dev/null; then + echo -e "${RED}Error: Docker Compose is not installed or version is too old${NC}" + echo "Please install Docker Compose v2.0+: https://docs.docker.com/compose/install/" + exit 1 +fi + +echo -e "${GREEN}✓ Docker and Docker Compose are installed${NC}" +echo "" + +# Check .env file +if [ ! -f .env ]; then + echo -e "${YELLOW}⚠ .env file does not exist, creating...${NC}" + cp .env.example .env + + # Generate random JWT secret + JWT_SECRET=$(openssl rand -base64 32 2>/dev/null || head -c 32 /dev/urandom | base64) + sed -i.bak "s|JWT_SECRET=.*|JWT_SECRET=$JWT_SECRET|g" .env + rm -f .env.bak + + echo -e "${GREEN}✓ .env file created${NC}" + echo -e "${YELLOW}⚠ Please edit .env file to change default passwords and configuration${NC}" + echo "" +fi + +# Check config.toml +if [ ! -f config.toml ]; then + echo -e "${YELLOW}⚠ config.toml does not exist, creating...${NC}" + cp config.docker.toml config.toml + echo -e "${GREEN}✓ config.toml created${NC}" + echo "" +fi + +# Build MCP image +echo -e "${GREEN}Building MCP image...${NC}" +if docker build -f cmd/mcp/Dockerfile -t memoh-mcp:latest . > /dev/null 2>&1; then + echo -e "${GREEN}✓ MCP image built successfully${NC}" +else + echo -e "${YELLOW}⚠ MCP image build failed, will try to pull at runtime${NC}" +fi +echo "" + +# Start services +echo -e "${GREEN}Starting services...${NC}" +docker compose up -d + +echo "" +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN} Deployment Complete!${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" +echo "Service URLs:" +echo " - Web UI: http://localhost" +echo " - API Service: http://localhost:8080" +echo " - Agent Gateway: http://localhost:8081" +echo "" +echo "View service status:" +echo " docker compose ps" +echo "" +echo "View logs:" +echo " docker compose logs -f" +echo "" +echo "Stop services:" +echo " docker compose down" +echo "" +echo -e "${YELLOW}⚠ First startup may take 1-2 minutes, please be patient${NC}" +echo "" +echo "View detailed documentation: DEPLOYMENT.md" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..62c4ad38 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,137 @@ +services: + + postgres: + image: postgres:16-alpine + container_name: memoh-postgres + environment: + POSTGRES_DB: memoh + POSTGRES_USER: memoh + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-memoh123} + volumes: + - postgres_data:/var/lib/postgresql/data + - ./db/migrations:/docker-entrypoint-initdb.d:ro + expose: + - "5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U memoh"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + networks: + - memoh-network + + qdrant: + image: qdrant/qdrant:latest + container_name: memoh-qdrant + volumes: + - qdrant_data:/qdrant/storage + expose: + - "6333" + - "6334" + healthcheck: + test: ["CMD-SHELL", "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/6333' || exit 1"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + networks: + - memoh-network + + docker-cli: + image: docker:27-cli + container_name: memoh-docker-cli + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - memoh_bot_data:/var/lib/memoh/data + command: ["tail", "-f", "/dev/null"] + restart: unless-stopped + networks: + - memoh-network + + server: + build: + context: . + dockerfile: Dockerfile.server + container_name: memoh-server + environment: + - LOG_LEVEL=${LOG_LEVEL:-info} + - SERVER_ADDR=:8080 + - POSTGRES_HOST=postgres + - POSTGRES_PORT=5432 + - POSTGRES_USER=memoh + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-memoh123} + - POSTGRES_DB=memoh + - POSTGRES_SSLMODE=disable + - QDRANT_BASE_URL=http://qdrant:6334 + - QDRANT_COLLECTION=memory + - CONTAINERD_SOCKET=unix:///var/run/docker.sock + - AGENT_GATEWAY_HOST=agent + - AGENT_GATEWAY_PORT=8081 + - JWT_SECRET=${JWT_SECRET:-YZq8kXrW5dFpNt9mLxQvHbRjKsMnOePw} + - JWT_EXPIRES_IN=168h + - ADMIN_USERNAME=${ADMIN_USERNAME:-admin} + - ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin123} + - ADMIN_EMAIL=${ADMIN_EMAIL:-admin@memoh.local} + - MCP_BUSYBOX_IMAGE=memoh-mcp:latest + - MCP_DATA_ROOT=/var/lib/memoh/data + - MCP_DATA_MOUNT=/data + volumes: + - ./config.toml:/app/config.toml:ro + - /var/run/docker.sock:/var/run/docker.sock + - memoh_bot_data:/var/lib/memoh/data + ports: + - "8080:8080" + depends_on: + postgres: + condition: service_healthy + qdrant: + condition: service_healthy + restart: unless-stopped + networks: + - memoh-network + + agent: + build: + context: . + dockerfile: Dockerfile.agent + container_name: memoh-agent + environment: + - NODE_ENV=production + - PORT=8081 + ports: + - "8081:8081" + depends_on: + - server + restart: unless-stopped + networks: + - memoh-network + + web: + build: + context: . + dockerfile: Dockerfile.web + args: + - VITE_API_URL=${VITE_API_URL:-http://localhost:8080} + - VITE_AGENT_URL=${VITE_AGENT_URL:-http://localhost:8081} + container_name: memoh-web + ports: + - "8090:80" + depends_on: + - server + - agent + restart: unless-stopped + networks: + - memoh-network + +volumes: + postgres_data: + driver: local + qdrant_data: + driver: local + memoh_bot_data: + driver: local + +networks: + memoh-network: + driver: bridge diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 00000000..b89ba890 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,64 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + # Gzip 压缩 + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript; + + # 前端路由 + location / { + try_files $uri $uri/ /index.html; + } + + # API 代理 + location /api/ { + proxy_pass http://memoh-server:8080/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # 超时设置 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # Agent Gateway 代理 + location /agent/ { + proxy_pass http://memoh-agent:8081/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # 超时设置 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # 静态资源缓存 + location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # 安全头 + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; +}