部署指南

部署指南

M-Doc 支持 Docker 部署和二进制部署两种方式。完整生产部署需要同时运行后端 API 服务、前端 Nuxt 服务、PostgreSQL 和 Redis;仅启动后端镜像无法提供完整 Web 界面。


环境要求

组件 最低要求 推荐
Go 1.25+(仅源码构建后端时需要) 最新稳定版
数据库 PostgreSQL 14+ / MySQL 8.0+ / SQLite 3 PostgreSQL 16 + pgvector
Redis 6.0+ 7.0+
Node.js 18+(仅源码构建前端时需要) 22 LTS

如需使用语义搜索或向量检索,PostgreSQL 必须安装并启用 vector 扩展。Docker 部署建议直接使用带 pgvector 的 PostgreSQL 镜像。

Docker 部署(推荐)

1. 准备配置文件

创建 config.yaml,其中 database.hostredis.host 使用 Compose 服务名:

server:
  mode: release
  addr: ":8080"
  base_url: "https://your-domain.com"

app:
  base_url: "https://your-domain.com"

database:
  driver: postgresql
  host: postgres
  port: 5432
  username: mdoc
  password: your-password
  dbname: mdoc

redis:
  host: redis
  port: 6379
  password: ""
  db: 0

jwt:
  secret: "your-jwt-secret-change-this"
  expire_hours: 168

migration:
  enabled: true
  halt_on_failure: true

2. 开启 PostgreSQL 向量扩展

如果是全新 Docker 数据库,创建初始化 SQL:

mkdir -p initdb
cat > initdb/001-enable-vector.sql <<'SQL'
CREATE EXTENSION IF NOT EXISTS vector;
SQL

如果使用已经存在的 PostgreSQL 或云数据库,需要确认数据库实例已安装 pgvector,并在 mdoc 数据库中执行:

CREATE EXTENSION IF NOT EXISTS vector;

3. 使用 Docker Compose 部署

version: '3.8'

services:
  postgres:
    image: pgvector/pgvector:pg16
    environment:
      POSTGRES_DB: mdoc
      POSTGRES_USER: mdoc
      POSTGRES_PASSWORD: your-password
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./initdb:/docker-entrypoint-initdb.d:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mdoc -d mdoc"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redisdata:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  mdoc-server:
    image: docker.cnb.cool/mliev/mdoc/mdoc-server:master
    ports:
      - "8080:8080"
    volumes:
      - ./config.yaml:/app/config.yaml:ro
      - server_logs:/app/logs
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped

  mdoc-frontend:
    image: docker.cnb.cool/mliev/mdoc/frontend:1.44.5
    environment:
      NODE_ENV: production
      NUXT_HOST: 0.0.0.0
      NUXT_PORT: "3000"
      # 这里必须填写浏览器可访问的后端地址,不要写 Docker 内部服务名。
      NUXT_PUBLIC_API_BASE: https://your-domain.com
      # 可选:站点备案、白名单、统计脚本等前端运行时配置。
      # NUXT_PUBLIC_ICP_BEIAN: ""
      # NUXT_PUBLIC_LINK_WHITELIST: "example.com,www.example.com"
      # NUXT_PUBLIC_ANALYTICS_SCRIPT: ""
    ports:
      - "3000:3000"
    depends_on:
      - mdoc-server
    restart: unless-stopped

volumes:
  pgdata:
  redisdata:
  server_logs:

启动:

docker compose up -d

检查服务:

docker compose ps
docker compose logs -f mdoc-server mdoc-frontend

4. 镜像说明

  • 后端镜像:docker.cnb.cool/mliev/mdoc/mdoc-server:master,监听 8080 端口,提供 /api/openapi 和健康检查接口。
  • 前端镜像:docker.cnb.cool/mliev/mdoc/frontend:1.44.5,监听 3000 端口,提供 Nuxt Web 页面。
  • PostgreSQL 镜像建议使用 pgvector/pgvector:pg16,否则普通 postgres:16-alpine 镜像默认不包含 pgvector 扩展文件,执行 CREATE EXTENSION vector 可能失败。

如镜像仓库需要认证,先在部署机器执行 docker login docker.cnb.cool;Kubernetes 环境中则配置对应的 imagePullSecrets

5. Kubernetes 部署要点

Kubernetes 中也需要同时部署后端和前端两个 Deployment / Service:

# 后端容器关键字段
containers:
  - name: mdoc-server
    image: docker.cnb.cool/mliev/mdoc/mdoc-server:master
    ports:
      - containerPort: 8080
        name: server-proxy
    volumeMounts:
      - name: config-file
        mountPath: /app/config.yaml
        subPath: config.yaml

# 前端容器关键字段
containers:
  - name: mdoc-frontend
    image: docker.cnb.cool/mliev/mdoc/frontend:1.44.5
    env:
      - name: NODE_ENV
        value: production
      - name: NUXT_HOST
        value: 0.0.0.0
      - name: NUXT_PORT
        value: "3000"
      - name: NUXT_PUBLIC_API_BASE
        value: https://your-domain.com
    ports:
      - containerPort: 3000
        name: frontend-proxy

PostgreSQL 在 Kubernetes 中同样需要使用支持 pgvector 的镜像,或在云数据库实例中开启 vector 扩展。

二进制部署

二进制部署时,后端和前端仍然是两个独立服务。

1. 编译后端

# 克隆代码
git clone https://cnb.cool/mliev/mdoc/mdoc-server.git
cd mdoc-server

# 编译后端
go build -ldflags="-s -w" -o mdoc-server main.go

准备 config.yaml,配置 PostgreSQL、Redis、JWT、server.base_urlapp.base_url 后启动:

./mdoc-server start

后端默认监听 :8080 端口。

2. 编译并运行前端

# 初始化前端子模块
cd mdoc-server
git submodule update --init --recursive

# 构建前端
cd frontend
pnpm install
NUXT_PUBLIC_API_BASE=https://your-domain.com pnpm build

# 运行 Nuxt 服务
NODE_ENV=production NUXT_HOST=0.0.0.0 NUXT_PORT=3000 node .output/server/index.mjs

前端默认监听 :3000 端口。

数据库初始化

M-Doc 支持自动迁移,首次启动时会自动创建所需的表结构。

配置项:

migration:
  enabled: true           # 启动时自动执行迁移
  halt_on_failure: true   # 迁移失败是否停止启动

向量搜索依赖 PostgreSQL 的 pgvector 扩展。确认扩展是否已开启:

SELECT extname FROM pg_extension WHERE extname = 'vector';

未返回结果时执行:

CREATE EXTENSION IF NOT EXISTS vector;

健康检查

端点 说明
GET /health/simple 简单健康检查,返回最小响应
GET /health 详细健康检查,返回系统状态

反向代理配置(Nginx)

如果前后端共用同一个域名,建议将页面流量转发到前端,将 API 流量转发到后端:

server {
    listen 443 ssl;
    server_name your-domain.com;

    location /api/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        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;
    }

    location /openapi/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        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;
    }

    location /health {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        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;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        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;
    }
}