[{"content":"PlotVault PDM 安装部署指南 本文档介绍如何部署 PlotVault PDM 后端服务。PlotVault 支持多种部署方式，推荐使用 Docker Compose 进行一键部署。\n前置要求 Docker 和 Docker Compose 至少 1GB 的磁盘空间 网络连接（用于拉取镜像） 方式 A：Docker Compose（推荐） 这是最简单的部署方式，只需几步即可完成。\n步骤 1：准备配置文件 从仓库复制 docker-compose.yml 文件到你的部署目录：\n1 2 git clone https://github.com/donniemarc/plotvault-PDM.git cd plotvault-PDM 步骤 2：配置环境变量 编辑 docker-compose.yml，替换所有 \u0026lt;...\u0026gt; 占位符：\n占位符 说明 示例值 \u0026lt;DOCKERHUB_USER\u0026gt; Docker Hub 用户名 donniemarc \u0026lt;数据库密码\u0026gt; PostgreSQL 数据库密码 your_secure_password \u0026lt;API_TOKEN\u0026gt; 客户端连接用的访问令牌 your_api_token \u0026lt;HOST_PORT\u0026gt; 对外端口 8642 \u0026lt;DATA_HOST_PATH\u0026gt; 图纸数据宿主目录 /home/user/plotvault/data \u0026lt;CONFIG_HOST_PATH\u0026gt; 软件缓存宿主目录 /home/user/plotvault/config \u0026lt;PGDATA_HOST_PATH\u0026gt; 数据库数据宿主目录 /home/user/plotvault/pgdata 步骤 3：启动服务 1 docker compose up -d 启动后将运行三个容器：\ndb - PostgreSQL 18（存储元数据） plotvault-pdm - 后端 API，端口 8642 converter（可选）- STEP/IGES 服务端转换，端口 8000 步骤 4：验证部署 1 curl http://\u0026lt;主机IP\u0026gt;:8642/api/health 预期输出：\n1 {\u0026#34;service\u0026#34;:\u0026#34;plotvault-pdm\u0026#34;,\u0026#34;status\u0026#34;:\u0026#34;ok\u0026#34;} 方式 B：构建镜像并推送 Docker Hub 适用于需要在远程主机部署的场景。\n步骤 1：构建镜像 在 Windows PC 上（需 Docker Desktop）：\n1 .\\build-push.ps1 按提示输入 Docker Hub 用户名。\n步骤 2：在远程主机部署 在目标主机上将 docker-compose.yml 的镜像指向 \u0026lt;你的用户名\u0026gt;/plotvault-pdm-server:latest，然后执行：\n1 docker compose up -d 方式 C：离线 tar 导入 适用于无外网环境。\n步骤 1：在 PC 上构建镜像 1 2 docker build -t plotvault-pdm-server ./server docker save plotvault-pdm-server | gzip \u0026gt; plotvault-pdm-server.tar.gz 步骤 2：传送到目标主机并加载 1 2 docker load \u0026lt; plotvault-pdm-server.tar.gz docker compose up -d 验证服务 部署完成后，可以通过以下方式验证服务是否正常运行：\n1 2 3 4 5 6 7 8 # 检查容器状态 docker compose ps # 查看日志 docker compose logs -f plotvault-pdm # 测试健康检查接口 curl http://localhost:8642/api/health 下一步 部署完成后，请参阅 使用说明 了解如何使用桌面客户端连接和管理图纸文件。\n常见问题 DWG 预览报错「dwg2dxf not available」？ 说明容器内没有 dwg2dxf（本机裸跑二进制时常见，Docker 镜像会从源码编译 libredwg）。请用 Docker 部署；转换只在首次预览时执行并缓存到 CONFIG_DIR/dxf_cache。\n如何备份？ 备份图纸拷贝 data/ 目录（library 真实目录 + blobs 归档）即可；建议一并备份 pgdata/ 卷（目录结构、版本备注等元数据，丢了不影响图纸文件本身）。\n数据库连不上？ 确认 compose 中 db 容器先启动且健康（pg_isready），DATABASE_URL 的用户/密码/库名与 POSTGRES_* 一致。\n","permalink":"https://625021125.xyz/docs/installation/","summary":"\u003ch1 id=\"plotvault-pdm-安装部署指南\"\u003ePlotVault PDM 安装部署指南\u003c/h1\u003e\n\u003cp\u003e本文档介绍如何部署 PlotVault PDM 后端服务。PlotVault 支持多种部署方式，推荐使用 Docker Compose 进行一键部署。\u003c/p\u003e\n\u003ch2 id=\"前置要求\"\u003e前置要求\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDocker 和 Docker Compose\u003c/li\u003e\n\u003cli\u003e至少 1GB 的磁盘空间\u003c/li\u003e\n\u003cli\u003e网络连接（用于拉取镜像）\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"方式-adocker-compose推荐\"\u003e方式 A：Docker Compose（推荐）\u003c/h2\u003e\n\u003cp\u003e这是最简单的部署方式，只需几步即可完成。\u003c/p\u003e\n\u003ch3 id=\"步骤-1准备配置文件\"\u003e步骤 1：准备配置文件\u003c/h3\u003e\n\u003cp\u003e从仓库复制 \u003ccode\u003edocker-compose.yml\u003c/code\u003e 文件到你的部署目录：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit clone https://github.com/donniemarc/plotvault-PDM.git\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd plotvault-PDM\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"步骤-2配置环境变量\"\u003e步骤 2：配置环境变量\u003c/h3\u003e\n\u003cp\u003e编辑 \u003ccode\u003edocker-compose.yml\u003c/code\u003e，替换所有 \u003ccode\u003e\u0026lt;...\u0026gt;\u003c/code\u003e 占位符：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e占位符\u003c/th\u003e\n          \u003cth\u003e说明\u003c/th\u003e\n          \u003cth\u003e示例值\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;DOCKERHUB_USER\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eDocker Hub 用户名\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003edonniemarc\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;数据库密码\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003ePostgreSQL 数据库密码\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003eyour_secure_password\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;API_TOKEN\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e客户端连接用的访问令牌\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003eyour_api_token\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;HOST_PORT\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e对外端口\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e8642\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;DATA_HOST_PATH\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e图纸数据宿主目录\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e/home/user/plotvault/data\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;CONFIG_HOST_PATH\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e软件缓存宿主目录\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e/home/user/plotvault/config\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003e\u0026lt;PGDATA_HOST_PATH\u0026gt;\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e数据库数据宿主目录\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e/home/user/plotvault/pgdata\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"步骤-3启动服务\"\u003e步骤 3：启动服务\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edocker compose up -d\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e启动后将运行三个容器：\u003c/p\u003e","title":"安装部署指南"},{"content":"PlotVault PDM 使用说明 本文档介绍如何使用 PlotVault PDM 桌面客户端来管理你的图纸文件。\n客户端安装 Windows 客户端构建 在一台 Windows PC 上构建一次即可（安装包可分发给其他机器）。\n前置要求：\nRust（MSVC 工具链 + Visual Studio Build Tools C++ 工作负载） Node.js 18+ WebView2 运行时（Win10/11 一般自带） 构建步骤：\n1 2 3 cd client npm install npm run tauri build 产物位于 client/src-tauri/target/release/bundle/。\n开发调试：\n1 2 cd client npm run tauri dev 首次连接 启动客户端 点击右上角 设置 按钮 填入服务器地址：http://\u0026lt;主机IP\u0026gt;:8642 填入 API Token（与服务端配置的 token 一致） 点击 测试连接 确认连接成功 点击 保存 基础操作 文件夹树 左侧显示文件夹树结构，点击文件夹可展开或收起子目录。\n文件列表 右侧显示当前文件夹中的文件列表，包括：\n文件名 文件大小 最后修改时间 版本号（如有多个版本） 文件操作 上传：点击右上角「上传」按钮，或直接把文件拖进窗口 下载：选中文件，点击「下载」按钮 删除：选中文件，点击「删除」按钮 重命名：选中文件，点击「重命名」按钮 移动：选中文件，点击「移动」按钮，选择目标文件夹 版本管理 PlotVault 的核心功能之一是版本管理。\n上传新版本 同目录同名文件上传会自动作为新版本。旧版本不会被删除，而是归档到版本历史中。\n查看版本历史 选中文件 点击「版本」按钮 查看所有版本列表 可以下载任意旧版本 上传新版本时可以附带备注 版本备注 每次上传新版本时，可以添加备注说明修改内容，方便日后查阅。\n文件预览 PlotVault 支持多种文件格式的在线预览：\n格式 预览方式 DWG/DXF Three.js 2D 渲染 STEP/IGES OpenCascade WASM 3D 渲染 STL Three.js 3D 渲染 PDF pdf.js 渲染 图片 内建图片查看器 文本 内建文本查看器 预览操作 缩放：鼠标滚轮 旋转（3D 文件）：鼠标左键拖拽 平移：鼠标右键拖拽 关闭预览：点击右上角关闭按钮 搜索功能 在文件列表上方的搜索框中输入关键词，可以快速查找文件。\n快捷键 快捷键 功能 Ctrl+U 上传文件 Ctrl+D 下载文件 Delete 删除文件 F2 重命名文件 Ctrl+F 搜索文件 下一步 了解更多配置选项，请参阅 配置说明。\n","permalink":"https://625021125.xyz/docs/usage/","summary":"\u003ch1 id=\"plotvault-pdm-使用说明\"\u003ePlotVault PDM 使用说明\u003c/h1\u003e\n\u003cp\u003e本文档介绍如何使用 PlotVault PDM 桌面客户端来管理你的图纸文件。\u003c/p\u003e\n\u003ch2 id=\"客户端安装\"\u003e客户端安装\u003c/h2\u003e\n\u003ch3 id=\"windows-客户端构建\"\u003eWindows 客户端构建\u003c/h3\u003e\n\u003cp\u003e在一台 Windows PC 上构建一次即可（安装包可分发给其他机器）。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e前置要求：\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eRust（MSVC 工具链 + Visual Studio Build Tools C++ 工作负载）\u003c/li\u003e\n\u003cli\u003eNode.js 18+\u003c/li\u003e\n\u003cli\u003eWebView2 运行时（Win10/11 一般自带）\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003e构建步骤：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e3\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd client\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enpm install\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enpm run tauri build\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e产物位于 \u003ccode\u003eclient/src-tauri/target/release/bundle/\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e开发调试：\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd client\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003enpm run tauri dev\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"首次连接\"\u003e首次连接\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e启动客户端\u003c/li\u003e\n\u003cli\u003e点击右上角 \u003cstrong\u003e设置\u003c/strong\u003e 按钮\u003c/li\u003e\n\u003cli\u003e填入服务器地址：\u003ccode\u003ehttp://\u0026lt;主机IP\u0026gt;:8642\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e填入 API Token（与服务端配置的 token 一致）\u003c/li\u003e\n\u003cli\u003e点击 \u003cstrong\u003e测试连接\u003c/strong\u003e 确认连接成功\u003c/li\u003e\n\u003cli\u003e点击 \u003cstrong\u003e保存\u003c/strong\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"基础操作\"\u003e基础操作\u003c/h2\u003e\n\u003ch3 id=\"文件夹树\"\u003e文件夹树\u003c/h3\u003e\n\u003cp\u003e左侧显示文件夹树结构，点击文件夹可展开或收起子目录。\u003c/p\u003e","title":"使用说明"},{"content":"PlotVault PDM 配置说明 本文档介绍 PlotVault PDM 的各项配置参数。\n环境变量 核心配置 变量名 默认值 说明 DATA_DIR /data 图纸数据目录（library 真实目录 + blobs 版本归档），主机上可直接浏览 CONFIG_DIR /config 软件缓存目录（dxf_cache + tmp） DATABASE_URL postgres://postgres:postgres@localhost:5432/plotvault_pdm PostgreSQL 连接串（compose 里指向 db 容器） BIND 0.0.0.0:8642 监听地址 API_TOKEN 空 设置后所有 API 需 Authorization: Bearer \u0026lt;token\u0026gt; 即使是局域网私有环境，也建议设置 API_TOKEN。\nDocker Compose 配置示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 version: \u0026#39;3.8\u0026#39; services: db: image: postgres:18 environment: POSTGRES_DB: plotvault_pdm POSTGRES_USER: postgres POSTGRES_PASSWORD: \u0026lt;数据库密码\u0026gt; volumes: - \u0026lt;PGDATA_HOST_PATH\u0026gt;:/var/lib/postgresql/data healthcheck: test: [\u0026#34;CMD-SHELL\u0026#34;, \u0026#34;pg_isready -U postgres\u0026#34;] interval: 5s timeout: 5s retries: 5 plotvault-pdm: image: \u0026lt;DOCKERHUB_USER\u0026gt;/plotvault-pdm-server:latest depends_on: db: condition: service_healthy ports: - \u0026#34;\u0026lt;HOST_PORT\u0026gt;:8642\u0026#34; environment: DATABASE_URL: postgres://postgres:\u0026lt;数据库密码\u0026gt;@db:5432/plotvault_pdm API_TOKEN: \u0026lt;API_TOKEN\u0026gt; DATA_DIR: /data CONFIG_DIR: /config BIND: 0.0.0.0:8642 volumes: - \u0026lt;DATA_HOST_PATH\u0026gt;:/data - \u0026lt;CONFIG_HOST_PATH\u0026gt;:/config converter: image: \u0026lt;DOCKERHUB_USER\u0026gt;/plotvault-pdm-converter:latest ports: - \u0026#34;8000:8000\u0026#34; 数据目录结构 DATA_DIR（图纸数据） data/ ├── library/ # 真实目录结构，与客户端看到的文件夹树一致 │ ├── 项目A/ │ │ ├── 零件1.step │ │ └── 零件1.step │ └── 项目B/ │ └── 图纸1.dwg └── blobs/ # 版本归档 ├── v1/ │ └── \u0026lt;hash\u0026gt; └── v2/ └── \u0026lt;hash\u0026gt; CONFIG_DIR（软件缓存） config/ ├── dxf_cache/ # DWG 转 DXF 的缓存 └── tmp/ # 临时文件 安全建议 1. 设置 API Token 即使在局域网环境，也建议设置 API Token：\n1 2 3 4 5 # 生成一个随机 token openssl rand -hex 32 # 将生成的 token 设置到环境变量 API_TOKEN=your_generated_token_here 2. 使用 HTTPS 如果暴露到公网，建议使用反向代理（如 Nginx）配置 HTTPS：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 server { listen 443 ssl; server_name plotvault.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://localhost:8642; 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; } } 3. 限制访问 可以通过防火墙规则限制只允许特定 IP 访问：\n1 2 3 # 只允许 192.168.1.0/24 网段访问 iptables -A INPUT -p tcp --dport 8642 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 8642 -j DROP 性能调优 PostgreSQL 优化 对于大量文件的场景，可以调整 PostgreSQL 配置：\n# postgresql.conf shared_buffers = 256MB effective_cache_size = 1GB work_mem = 16MB maintenance_work_mem = 128MB 文件存储优化 将 DATA_DIR 放在 SSD 上可以提高文件读写速度 使用 RAID 配置可以提高数据安全性 备份与恢复 备份 1 2 3 4 5 # 备份图纸数据 cp -r /path/to/data /backup/data # 备份数据库 docker exec -t db pg_dump -U postgres plotvault_pdm \u0026gt; /backup/plotvault_pdm.sql 恢复 1 2 3 4 5 # 恢复图纸数据 cp -r /backup/data /path/to/data # 恢复数据库 cat /backup/plotvault_pdm.sql | docker exec -i db psql -U postgres plotvault_pdm 清空重建 1 2 3 4 5 6 7 # 删除配置和数据库（保留图纸文件） rm -rf /path/to/config docker exec -t db dropdb -U postgres plotvault_pdm docker exec -t db createdb -U postgres plotvault_pdm # 连图纸一起清空 rm -rf /path/to/data ","permalink":"https://625021125.xyz/docs/configuration/","summary":"\u003ch1 id=\"plotvault-pdm-配置说明\"\u003ePlotVault PDM 配置说明\u003c/h1\u003e\n\u003cp\u003e本文档介绍 PlotVault PDM 的各项配置参数。\u003c/p\u003e\n\u003ch2 id=\"环境变量\"\u003e环境变量\u003c/h2\u003e\n\u003ch3 id=\"核心配置\"\u003e核心配置\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e变量名\u003c/th\u003e\n          \u003cth\u003e默认值\u003c/th\u003e\n          \u003cth\u003e说明\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eDATA_DIR\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e/data\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e图纸数据目录（library 真实目录 + blobs 版本归档），主机上可直接浏览\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eCONFIG_DIR\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e/config\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e软件缓存目录（dxf_cache + tmp）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eDATABASE_URL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003epostgres://postgres:postgres@localhost:5432/plotvault_pdm\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003ePostgreSQL 连接串（compose 里指向 \u003ccode\u003edb\u003c/code\u003e 容器）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eBIND\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003ccode\u003e0.0.0.0:8642\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e监听地址\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003ccode\u003eAPI_TOKEN\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003e空\u003c/td\u003e\n          \u003ctd\u003e设置后所有 API 需 \u003ccode\u003eAuthorization: Bearer \u0026lt;token\u0026gt;\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cblockquote\u003e\n\u003cp\u003e即使是局域网私有环境，也建议设置 \u003ccode\u003eAPI_TOKEN\u003c/code\u003e。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch3 id=\"docker-compose-配置示例\"\u003eDocker Compose 配置示例\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 2\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 3\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 4\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 5\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 6\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 7\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 8\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e 9\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e10\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e11\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e12\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e13\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e14\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e15\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e16\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e17\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e18\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e19\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e20\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e21\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e22\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e23\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e24\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e25\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e26\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e27\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e28\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e29\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e30\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e31\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e32\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e33\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e34\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e35\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e36\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e37\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e38\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eversion\u003c/span\u003e: \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;3.8\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003eservices\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003edb\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eimage\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003epostgres:18\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eenvironment\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003ePOSTGRES_DB\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eplotvault_pdm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003ePOSTGRES_USER\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003epostgres\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003ePOSTGRES_PASSWORD\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;数据库密码\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003evolumes\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      - \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;PGDATA_HOST_PATH\u0026gt;:/var/lib/postgresql/data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003ehealthcheck\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003etest\u003c/span\u003e: [\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;CMD-SHELL\u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;pg_isready -U postgres\u0026#34;\u003c/span\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003einterval\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e5s\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003etimeout\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e5s\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003eretries\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003eplotvault-pdm\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eimage\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;DOCKERHUB_USER\u0026gt;/plotvault-pdm-server:latest\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003edepends_on\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003edb\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        \u003cspan style=\"color:#f92672\"\u003econdition\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003eservice_healthy\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eports\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      - \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;\u0026lt;HOST_PORT\u0026gt;:8642\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eenvironment\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003eDATABASE_URL\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003epostgres://postgres:\u0026lt;数据库密码\u0026gt;@db:5432/plotvault_pdm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003eAPI_TOKEN\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;API_TOKEN\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003eDATA_DIR\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e/data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003eCONFIG_DIR\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e/config\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u003cspan style=\"color:#f92672\"\u003eBIND\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e0.0.0.0\u003c/span\u003e:\u003cspan style=\"color:#ae81ff\"\u003e8642\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003evolumes\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      - \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;DATA_HOST_PATH\u0026gt;:/data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      - \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;CONFIG_HOST_PATH\u0026gt;:/config\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#f92672\"\u003econverter\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eimage\u003c/span\u003e: \u003cspan style=\"color:#ae81ff\"\u003e\u0026lt;DOCKERHUB_USER\u0026gt;/plotvault-pdm-converter:latest\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    \u003cspan style=\"color:#f92672\"\u003eports\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      - \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;8000:8000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"数据目录结构\"\u003e数据目录结构\u003c/h2\u003e\n\u003ch3 id=\"data_dir图纸数据\"\u003eDATA_DIR（图纸数据）\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003edata/\n├── library/          # 真实目录结构，与客户端看到的文件夹树一致\n│   ├── 项目A/\n│   │   ├── 零件1.step\n│   │   └── 零件1.step\n│   └── 项目B/\n│       └── 图纸1.dwg\n└── blobs/            # 版本归档\n    ├── v1/\n    │   └── \u0026lt;hash\u0026gt;\n    └── v2/\n        └── \u0026lt;hash\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"config_dir软件缓存\"\u003eCONFIG_DIR（软件缓存）\u003c/h3\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003econfig/\n├── dxf_cache/        # DWG 转 DXF 的缓存\n└── tmp/              # 临时文件\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"安全建议\"\u003e安全建议\u003c/h2\u003e\n\u003ch3 id=\"1-设置-api-token\"\u003e1. 设置 API Token\u003c/h3\u003e\n\u003cp\u003e即使在局域网环境，也建议设置 API Token：\u003c/p\u003e","title":"配置说明"}]