之前有个现场需求客户要求在一面大屏上实时展示车间设备状态不仅办公室要看产线旁边还得摆几台平板随时点按操作。传统思路是上组态软件可授权费不便宜、Windows 部署也重还得绑定固定的显示终端。后来我在这类项目里改用 FUXA 这个开源 Web SCADA/HMI 组态平台配合 Docker 部署从拉镜像到出第一个可视化画面基本二十分钟就能干完。这篇文章就记录我实际部署、接线、做画面的完整过程以及那些文档里不会写清楚的坑。FUXA 对我这种经常要快速交付监控界面的场景来说价值很直接它把传统组态软件里的“数据采集”和“画面组态”搬到了浏览器里服务器端负责采集设备数据前端负责拖拽式画面设计。而且官方提供 Docker 镜像部署环节被大幅压缩。你不需要在自己的电脑上装 Node.js 环境也不用折腾 npm 依赖一条 docker run 就能把整个平台跑起来。这篇文章适合三类人一是刚接触 SCADA/HMI想找个免费好上手的平台练手的工控工程师二是前端或全栈开发需要在短时间内部署一个可视化的数据监控后台三是做设备配套项目的朋友要给客户交付一套能远程看、能分组管理的监控系统。1. 先认清 FUXA 是什么以及为什么这套组合值得用1.1 一句话理解 FUXA浏览器里的组态软件组态软件这个词老工控人都熟悉像 WinCC、组态王、iFIX 都是这一类干的事就是连接设备数据、画监控画面、做报警记录。FUXA 做的事情基本一致但它把整个系统做成 B/S 架构也就是服务器端 浏览器端。你在服务器上跑一个 FUXA 服务任何一台能上网的电脑或平板打开浏览器输入地址就能看到监控画面不需要额外安装客户端不需要授权加密狗更不需要装一堆运行库。FUXA 本身用 Node.js 和 Angular 开发开源协议是 MIT这意味着你拿它做商业项目、二次开发都没有授权成本。对项目型公司来说这点很关键方案里省去一笔不小的组态软件授权费投标和交付的压力都会小很多。技术上它原生支持的设备协议也不少Modbus RTU/TCP、OPC UA、Siemens S7、BACnet 等基本覆盖了常见的 PLC、仪表和楼宇设备。更实用的是它自带一个可视化的画面编辑器可以直接在网页上拖控件、画管线、搭工艺图不用写一行前端代码。我自己的理解是FUXA 比较像把“组态软件”和“Web 前端框架”揉在了一起但它做得足够轻我拉起来跑一个几百点的小项目内存占用也就一百多兆比开一个虚拟机装 Windows 再跑组态软件轻太多。1.2 用 Docker 跑 FUXA解决的是环境问题和交付问题直接跑 FUXA 也不是不行官方文档也给了 npm 启动的方式但我强烈推荐用 Docker原因不是装腔而是环境太烦了。FUXA 依赖 Node.js而且对版本有要求我曾经在一台 Ubuntu 服务器上为了装 FUXA先折腾 Node 版本切换又遇到 npm 安装编译慢最后还在 Python 版本的坑里耗了半天。用 Docker 之后这些全没了镜像把 Node 运行时、依赖包、应用代码全部打包好拉下来只管跑。另一个我觉得很值的地方是交付。给客户部署系统的时候我只要把 docker-compose.yml 文件和一个数据目录复制过去执行一句 docker compose up -d系统就起来了。即便客户要换服务器迁移成本也极低把数据目录一打包到新机器上再跑一次命令就完成迁移。相比之下传统组态软件迁移要考虑授权重新激活、运行库版本、数据库驱动能折腾一整天。升级和回滚也方便。FUXA 官方镜像有版本标签我固定某个版本跑等确认新版本功能没问题后只需拉新镜像重建容器。万一升级出问题还能用旧镜像秒回滚。这一步在传统组态系统里几乎没有这么干净的方案。1.3 适合哪些场景哪些场景不适合硬上用了一段时间后我总结 FUXA 适合的场景和不太适合的场景方便大家判断。适合的场景不适合的场景中小规模的数据采集监控几十到几百个数据点要求高可用、冗余架构的大型 SCADA 系统设备配套的可视化大屏、状态看板对亚秒级实时性有苛刻要求的控制场景快速原型验证、教学演示、实验室监控需要复杂批次管理、高级报表引擎的场景给客户做一套可远程访问的轻量监控界面涉及关键工艺安全联锁的控制系统需要跨平台访问手机平板都要看的情况和西门子 WinCC 深度耦合、大量使用脚本的存量系统注意FUXA 再怎么说也是个开源项目别指望它能直接替代大型工业 SCADA。如果你的项目涉及安全联锁、核心工艺闭环控制该上专业控制系统还得上。FUXA 更适合做“看得见、管得着”的监控展示层数据采集走它没问题但控制功能要谨慎我一般只让它写少量非关键设定值关键操作还是留给 PLC 逻辑和正牌 HMI。2. 部署前的准备镜像、端口、数据卷三件事先想清楚2.1 官方镜像与版本选择FUXA 官方镜像在 Docker Hub 上名字是fuxa/fuxa直接docker pull fuxa/fuxa就能拉。不过这里有个经验别直接用latest标签因为latest的更新不受控你昨天跑得好好的今天重新拉一次镜像可能就变成新版本了新版本的行为变化可能让你的画面配置突然出问题。我习惯在确认某个版本能正常满足需求后就把镜像 tag 固定下来比如fuxa/fuxa:2.0.5这种形式具体 tag 以 Docker Hub 上实际存在的为准。如果你对版本不敏感刚开始只是想体验一下那用latest也没问题。但一旦进入正式项目建议把版本固定并且把 tag 写进 docker-compose 文件里这样每次部署都确定回滚也有明确目标。另外提一句Windows 环境下建议先装 Docker DesktopMac 和 Linux 则直接用各自的 Docker Engine 就行。安装好之后先确认docker version能正常输出再继续后面的步骤。2.2 端口、数据卷、时区这三个参数背后的逻辑部署 FUXA 需要关心的核心配置项就三个端口、数据卷、时区。先说端口。FUXA 容器内部的默认 Web 服务端口是 1881启动时要把宿主机的某个端口映射到容器的 1881。映射哪个端口由你决定想用 80 端口直接访问就写-p 80:1881但要注意宿主机 80 端口可能被 Nginx 或其他 Web 服务占用。我一般保留 1881 作为内网直接访问的端口对外统一用 Nginx 反代。然后是数据卷这个最关键。FUXA 的系统配置、项目文件、SQLite 数据库、报警记录、仪表盘配置统统写在容器内的/data目录。如果不做数据卷映射容器一旦被删除重建你之前画的画面、建的设备、配的标签全都没了。这是新手最容易踩的坑很多人调试了半天最后因为重建容器导致所有配置归零心态直接崩。所以必须把/data挂载出来可以用具名数据卷也可以直接挂到宿主机某个目录比如./fuxa-data:/data。我个人倾向于挂宿主机目录因为备份只需要拷贝一个文件夹。最后是时区。FUXA 容器默认可能使用 UTC 时区如果你不设置TZ环境变量历史趋势和时间戳会显示成标准时间和北京时间差 8 小时。表面看没什么等你真要排查报警时间或者做报表统计就会发现所有时间都对不上。所以启动时环境变量TZAsia/Shanghai建议直接带上。2.3 docker run 与 docker-compose 两种落地方式为了让大家直接抄作业我给两份配置。先是最简单的 docker run 方式docker pull fuxa/fuxa docker run -d --name fuxa \ -p 1881:1881 \ -v ./fuxa-data:/data \ -e TZAsia/Shanghai \ --restart unless-stopped \ fuxa/fuxa解释一下每个参数的作用-d表示后台运行--name fuxa给容器起名-p 1881:1881映射端口-v ./fuxa-data:/data把当前目录下的 fuxa-data 目录挂载成容器里的数据目录-e TZAsia/Shanghai设置时区--restart unless-stopped让容器在服务器重启后自动拉起。这里./fuxa-data是相对路径建议改成绝对路径避免以后在别的目录执行命令找不到挂载点。我个人更推荐 docker-compose 方式因为可读性和可维护性更好。创建一个项目目录比如/opt/fuxa在里面放一个docker-compose.ymlversion: 3.8 services: fuxa: image: fuxa/fuxa:2.0.5 container_name: fuxa ports: - 1881:1881 environment: - TZAsia/Shanghai volumes: - /opt/fuxa/data:/data restart: unless-stopped然后在/opt/fuxa目录下执行docker compose up -d服务就起来了。后续查看日志用docker compose logs -f fuxa停止用docker compose down。这种方式的另一个好处是整个部署配置就是一个文本文件放在项目里跟代码一起管理后面给客户移植环境也省事。如果你在拉镜像时遇到下载慢的问题可以去配置一下 Docker 镜像加速器。Linux 上编辑/etc/docker/daemon.json加上registry-mirrors配置然后重启 Docker 服务。这是国内网络环境下比较常见的优化手段注意配置完要确认 docker info 里能看到你设置的镜像加速地址。3. 启动 FUXA 并完成首个可视化页面3.1 启动、登录与初始化配置容器起来之后浏览器访问http://服务器IP:1881就能看到 FUXA 的登录界面。首次访问时系统会引导你创建管理员账号新版本基本都会要求设置用户名和密码建议一开始就用一个强密码。老版本里可能存在默认的 admin/admin如果你用的版本还能用默认账号登录登录后第一件事就是改掉密码。登录成功后看到的就是 FUXA 的主界面左侧是主导航区包含 Projects项目管理、Data Tags数据标签、Devices设备、Alarms报警等模块中间和右侧是内容展示区。第一次进来可能有点空但界面结构不难理解。我建议步骤是先建一个 Project相当于一个独立的应用空间然后在 Project 下创建设备和数据标签最后在 Dashboard 或者画布上开始设计画面。FUXA 的整体概念可以类比成传统组态软件里的“工程管理”Project 就是工程Devices 就是下面挂的 PLC 或仪表Data Tags 是这些设备的寄存器点位Dashboard 就是画面。搞清楚这个对应关系后面操作就顺了。3.2 连接第一个数据源Modbus TCP 从零配置我第一次部署 FUXA 时最想干的事就是赶紧接一台真实的 Modbus 设备看看数据能不能读到。这里以最常见、最容易测试的 Modbus TCP 为例把配置流程走一遍。先准备一个支持 Modbus TCP 的设备或者用模拟器替代确认 IP 能 ping 通端口 502 能访问。进入 FUXA 的设备管理界面点新增设备选择协议类型为 Modbus TCP填上设备的 IP 地址。端口默认 502 一般不用改然后设置轮询间隔Polling Time我通常设 500ms如果设备数量多、通信压力大会放宽到 1000ms。轮询时间设置这里有个权衡太短会加重设备通信负担太长页面数据刷新不够及时。一般监控类应用 500ms 到 1000ms 足够。设备创建好之后在设备下面添加数据标签Tag。这里需要明白一个关键点FUXA 的 Tag 就是你要采集的具体数据点每个 Tag 要指定寄存器类型、地址、数据类型等信息。以 Modbus 保持寄存器为例填写时需要把寄存器起始地址搞清楚。很多设备手册上写的地址是 40001、40002 这种偏置后的“协议地址”但 FUXA 里填的地址是从 0 开始的 Modbus 地址。也就是说手册里的 40001 对应 FUXA 里的地址 040002 对应地址 1这个偏移量是新手最容易搞错的地方。还有数据类型的选择。默认情况下可能按 16 位整数处理但如果你读的是压力、温度这种带小数的模拟量设备端多半是 32 位浮点数占用两个连续寄存器。这时候不仅要把数据类型选成 Float还要注意字节顺序。字节序错了读出来的数值会是天文数字或者完全不对这个问题我在后面常见问题里专门展开。配置好 Tag 之后回到项目界面给 Project 添加这些 Tag。注意数据标签添加到设备下还不够工程里要用到的点位需要把它们关联到 Project 下画面绑定数据的时候才能搜到。3.3 画面编辑器的核心操作拖控件、绑数据、做交互数据通了之后接下来就是画监控画面。FUXA 的画面编辑器是我觉得它做得最接近传统组态软件的地方。新建一个页面或者 Dashboard 后从右侧控件库拖拽图形到画布上可以用线条画管道、用矩形画设备、用文本做标注整个操作跟画图软件差不多。控件的属性面板可以设置外观、位置、尺寸最关键的是数据绑定Data Binding。选中一个控件点击绑定按钮搜索你要绑定的 Tag确认后这个控件就会实时显示对应数据点的值。如果你要画一个电机状态拖两个圆和一段文字把颜色变化绑定到电机运行的布尔量 Tag 上运行状态和停止状态用不同颜色区分这样画面动态效果就出来了。我习惯把整个画面分成几个区域设备状态区用指示灯和颜色块趋势区放历史曲线图操作区放按钮和输入控件。趋势图控件绑定对应 Tag 后能直接看到最近时间段的数据曲线这在现场调试时非常好用。交互操作方面按钮可以配置点击事件比如点击按钮往某个保持寄存器写一个数值。这里的坑点是你要明白 FUXA 写值默认是针对 Tag 的写操作如果设备的寄存器是只读的写入就会失败。遇到“按钮点了没反应”的情况先别怀疑控件先去设备管理页面看这个 Tag 当前有没有显示 Connected再看设备侧寄存器是否允许写入。关于热词里有人提到的 FUXA 中 Select Value 控件的使用我实际用下来场景比较多的是设定值切换和配方选择。拖一个 Select Value 控件在属性里配置选项列表比如“低速、高速、自动”三个选项每个选项对应一个要写入的值然后把它绑定到要写值的 Tag 上。操作员在下拉列表里选择一项FUXA 就把对应值写入该 Tag。启用这个控件前一定确认目标寄存器支持写入否则选了也没反应。4. 生产环境化反向代理、认证与数据备份4.1 用 Nginx 反代并支持 WebSocketFUXA 在局域网里直接用 IP 加端口访问没问题但如果要把系统暴露到公网或者想统一入口管理多个 Web 服务就需要在前面加一层 Nginx 反向代理。这里有个技术重点FUXA 的实时数据推送用了 WebSocket 技术反代配置必须支持 WebSocket 升级否则页面能打开但数据不会实时刷新。我用的 Nginx 配置大致是这样server { listen 80; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:1881; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_read_timeout 3600s; } }关键就是Upgrade和Connection这两个头不能丢。proxy_read_timeout我设置得比较长因为 FUXA 的 WebSocket 长连接如果超时断开页面上的数据就会停止刷新又要自动重连。如果你发现反代之后数据不更新八成是 WebSocket 没代理对回到配置里检查这两个头。如果对外使用 HTTPS我通常会顺手配一下证书用标准的 certbot 申请证书和自动续期。FUXA 本身不强制 HTTPS但只要系统出了内网强烈建议把 HTTPS 打开否则用户名密码和设备数据全部明文传输风险很大。4.2 用户权限与远程访问安全FUXA 自带用户管理功能支持 Admin、Engineer、Operator 等角色。默认角色权限差别在于Admin 能管理一切Engineer 通常可以改配置和画面Operator 基本只能看图操作。生产环境里我建议给现场操作人员分配最低权限的账号不要让他们拿到管理员权限。这样即便操作工误操作也只是修改了运行数据不至于把整个工程的配置改坏。远程访问的安全除了账号密码我还建议在网络层做限制。如果系统只给内部使用可以在防火墙或者安全组里只放开办公室网段的 IP如果一定要公网访问配合反向代理加 IP 白名单或者在前面加一层 Basic Auth。注意任何暴露在公网的管理后台默认账号密码不改就是给自己埋雷。FUXA 部署完管理员密码必须改且不要和别的平台共用密码。另外如果你把 1881 端口直接映射到公网而且没加任何反代和认证保护那就等于把生产监控系统赤裸裸暴露在互联网上这属于安全底线问题千万别犯。4.3 数据备份与容器升级FUXA 的所有配置和运行数据都在/data目录里所以备份这件事就变得特别简单拷贝这个目录即可。但直接拷贝运行中的 SQLite 数据库可能得到不一致的结果我建议备份前先停掉容器或者用 docker 命令把目录复制出来。例如docker exec fuxa tar czf /tmp/fuxa-backup.tar.gz /data docker cp fuxa:/tmp/fuxa-backup.tar.gz ./ docker exec fuxa rm -f /tmp/fuxa-backup.tar.gz这是在线备份的一种方式能保证文件处于静止状态。更稳妥的办法是每天晚上用 crontab 执行自动备份备份文件保留最近七天。升级容器的步骤也很简单先备份当前数据目录然后拉取新版本镜像用新的 tag 更新 docker-compose 文件再执行docker compose up -d重建容器。重启后登录系统检查几个关键画面和设备连接情况确认没问题再把旧镜像清理掉。如果出现问题想回滚把之前固定的镜像 tag 改回去重新 up 一次即可。整个升级过程最快几分钟完成这比传统组态系统的升级体验好太多了。5. 常见问题排查与技术细节实录5.1 配置保存丢失、设备连不上的几个经典场景用 Docker 部署 FUXA 后大部分问题都集中在配置持久化和设备通信上。我这里把实际遇到过的高频问题整理成一张速查表方便大家对应排查。现象大概率原因解决方法容器重建后配置全部丢失没有挂载/data数据卷重新创建容器用-v或 compose 挂载宿主机目录容器启动失败端口冲突1881 被占用换一个宿主机端口映射如-p 1882:1881设备状态一直离线防火墙挡了 502 端口宿主机和目标的中间网络放行 Modbus TCP 502页面能打开但设备数据不刷新反代没有转发 WebSocket检查 Nginx 的 Upgrade 和 Connection 头数据读取的是乱码或超大数值字节序、寄存器类型、数据类型配置错误根据设备手册核对 Tag 类型和字节顺序这里面设备连不上是最常见的。如果是 Modbus TCP先做两层检查宿主机上用工具测试到设备 502 端口的联通性再用 Modbus 测试客户端读一次寄存器看返回是否正常。如果外部工具能读到FUXA 却读不到多半是 Tag 配置里的地址或协议参数不对。如果是西门子 S7 系列FUXA 用 S7 协议连接时还要填对的机架号Rack和槽号Slot。很多 S7-1200/1500 PLC 默认设置是 Rack 0、Slot 1 或 Slot 2但这些值在不同 CPU 上可能不同配置前最好用官方工具确认一下。5.2 数据读写不对多半是地址、字节序和类型的问题读到的数值完全不对这是数据采集里最让人头大的问题。我举一个实际例子来拆解。假设设备 Registers 里存放了一个 32 位浮点数两个寄存器的值分别是 0x42F6 和 0xE666按 IEEE 754 换算应该是 123.4。如果 FUXA 按 16 位整数读你会得到两个没意义的整数如果把 32 位 Float 的字节顺序配错比如寄存器的顺序反了读出来的浮点数可能是几亿。所以遇到数据不对第一步先确认数据类型选对没有第二步再考虑字节序。Modbus 的字节序问题可以这样理解32 位数据在多个寄存器里存放存在两种常见的排列方式一种是高 16 位在前、低 16 位在后另一种是反过来。FUXA 里一般有对应的选项比如 Big Endian、Little Endian、Swapped Word 等。如果你发现读出来的浮点数量级完全不对就去切换这些字节序选项通常试一次就能测出来。调试技巧是现场用一个已知的恒定值来对比比如把压力变送器抬到大气压读到的值应当为 0 或 1 个标准大气压如果完全对不上就去改字节序。还有一个容易忽略的点是缩放因子。很多仪表实际值寄存器原始值 × 0.1 或 × 0.01即设备端把小数放大后存在寄存器里。FUXA 的 Tag 配置里支持设置缩放系数Scale你可以在标签里配置“缩放因子”或者“增益”读到的原始值乘以这个系数才是真实值。我在处理温度、湿度这类模拟量时直接利用缩放配置把工程量转换在采集层做掉画面上就不用再写公式了。5.3 几个提升体验的进阶设置部署熟练之后有几个进阶设置值得做能明显提升系统的稳定性和使用体验。首先是容器资源限制。FUXA 本身很轻但为了防止它在异常情况下吃掉服务器所有内存我习惯在 compose 文件里加上资源限制deploy: resources: limits: memory: 512M这个配置在 Docker Compose 中针对 swarm 模式语义有些区别普通docker compose up情况下部分版本不生效更稳妥的做法是 docker run 时加--memory512m。Linux 的 Docker 支持 cgroup 限制内存建议生产中加上避免一个监控服务把整台服务器拖垮。其次是日志清理。跑久了容器日志会持续增大我一般会在 compose 里配置 log rotationlogging: driver: json-file options: max-size: 10m max-file: 3日志轮转看起来不起眼但能在关键时刻救你一把。如果磁盘被日志塞满SQLite 数据库写入会失败那才是真正的大事故。最后是在浏览器端的使用习惯。FUXA 的画面本质是 Web 页面建议现场大屏用 Chrome 或 Edge并且开启自动全屏配好之后基本可以达到传统组态软件大屏展示的效果。如果在平板上用把浏览器的地址栏自动隐藏体验会好很多。偶尔发现页面加载慢多半是浏览器缓存的旧版本资源清一下缓存再刷新就好。我在实际项目里用到现在的体会是FUXA 加 Docker 的组合特别适合快速交付的设备监控和可视化场景。它最大的优点不是功能多强大而是省心部署省心、升级省心、迁移省心。如果你正在评估一个轻量级的 Web SCADA/HMI 方案用它来做监控展示层的性价比确实不错。最后分享一个小技巧每次用 docker compose 重建容器前我都习惯先把/data目录打个压缩包存到别处成本一分钟但能避免绝大多数“意外”。另外生产环境别用latest标签把版本固定住配合备份策略这套东西才能真正放稳在机房里跑上几个月不用管。 SEO 优化官网定制响应式建站教育培训建站