上一篇 下一篇 分享链接 返回 返回顶部

从零搭建一套可私有化部署的 AI 办公助手:Docker 一键上线+完整源码

发布人:慈云数据-客服中心 发布时间:23小时前 阅读量:6

AI办公 Docker部署教程|附源码

随着大语言模型(LLM)能力的不断提升,越来越多企业和个人开始把 AI 引入日常办公场景,例如:文档摘要、会议纪要生成、邮件润色、PPT 大纲生成、Excel 数据分析、知识库问答等。相比直接使用公开 AI 工具,自建一套“AI办公助手”有几个明显优势:数据可控、可接入企业内部知识库、可按需扩展功能、部署成本可控,并且能够结合公司业务进行二次开发。

本文将带你从零搭建一个简易版 AI办公系统,并使用 Docker + Docker Compose 完成一键部署。项目包含前端页面、后端 API 服务、数据库服务,并预留大模型接口配置。文章会提供完整目录结构、核心源码、Dockerfile、docker-compose.yml 以及部署步骤,适合学习、二次开发和企业内部原型验证。


一、项目功能介绍

本教程实现的是一个轻量级 AI办公助手,主要包含以下功能:

  1. AI 对话办公助手

    • 支持输入办公需求,例如“帮我写一封请假邮件”“总结下面这段文档内容”。
    • 后端调用大模型接口返回结果。
  2. 文档摘要

    • 用户输入一段较长文本。
    • AI 自动生成摘要、重点和待办事项。
  3. 邮件润色

    • 将普通表达转换为正式、礼貌、商务风格的邮件内容。
  4. 会议纪要生成

    • 根据会议记录生成结构化纪要,包括会议主题、参会人员、重点结论、待办事项。
  5. 历史记录保存

    • 使用 MySQL 存储用户请求和 AI 返回内容。
    • 便于后续查看和统计。
  6. Docker 一键部署

    • 前端、后端、数据库统一编排。
    • 适合部署到本地服务器、云服务器或内网环境。

二、技术栈说明

本项目采用前后端分离架构:

模块 技术
前端 Vue 3 + Vite
后端 Node.js + Express
数据库 MySQL 8
部署 Docker + Docker Compose
AI接口 OpenAI兼容接口 / 私有大模型接口

整体架构如下:

用户浏览器
   │
   ▼
前端 Vue 页面
   │ HTTP请求
   ▼
后端 Express API
   │
   ├── 调用大模型接口
   │
   └── 写入 MySQL 数据库

三、项目目录结构

创建项目目录:

mkdir ai-office-docker
cd ai-office-docker

推荐目录结构如下:

ai-office-docker
├── backend
│   ├── Dockerfile
│   ├── package.json
│   ├── server.js
│   └── .env.example
├── frontend
│   ├── Dockerfile
│   ├── nginx.conf
│   ├── package.json
│   ├── index.html
│   └── src
│       ├── App.vue
│       └── main.js
├── mysql
│   └── init.sql
└── docker-compose.yml

四、后端源码编写

后端主要负责三件事:

  1. 接收前端请求;
  2. 调用 AI 大模型接口;
  3. 保存请求历史记录到数据库。

进入后端目录:

mkdir backend
cd backend

1. 创建 package.json

{
  "name": "ai-office-backend",
  "version": "1.0.0",
  "description": "AI Office Backend API",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "axios": "^1.6.8",
    "cors": "^2.8.5",
    "dotenv": "^16.4.5",
    "express": "^4.18.3",
    "mysql2": "^3.9.2"
  }
}

2. 创建环境变量示例文件

文件名:backend/.env.example

PORT=3000

DB_HOST=mysql
DB_PORT=3306
DB_USER=root
DB_PASSWORD=123456
DB_NAME=ai_office

AI_API_KEY=your_api_key
AI_BASE_URL=https://api.openai.com/v1/chat/completions
AI_MODEL=gpt-4o-mini

说明:

  • AI_API_KEY:填写你的大模型 API Key。
  • AI_BASE_URL:如果你使用的是兼容 OpenAI 格式的国产模型,也可以填写对应接口地址。
  • AI_MODEL:模型名称,可根据服务商要求修改。

3. 创建 server.js

文件名:backend/server.js

const express = require("express");
const cors = require("cors");
const axios = require("axios");
const mysql = require("mysql2/promise");
require("dotenv").config();

const app = express();

app.use(cors());
app.use(express.json({ limit: "5mb" }));

const PORT = process.env.PORT || 3000;

const dbConfig = {
  host: process.env.DB_HOST || "mysql",
  port: process.env.DB_PORT || 3306,
  user: process.env.DB_USER || "root",
  password: process.env.DB_PASSWORD || "123456",
  database: process.env.DB_NAME || "ai_office",
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
};

const pool = mysql.createPool(dbConfig);

function buildPrompt(type, content) {
  const prompts = {
    chat: `你是一名专业的AI办公助手,请根据用户需求提供清晰、实用、结构化的回答。用户内容如下:\n${content}`,
    summary: `请将以下文本整理为办公摘要,要求包含:1.核心摘要;2.重点事项;3.待办清单。\n文本内容:\n${content}`,
    email: `请将以下内容润色为正式、礼貌、商务风格的邮件,要求语气自然、表达清晰。\n原始内容:\n${content}`,
    meeting: `请根据以下会议记录生成会议纪要,要求包含:会议主题、会议结论、关键讨论点、待办事项、责任人建议。\n会议记录:\n${content}`
  };

  return prompts[type] || prompts.chat;
}

async function callAI(prompt) {
  const apiKey = process.env.AI_API_KEY;
  const baseURL = process.env.AI_BASE_URL;
  const model = process.env.AI_MODEL || "gpt-4o-mini";

  if (!apiKey) {
    return "当前未配置 AI_API_KEY,请在 docker-compose.yml 或 .env 文件中配置大模型接口密钥。";
  }

  const response = await axios.post(
    baseURL,
    {
      model,
      messages: [
        {
          role: "system",
          content: "你是一个擅长企业办公、文档处理、会议纪要和商务沟通的AI助手。"
        },
        {
          role: "user",
          content: prompt
        }
      ],
      temperature: 0.7
    },
    {
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      timeout: 60000
    }
  );

  return response.data.choices?.[0]?.message?.content || "AI未返回有效内容。";
}

async function saveHistory(type, input, output) {
  const sql = `
    INSERT INTO histories(type, input_text, output_text)
    VALUES (?, ?, ?)
  `;
  await pool.execute(sql, [type, input, output]);
}

app.get("/api/health", async (req, res) => {
  res.json({
    status: "ok",
    message: "AI Office Backend is running"
  });
});

app.post("/api/ai", async (req, res) => {
  try {
    const { type, content } = req.body;

    if (!content || !content.trim()) {
      return res.status(400).json({
        success: false,
        message: "内容不能为空"
      });
    }

    const prompt = buildPrompt(type, content);
    const result = await callAI(prompt);

    await saveHistory(type || "chat", content, result);

    res.json({
      success: true,
      data: result
    });
  } catch (error) {
    console.error("AI处理失败:", error.message);

    res.status(500).json({
      success: false,
      message: "AI处理失败,请检查接口配置或网络连接",
      error: error.message
    });
  }
});

app.get("/api/histories", async (req, res) => {
  try {
    const [rows] = await pool.query(`
      SELECT id, type, input_text, output_text, created_at
      FROM histories
      ORDER BY id DESC
      LIMIT 20
    `);

    res.json({
      success: true,
      data: rows
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      message: "查询历史记录失败",
      error: error.message
    });
  }
});

app.listen(PORT, () => {
  console.log(`AI Office Backend running on port ${PORT}`);
});

4. 后端 Dockerfile

文件名:backend/Dockerfile

FROM node:20-alpine

WORKDIR /app

COPY package.json ./

RUN npm install --registry=https://registry.npmmirror.com

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

五、数据库初始化脚本

回到项目根目录,创建 MySQL 初始化目录:

mkdir mysql

创建文件:mysql/init.sql

CREATE DATABASE IF NOT EXISTS ai_office
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

USE ai_office;

CREATE TABLE IF NOT EXISTS histories (
  id INT AUTO_INCREMENT PRIMARY KEY,
  type VARCHAR(50) NOT NULL COMMENT '功能类型:chat/summary/email/meeting',
  input_text LONGTEXT NOT NULL COMMENT '用户输入内容',
  output_text LONGTEXT NOT NULL COMMENT 'AI输出内容',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这个表用于保存用户的输入内容和 AI 返回结果。实际生产环境中,可以继续扩展用户表、权限表、知识库表、文件上传表等。


六、前端源码编写

前端使用 Vue 3 + Vite,实现一个简单清爽的办公助手页面。用户可以选择功能类型,输入内容,然后点击生成。

进入前端目录:

mkdir frontend
cd frontend

1. 创建 package.json

文件名:frontend/package.json

{
  "name": "ai-office-frontend",
  "version": "1.0.0",
  "description": "AI Office Frontend",
  "scripts": {
    "dev": "vite --host 0.0.0.0",
    "build": "vite build"
  },
  "dependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
    "vite": "^5.1.6",
    "vue": "^3.4.21"
  },
  "devDependencies": {}
}

2. 创建 index.html

文件名:frontend/index.html



  
    
    AI办公助手
    
  
  
    

3. 创建 main.js

创建目录:

mkdir src

文件名:frontend/src/main.js

import { createApp } from "vue";
import App from "./App.vue";

createApp(App).mount("#app");

4. 创建 App.vue

文件名:frontend/src/App.vue





5. 前端 Nginx 配置

由于前端构建后是静态文件,我们使用 Nginx 托管,同时将 /api 请求反向代理到后端服务。

文件名:frontend/nginx.conf

server {
    listen 80;
    server_name localhost;

    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://backend:3000/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

6. 前端 Dockerfile

文件名:frontend/Dockerfile

FROM node:20-alpine AS builder

WORKDIR /app

COPY package.json ./

RUN npm install --registry=https://registry.npmmirror.com

COPY . .

RUN npm run build

FROM nginx:1.25-alpine

COPY nginx.conf /etc/nginx/conf.d/default.conf

COPY --from=builder /app/dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

七、Docker Compose 编排

回到项目根目录,创建 docker-compose.yml

version: "3.8"

services:
  mysql:
    image: mysql:8.0
    container_name: ai-office-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: ai_office
      TZ: Asia/Shanghai
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - ai-office-net

  backend:
    build:
      context: ./backend
    container_name: ai-office-backend
    restart: always
    depends_on:
      - mysql
    environment:
      PORT: 3000
      DB_HOST: mysql
      DB_PORT: 3306
      DB_USER: root
      DB_PASSWORD: 123456
      DB_NAME: ai_office

      AI_API_KEY: your_api_key
      AI_BASE_URL: https://api.openai.com/v1/chat/completions
      AI_MODEL: gpt-4o-mini
    ports:
      - "3000:3000"
    networks:
      - ai-office-net

  frontend:
    build:
      context: ./frontend
    container_name: ai-office-frontend
    restart: always
    depends_on:
      - backend
    ports:
      - "8080:80"
    networks:
      - ai-office-net

volumes:
  mysql_data:

networks:
  ai-office-net:
    driver: bridge

注意:请将 AI_API_KEY: your_api_key 替换成你自己的大模型接口密钥。如果你使用的是私有化模型接口,例如企业内部部署的 Qwen、DeepSeek、GLM、Llama 等,只要接口兼容 OpenAI Chat Completions 格式,就可以直接替换 AI_BASE_URLAI_MODEL


八、启动部署

在项目根目录执行:

docker compose up -d --build

如果你的 Docker 版本较旧,也可能需要使用:

docker-compose up -d --build

查看容器状态:

docker ps

正常情况下可以看到三个容器:

ai-office-mysql
ai-office-backend
ai-office-frontend

查看后端日志:

docker logs -f ai-office-backend

查看前端日志:

docker logs -f ai-office-frontend

访问系统:

http://服务器IP:8080

如果是本地部署,可以访问:

http://localhost:8080

九、接口测试

除了通过前端页面访问,也可以使用 curl 测试后端接口。

1. 健康检查

curl http://localhost:3000/api/health

返回示例:

{
  "status": "ok",
  "message": "AI Office Backend is running"
}

2. AI 办公生成接口

curl -X POST http://localhost:3000/api/ai \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "content": "通知客户项目因为供应商原因要延期一周,希望客户理解"
  }'

返回示例:

{
  "success": true,
  "data": "尊敬的客户您好:\n\n非常感谢您一直以来对我们项目工作的支持..."
}

3. 查询历史记录

curl http://localhost:3000/api/histories

十、常见问题与解决方法

1. 前端页面能打开,但 AI 请求失败

可能原因:

  • 后端服务未启动;
  • Nginx 反向代理配置错误;
  • 后端接口地址不正确;
  • 大模型 API Key 未配置;
  • 服务器无法访问外部 AI 接口。

解决方法:

docker logs -f ai-office-backend

查看后端日志,根据错误信息定位问题。


2. MySQL 连接失败

后端启动时如果出现类似错误:

ECONNREFUSED
Access denied for user
Unknown database

可以检查:

  1. docker-compose.yml 中数据库密码是否一致;
  2. MySQL 容器是否正常启动;
  3. 初始化 SQL 是否执行成功;
  4. 后端连接地址是否写成了 mysql,而不是 localhost

在 Docker Compose 网络中,服务之间通过服务名访问,所以后端连接 MySQL 的地址应该是:

mysql

而不是:

127.0.0.1

3. 修改代码后不生效

如果你修改了前端或后端源码,需要重新构建镜像:

docker compose up -d --build

如果需要彻底清理旧容器和数据:

docker compose down
docker compose up -d --build

如果连 MySQL 数据也要删除:

docker compose down -v
docker compose up -d --build

注意:-v 会删除数据库卷,历史记录会丢失。


4. 端口冲突

如果本机已经占用了 808030003306,可以修改 docker-compose.yml 中左侧端口。

例如将前端端口改为 8090

ports:
  - "8090:80"

访问地址改为:

http://localhost:8090

十一、生产环境优化建议

上面的代码适合学习和原型验证。如果要用于企业生产环境,建议进一步优化。

1. 增加用户登录与权限控制

当前示例没有用户体系,任何访问页面的人都可以调用 AI 接口。生产环境中应增加:

  • 用户注册与登录;
  • JWT 鉴权;
  • 角色权限控制;
  • 管理员后台;
  • 调用次数限制。

2. 增加接口限流

AI 接口通常按 Token 计费,如果没有限流,容易出现滥用问题。可以使用:

  • Nginx 限流;
  • Redis 记录用户调用次数;
  • 后端中间件限流;
  • 按部门或用户设置额度。

3. 增加敏感词和数据脱敏

企业办公场景可能包含客户信息、合同信息、财务数据等敏感内容。建议在调用大模型前做数据脱敏,例如:

  • 手机号脱敏;
  • 邮箱脱敏;
  • 身份证号脱敏;
  • 客户名称替换;
  • 合同编号替换。

4. 接入知识库

如果希望 AI 回答企业内部制度、产品文档、技术手册等内容,可以扩展知识库模块:

  • 文件上传;
  • 文档切分;
  • 向量化;
  • 向量数据库检索;
  • RAG 增强生成。

常见向量数据库包括:

  • Milvus;
  • Qdrant;
  • Weaviate;
  • Elasticsearch;
  • pgvector。

5. 支持本地大模型

如果企业对数据安全要求较高,可以使用本地模型:

  • Qwen;
  • DeepSeek;
  • GLM;
  • Llama;
  • Baichuan;
  • Yi。

部署方式可以选择 Ollama、vLLM、LMDeploy 或 Text Generation Inference。只要服务提供 OpenAI 兼容接口,本文后端代码基本无需大改。


十二、项目扩展方向

这个 AI办公系统只是基础版本,你可以继续扩展为更完整的办公平台。

1. Word 文档处理

支持上传 Word 文档,然后自动生成:

  • 文档摘要;
  • 风险点;
  • 修改建议;
  • 汇报材料;
  • 领导版简报。

2. Excel 数据分析

支持上传 Excel 表格,让 AI 自动分析:

  • 销售趋势;
  • 异常数据;
  • 关键指标;
  • 可视化图表建议;
  • 经营分析结论。

3. PPT 大纲生成

输入主题后自动生成:

  • PPT 标题;
  • 页目录;
  • 每页核心内容;
  • 演讲稿;
  • 视觉风格建议。

4. 企业知识库问答

把公司制度、产品说明、技术文档、客服 FAQ 导入知识库,员工可以直接提问,例如:

公司年假制度是什么?
某产品的售后流程是什么?
服务器上线审批需要哪些材料?

AI 根据内部文档回答,而不是凭空生成。

5. 多模型切换

可以在后台增加模型配置功能,让用户选择不同模型:

  • 通用模型;
  • 代码模型;
  • 文档模型;
  • 本地私有模型;
  • 多模态模型。

十三、安全注意事项

部署 AI办公系统时,不要只关注功能,还要重视安全。

  1. 不要把 API Key 写进前端代码

    • 前端代码会暴露给浏览器。
    • API Key 必须放在后端环境变量中。
  2. 不要在公网直接暴露数据库端口

    • 示例中暴露了 3306 便于调试。
    • 生产环境建议删除 MySQL 的 ports 映射,只允许容器内部访问。
  3. 开启 HTTPS

    • 如果部署到公网,建议通过 Nginx、Caddy 或云厂商证书开启 HTTPS。
  4. 限制上传文件大小

    • 如果后续增加文件上传,应限制文件大小和类型。
  5. 记录调用日志

    • 保存调用用户、时间、消耗 Token、请求类型,便于审计和成本分析。

十四、完整部署命令汇总

如果你已经按照上文创建好全部文件,可以直接执行以下命令:

cd ai-office-docker

docker compose up -d --build

docker ps

访问:

http://localhost:8080

停止服务:

docker compose down

停止并删除数据库数据:

docker compose down -v

重新构建:

docker compose up -d --build

十五、总结

本文从零实现并部署了一个简易版 AI办公助手系统,包含前端 Vue 页面、后端 Express API、MySQL 数据库和 Docker Compose 一键编排。通过这个项目,你可以快速理解 AI办公类应用的基本架构:前端负责交互,后端负责封装大模型调用,数据库负责保存业务数据,Docker 负责统一部署和环境隔离。

这个项目虽然简单,但具备较好的扩展基础。你可以在此基础上继续加入用户系统、知识库问答、文件上传、Excel 分析、PPT 生成、多模型切换、企业权限管理等功能,逐步演进为真正适合企业内部使用的 AI办公平台。

对于个人开发者来说,它是一个很好的 AI 应用练手项目;对于企业技术团队来说,它也可以作为内部 AI 工具平台的原型。只要继续完善安全、权限、日志、成本控制和知识库能力,就能让 AI 真正融入日常办公流程,提高文档处理、沟通协作和信息整理效率。

目录结构
全文