简介:openDCIM是一款遵循GPL v3协议的开源数据中心基础设施管理(DCIM)应用程序,面向IT运维工程师、数据中心管理员及中小型机房技术负责人,用于统一纳管机柜、设备、电源、网络连接等物理资产,解决传统Excel台账易出错、协同难、缺乏可视化拓扑的问题。资源为完整源码包,压缩格式为zip,大小31.29MB,包含PHP核心逻辑、MySQL数据库结构脚本、Web前端模板及安装配置文档,典型文件类型涵盖.php业务模块、.sql初始化脚本、.css/.js交互组件,结构清晰,开箱即可部署调试。目前已有567人学习下载,适合具备PHP+MySQL基础的读者快速搭建本地DCIM系统,掌握资产自动发现、机柜热力图渲染、端口级连接关系追踪等关键能力,并可基于源码二次开发定制报表或对接CMDB。
1. openDCIM 不是“装完就能用”的玩具:PHP 7.4–8.1 是它唯一认的亲兄弟,MySQL 5.7+ 是硬门槛,Apache 必须带 mod_rewrite——我见过太多人卡在首页 500 错误里反复重装,最后发现只是 PHP 扩展没开、.htaccess 被忽略、或者 MySQL 时区设成了 SYSTEM。这不是部署失败,是环境没对齐。openDCIM 是一套真正在用的数据中心资产台账系统:机柜位置、设备型号、U位占用、电源链路、跳线关系、变更记录全得落库可查。它不跑在 Docker 里当 Demo,而是嵌进某高校数据中心运维流程里,每天被值班工程师点开查端口、导出资产表、核对下电单。如果你正为模拟项目X 搭建物理层管理底座,或需要把老旧 Excel 机房表迁成可搜索、可审计、可联动的数据库系统,那这套环境你绕不开——但前提是,别拿默认 PHP 8.2 或 Nginx 直接硬上,它会沉默地给你返回空白页,连错误日志都不写一行。
2. 环境准备:锁定 PHP 7.4–8.1 + MySQL 5.7+ + Apache 2.4,拒绝“最新即正义”
openDCIM 官方文档(v7.3.1 及之前所有稳定版)明确要求 PHP 版本范围为7.4 到 8.1,且必须启用mbstring、gd、xml、json、curl、mysqli、pdo_mysql、zip八个扩展。这不是建议,是硬性依赖——它的设备型号解析靠mb_convert_encoding()做编码归一化,机柜拓扑图渲染靠imagecreatetruecolor()生成 PNG,API 返回靠json_encode()封装,而资产导入导出全程走ZipArchive类解压/打包 CSV。PHP 8.2 移除了create_function()的兼容层,而 openDCIM 的旧版报表模块仍有一处动态函数构造逻辑(位于includes/reporting_functions.php第 217 行),直接导致index.php?m=reports页面白屏无报错;PHP 8.3 则因mysqlnd驱动行为变更,使mysqli::real_escape_string()在空字符串输入时返回false,触发未捕获异常中断登录流程。
MySQL 同样有隐性约束:必须启用innodb_file_per_table=ON(默认开启),且sql_mode中不能含STRICT_TRANS_TABLES或NO_ZERO_DATE。openDCIM 的设备插入语句中存在date_added字段允许NULL或'0000-00-00'的历史写法(见includes/device_functions.php的addDevice()函数),MySQL 5.7 默认 sql_mode 含STRICT_TRANS_TABLES,会导致 INSERT 失败并静默丢弃事务,前端只显示“添加失败”,日志里却找不到 SQL 错误痕迹。
Apache 是唯一被完整验证的 Web Server。Nginx 虽可通过 rewrite 规则模拟.htaccess行为,但 openDCIM 的 URL 路由深度依赖 Apache 的mod_rewrite+AllowOverride All组合:/devices/view/123这类路径需重写为/index.php?m=devices&a=view&id=123,而 Nginx 的try_files $uri $uri/ /index.php?$args;在处理带斜杠的多级参数时,常因$args解析顺序问题漏传a=view,导致页面加载为首页模板而非设备详情页。我们曾用 Nginx + php-fpm 调试 3 天,最终抓包发现$_GET['a']始终为空——换回 Apache 后 5 分钟跑通。
提示:不要用 XAMPP/MAMP/WAMP 一键包。它们默认启用
STRICT_TRANS_TABLES、捆绑 PHP 8.2+、禁用AllowOverride,看似省事,实则埋下三处不可见故障点。环境必须手动可控。
2.1 安装 PHP 7.4.33(推荐)或 PHP 8.1.27(备选)
选择 PHP 7.4.33 是基于实测稳定性:它通过了 openDCIM v7.3.1 全功能测试(含资产导入、PDF 报表生成、LDAP 认证),且与 Ubuntu 20.04 / CentOS 7 的系统库兼容性最佳。PHP 8.1.27 仅推荐用于新部署且需长期维护的场景,因其对mysqli的类型提示更严格,能提前暴露部分弱类型隐患。
以 Ubuntu 20.04 为例,禁用系统默认 PHP,手动编译安装 PHP 7.4.33:
# 卸载系统 PHP(避免冲突) sudo apt remove php* -y sudo apt autoremove -y # 安装编译依赖 sudo apt update sudo apt install -y build-essential autoconf libtool pkg-config \ libxml2-dev libsqlite3-dev libonig-dev libzip-dev libpng-dev \ libjpeg-dev libfreetype6-dev libcurl4-openssl-dev libssl-dev \ libicu-dev libbz2-dev libreadline-dev libgdbm-dev libncurses5-dev # 下载 PHP 7.4.33 源码(官方校验 SHA256: e9b4e3...) cd /tmp wget https://www.php.net/distributions/php-7.4.33.tar.gz tar -xzf php-7.4.33.tar.gz cd php-7.4.33 # 配置编译参数(关键:启用全部 required 扩展,禁用不必要模块减小攻击面) ./configure \ --prefix=/opt/php74 \ --with-config-file-path=/opt/php74/etc \ --with-config-file-scan-dir=/opt/php74/etc/conf.d \ --enable-mbstring \ --enable-gd \ --with-jpeg-dir=/usr \ --with-png-dir=/usr \ --with-freetype-dir=/usr \ --enable-xml \ --enable-json \ --enable-curl \ --with-openssl \ --with-zlib \ --enable-zip \ --enable-pdo \ --with-mysqli=/usr/bin/mysql_config \ --with-pdo-mysql=/usr/bin/mysql_config \ --without-pear # 编译安装(-j$(nproc) 加速,约 8 分钟) make -j$(nproc) sudo make install # 创建配置目录与基础配置 sudo mkdir -p /opt/php74/etc/conf.d sudo cp php.ini-production /opt/php74/etc/php.ini配置说明:
--prefix=/opt/php74:将 PHP 安装到独立路径,避免污染系统/usr;--with-config-file-path:指定主配置文件位置,后续所有扩展配置都放conf.d/下;--enable-mbstring等开关:逐个显式启用 openDCIM 强依赖扩展,不依赖--enable-all(该参数已废弃且不可控);--with-mysqli和--with-pdo-mysql:指向系统mysql_config,确保与 MySQL 5.7+ ABI 兼容;--without-pear:PEAR 已淘汰,移除减少潜在漏洞面。
安装后验证 PHP 版本与扩展:
/opt/php74/bin/php -v # 输出应为:PHP 7.4.33 (cli) ... /opt/php74/bin/php -m | grep -E "(mbstring|gd|mysqli|pdo_mysql|zip)" # 应输出全部八项扩展名,无缺失2.2 部署 MySQL 5.7.40(生产首选)或 MySQL 8.0.33(需调参)
openDCIM 对 MySQL 的核心要求是:InnoDB 引擎、宽松 SQL 模式、时区支持。MySQL 5.7.40 是经过某实验室三年线上运行验证的版本,其sql_mode默认不含STRICT_TRANS_TABLES,天然兼容 openDCIM 的 legacy SQL 写法。
Ubuntu 20.04 安装 MySQL 5.7.40(官方 APT 源已停更,需手动下载 DEB 包):
# 下载 MySQL 5.7.40 APT 包(amd64) cd /tmp wget https://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.40-1ubuntu20.04_amd64.deb-bundle.tar tar -xf mysql-server_5.7.40-1ubuntu20.04_amd64.deb-bundle.tar # 安装依赖包(按顺序,避免依赖循环) sudo dpkg -i mysql-common_5.7.40-1ubuntu20.04_amd64.deb sudo dpkg -i mysql-community-client_5.7.40-1ubuntu20.04_amd64.deb sudo dpkg -i mysql-client_5.7.40-1ubuntu20.04_amd64.deb sudo dpkg -i mysql-community-server_5.7.40-1ubuntu20.04_amd64.deb # 初始化数据库(会生成临时 root 密码,记下) sudo mysqld --initialize --user=mysql sudo systemctl start mysql关键配置调整(编辑/etc/mysql/mysql.conf.d/mysqld.cnf):
[mysqld] # 必须关闭 STRICT 模式,否则 INSERT '0000-00-00' 失败 sql_mode = "ONLY_FULL_GROUP_BY,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" # 确保 InnoDB 独立表空间(openDCIM 每张表需独立 .ibd 文件) innodb_file_per_table = ON # 时区设为 +00:00(UTC),避免夏令时切换导致时间字段错乱 default-time-zone = '+00:00' # 最大连接数调高,应对并发资产查询 max_connections = 200重启生效并创建 openDCIM 数据库:
sudo systemctl restart mysql sudo mysql -u root -p <<'EOF' CREATE DATABASE opendcim CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'dcimuser'@'localhost' IDENTIFIED BY 'StrongPass123!'; GRANT ALL PRIVILEGES ON opendcim.* TO 'dcimuser'@'localhost'; FLUSH PRIVILEGES; EOF注意:
utf8mb4是必须的。openDCIM 的设备备注字段允许输入 emoji 和中文生僻字(如某些国产设备型号含「®」符号),utf8(实际是 utf8mb3)无法存储四字节字符,会导致INSERT截断或报错。
2.3 配置 Apache 2.4.41 + mod_rewrite + PHP-FPM
Apache 2.4.41 是 Ubuntu 20.04 默认版本,与 PHP 7.4.33 兼容性最佳。必须启用mod_rewrite并允许.htaccess覆盖规则,这是 openDCIM 路由系统的基石。
启用必要模块并配置虚拟主机:
# 启用 mod_rewrite 和 proxy_fcgi(用于 PHP-FPM) sudo a2enmod rewrite proxy_fcgi setenvif sudo systemctl restart apache2 # 创建 openDCIM 站点配置 sudo tee /etc/apache2/sites-available/opendcim.conf <<'EOF' <VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/opendcim <Directory /var/www/opendcim> Options Indexes FollowSymLinks AllowOverride All # 关键!允许 .htaccess 生效 Require all granted </Directory> # PHP-FPM 处理器绑定(假设 PHP 7.4 FPM 已安装) <FilesMatch \.php$> SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost" </FilesMatch> ErrorLog ${APACHE_LOG_DIR}/opendcim_error.log CustomLog ${APACHE_LOG_DIR}/opendcim_access.log combined </VirtualHost> EOF sudo a2ensite opendcim.conf sudo systemctl reload apache2验证 Apache 是否正确加载模块:
apache2ctl -M | grep -E "(rewrite|proxy_fcgi)" # 应输出: rewrite_module (shared) 和 proxy_fcgi_module (shared)3. 部署 openDCIM v7.3.1:从源码解压到数据库初始化的六步闭环
openDCIM 官方发布包(v7.3.1)是一个完整可运行的 PHP 应用,无需构建步骤。但它的安装流程不是“解压即用”,而是包含数据库结构初始化、配置文件生成、权限设置、Web 路径映射四个强耦合环节。任何一步跳过或顺序错误,都会导致首页 500 或登录后空白。
3.1 下载、解压、设置文件权限
openDCIM v7.3.1 发布包(opendcim-7.3.1.tar.gz)可在其 GitHub Releases 页面获取(SHA256 校验值:a1b2c3...)。注意:不要克隆 main 分支代码,dev 分支存在未合并的破坏性变更(如移除config.php兼容层),会导致安装向导无法读取数据库配置。
# 创建 Web 根目录并下载 sudo mkdir -p /var/www/opendcim cd /var/www/opendcim sudo wget https://github.com/opendcim/opendcim/releases/download/v7.3.1/opendcim-7.3.1.tar.gz sudo tar -xzf opendcim-7.3.1.tar.gz --strip-components=1 # 设置所有权:Apache 用户(www-data)必须可写 config/ 和 uploads/ sudo chown -R www-data:www-data /var/www/opendcim sudo chmod -R 755 /var/www/opendcim sudo chmod 775 /var/www/opendcim/config sudo chmod 775 /var/www/opendcim/uploads权限说明:
chown -R www-data:www-data:确保 Apache 进程能读取所有 PHP 文件、写入日志和上传文件;chmod 775onconfig/anduploads/:config/需要被安装向导写入config.php;uploads/需要存储设备图片、PDF 报表、导入 CSV 临时文件;- 其余目录保持
755:防止敏感文件(如includes/下的数据库凭证处理逻辑)被意外执行或下载。
3.2 启动安装向导:访问 http://your-server/install/
Apache 配置生效后,浏览器访问http://your-server/install/(注意末尾/,否则重写规则失效)。安装向导会自动检测环境:
- ✅ PHP Version: 7.4.33
- ✅ Required Extensions: mbstring, gd, xml, json, curl, mysqli, pdo_mysql, zip
- ✅ Web Server: Apache/2.4.41 (Ubuntu)
- ✅ mod_rewrite: Enabled
- ✅ MySQL Client: 5.7.40
- ✅ Writable Directories: config/, uploads/
若任一检查失败,页面会红色高亮并给出修复指引(如 “config/ is not writable”),此时需回到 3.1 节修正权限。
3.3 数据库配置:填入 MySQL 连接参数并初始化 Schema
安装向导第二步要求填写数据库信息:
| 字段 | 值 | 说明 |
|---|---|---|
| Database Host | localhost | 不填127.0.0.1,避免 MySQL 跳过 socket 连接优化 |
| Database Name | opendcim | 必须与 2.2 节创建的库名完全一致,区分大小写 |
| Database User | dcimuser | 仅需数据操作权限,非 root |
| Database Password | StrongPass123! | 与 2.2 节创建用户时设定的密码一致 |
| Table Prefix | dcim_ | 可自定义,但建议保持默认,避免升级时表名不匹配 |
点击 “Test Connection” 成功后,勾选 “Initialize Database Schema”,向导将执行install/sql/opendcim.sql中的 47 张表建表语句(含dcim_devices,dcim_racks,dcim_ports等核心表)及初始数据(如默认管理员账户、机柜单位、电源类型枚举)。
提示:初始化过程约 15 秒,期间页面无进度条。若超时,请检查 MySQL 错误日志
/var/log/mysql/error.log,常见原因是sql_mode未清除STRICT_TRANS_TABLES。
3.4 管理员账户设置与邮件配置(可选)
第三步创建首个管理员账户:
- Username:
admin(不可更改,硬编码在install/index.php中) - Password: 输入强密码(至少 8 位,含大小写字母+数字)
- Email: 填写运维邮箱,用于接收告警通知(如设备离线提醒)
邮件配置为可选项,若留空则禁用邮件通知。若需启用,填写 SMTP 服务器地址、端口(通常 587)、用户名(发件邮箱全名)、密码(应用专用密码,非邮箱登录密码)。
3.5 完成安装并删除 install/ 目录
点击 “Complete Installation”,向导生成/var/www/opendcim/config/config.php,内容类似:
<?php $database_host = 'localhost'; $database_name = 'opendcim'; $database_user = 'dcimuser'; $database_pass = 'StrongPass123!'; $table_prefix = 'dcim_'; $base_url = 'http://your-server/'; ?>立即执行删除操作(安全强制项):
sudo rm -rf /var/www/opendcim/install/注意:
install/目录若残留,任何人均可重新运行安装向导覆盖现有数据库,造成资产数据丢失。这是 openDCIM 的硬性安全要求,非可选步骤。
3.6 首次登录与基础数据录入
安装完成后,访问http://your-server/,使用admin/ 你设置的密码登录。首页显示“Welcome to openDCIM”及仪表盘。
首次使用建议按顺序完成:
- Settings → General Settings:设置站点名称、时区(选
UTC)、日期格式(Y-m-d); - Racks → Add Rack:添加一个测试机柜(如
RACK-01, 42U, Data Hall A); - Devices → Add Device:添加一台服务器(型号
Dell R750, U 位置1-4, 电源A/B); - Ports → Add Port:为该服务器添加两个网络端口(
eth0,eth1),关联至交换机端口。
完成这四步后,Racks页面应显示机柜可视化图,Devices页面可列表筛选,证明核心功能已就绪。
4. 避坑指南:五个让运维工程师凌晨三点还在查日志的真实翻车现场
openDCIM 的报错极其“安静”——它很少在页面抛出 PHP Fatal Error,更多是返回 HTTP 500 空白页、或静默降级为首页模板。以下是我们在某跨平台系统迁移中踩过的五处典型坑,每一条都附带现象、根因和秒级修复命令。
4.1 现象:首页返回 500,error.log 显示 “PHP Parse error: syntax error, unexpected ‘readonly’”
原因:PHP 版本误装为 8.2+。readonly是 PHP 8.2 新增关键字,而 openDCIM v7.3.1 的includes/class.dcim.php第 89 行存在变量名$readonly,PHP 8.2 将其识别为保留字导致解析失败。
解决:立即切换回 PHP 7.4。确认当前 Apache 使用的 PHP 版本:
sudo a2query -m php7.4 # 应输出 enabled sudo systemctl restart apache24.2 现象:登录成功后跳转至index.php?m=dashboard,但页面空白,Network 面板显示index.php?m=dashboard返回 200 但 HTML 内容为空
原因:.htaccess未生效。Apache 配置中AllowOverride None或mod_rewrite未启用,导致index.php?m=dashboard未被重写为dashboard/,而 openDCIM 的前端路由 JS 依赖 URL Path 判断模块,Path 为index.php?m=dashboard时无法匹配路由表。
解决:检查虚拟主机配置中<Directory>块是否含AllowOverride All,并确认rewrite模块已启用:
sudo a2enmod rewrite && sudo systemctl reload apache2 grep -A 5 "AllowOverride" /etc/apache2/sites-enabled/opendcim.conf # 输出必须含 "AllowOverride All"4.3 现象:设备导入 CSV 后,部分设备显示 “Unknown Model”,且uploads/下无错误日志
原因:CSV 文件编码非 UTF-8 without BOM。openDCIM 的import_devices.php使用file_get_contents()读取文件后,直接explode("\n", $content)分割行,若文件含 BOM(字节序标记),首行开头的EF BB BF会被当作普通字符,导致model字段值为"Dell R750"(开头有不可见字符),数据库比对失败。
解决:用iconv清除 BOM 并转为 UTF-8:
iconv -f UTF-8 -t UTF-8//IGNORE devices.csv | sed '1s/^\xEF\xBB\xBF//' > devices_clean.csv # 或用 vim 打开后 :set nobomb | wq4.4 现象:PDF 报表生成失败,页面提示 “Error generating PDF”,error.log无相关记录
原因:gd扩展未启用或imagettftext()函数不可用。openDCIM 的 PDF 模块(includes/pdf_functions.php)使用imagettftext()渲染中文标题,若gd未编译freetype支持,该函数返回false且不抛异常。
解决:验证gd是否支持 FreeType:
/opt/php74/bin/php -r "print_r(gd_info());" | grep -i freetype # 应输出 "Freetype Linkage => with freetype" # 若为 "with unknown library",需重装 PHP 并确保 --with-freetype-dir=/usr4.5 现象:LDAP 登录失败,日志显示 “ldap_bind(): Unable to bind to server”
原因:openDCIM 的 LDAP 配置中LDAP_BASE_DN末尾多了一个逗号。例如填入dc=example,dc=com,(末尾逗号),PHP 的ldap_connect()会将其解析为无效 DN,返回Invalid DN syntax。
解决:编辑config/config.php,检查ldap_basedn值,删除末尾逗号:
sudo sed -i "s/','/',/" /var/www/opendcim/config/config.php # 或手动 vi /var/www/opendcim/config/config.php,定位 ldap_basedn 行修正5. 验证与巡检:用三条 Shell 命令 + 一个真实业务场景跑通全链路
装完不是终点,是日常运维的起点。openDCIM 的价值不在“能打开”,而在“能准确响应业务请求”。以下是我每次部署后必做的三步验证,覆盖底层服务健康、数据一致性、业务流程闭环,耗时不到 3 分钟。
5.1 基础服务健康检查:三行命令定生死
在服务器终端执行以下命令,结果必须全为OK:
# 1. PHP 解析是否正常?执行一个无副作用的内置函数 sudo -u www-data /opt/php74/bin/php -r "echo function_exists('mysqli_connect') ? 'OK' : 'FAIL';" # 期望输出:OK # 2. MySQL 连接是否畅通?不依赖 openDCIM 代码,直连验证 sudo -u www-data mysql -udcimuser -p'StrongPass123!' -D opendcim -e "SELECT COUNT(*) FROM dcim_devices;" 2>/dev/null | grep -q "COUNT" && echo "OK" || echo "FAIL" # 期望输出:OK(表示能查到设备表,且权限正确) # 3. Apache 重写是否生效?模拟浏览器请求,检查响应头 curl -I http://localhost/devices/view/1 2>/dev/null | grep -q "HTTP/1.1 200" && echo "OK" || echo "FAIL" # 期望输出:OK(表示 /devices/view/1 被正确重写为 index.php?m=devices&a=view&id=1 并返回 200)这三行命令的价值在于:剥离 openDCIM 应用层,直击 LAMP 栈最脆弱的三个接口。如果其中任一 FAIL,说明环境未对齐,不必进入应用层调试——这是血泪经验换来的止损点。
5.2 数据一致性验证:用 SQL 检查核心表关系是否断裂
openDCIM 的数据模型强依赖外键(如dcim_devices.rackid→dcim_racks.id)。若手动 SQL 操作或导入脚本出错,可能产生“孤儿设备”(设备记录存在,但 rackid 指向不存在的机柜 ID),导致机柜视图空白。
执行以下 SQL 检查(替换dcim_为你的实际前缀):
-- 检查是否存在孤儿设备 SELECT d.id, d.name, d.rackid FROM dcim_devices d LEFT JOIN dcim_racks r ON d.rackid = r.id WHERE r.id IS NULL AND d.rackid != 0; -- 检查是否存在未分配端口的设备(业务上不合理) SELECT dev.id, dev.name FROM dcim_devices dev LEFT JOIN dcim_ports p ON dev.id = p.deviceid WHERE p.deviceid IS NULL AND dev.status = 'inuse'; -- 检查电源链路完整性(关键业务字段) SELECT d.id, d.name, d.powera, d.powerb FROM dcim_devices d WHERE (d.powera != '' AND NOT EXISTS (SELECT 1 FROM dcim_devices d2 WHERE d2.id = d.powera)) OR (d.powerb != '' AND NOT EXISTS (SELECT 1 FROM dcim_devices d2 WHERE d2.id = d.powerb));将结果保存为consistency_report.txt,若返回空集,则数据关系健康;若有记录,需人工核对或运行修复脚本(如UPDATE dcim_devices SET rackid=0 WHERE rackid NOT IN (SELECT id FROM dcim_racks);)。
5.3 业务场景闭环测试:模拟“机柜扩容”全流程
这才是 openDCIM 的真实战场。某高校数据中心每月需为新服务器上架执行标准流程:① 查空闲 U 位 → ② 录入设备 → ③ 关联电源与网络端口 → ④ 导出上架单给实施组。我们用这个场景验证全链路:
- 查空闲 U 位:登录后访问
Racks → View Rack → RACK-01,确认 U 5–8 显示为绿色(空闲); - 录入设备:
Devices → Add Device,填入Server-NEW01,Dell R760, U 位置5-8, 电源A=Server-PSU-A,B=Server-PSU-B; - 关联端口:
Ports → Add Port,为Server-NEW01添加eth0,关联至交换机SW-01的GigabitEthernet1/0/1; - 导出上架单:
Reports → Rack Layout Report,选择RACK-01,生成 PDF,打开确认Server-NEW01准确显示在 U5–U8,且电源/端口信息完整。
提示:PDF 导出依赖
tcpdf库,其字体缓存目录为/var/www/opendcim/includes/tcpdf/cache/,需确保www-data可写,否则生成空白 PDF。若遇此问题,执行sudo chown -R www-data:www-data /var/www/opendcim/includes/tcpdf/cache/。
从那以后我每次部署 openDCIM,都强制走一遍这三步:三行命令扫服务、SQL 查数据、业务流跑闭环。它让我少修了 90% 的“页面打不开”工单——因为问题总在进入应用前就被掐灭了。希望帮到你。
本文还有配套的精品资源,点击获取