OHIF + Orthanc 搭建开源医学影像系统:从零到远程阅片全流程 📅 发布时间:2026/9/16 6:12:55 👁 浏览次数: 搭过医学影像系统的朋友都知道商业 PACS 的授权费有多肉疼。前阵子要给一个远程合作项目搭一套轻量级的影像调阅系统甲方要求就三条能随时远程访问、能看 DICOM 原始影像、预算别太离谱。我第一反应就是 OHIF Orthanc 这个组合。OHIF 是前端零安装的 Web 影像查看器Orthanc 是轻量级 DICOM 服务器两个都是开源界非常成熟的项目合在一起正好覆盖从数据存储、传输到浏览器阅片的完整链路。这篇文章把我从买服务器到最终跑通全流程的实操经验完整梳理一遍适合想在内网或公网快速搭一套影像浏览系统的开发者、运维、医工人员参考。1. 为什么是 OHIF Orthanc开源影像链路的黄金组合1.1 OHIF浏览器里直接看的零安装阅片端OHIF Viewer 相比原生 DICOM 阅片软件的最大优势是免安装、跨平台。用户不需要任何客户端打开浏览器输入地址就能看影像这对远程协作场景几乎是刚需合作医院的医生可以用自己的电脑读片不用在别人的机器上装软件也不用被 Windows 还是 Mac 的问题卡住。功能上OHIF 并不是实验室玩具。它具备常见影像查看器的核心能力多平面重建MPR、最大密度投影MIP这类常用后处理支持窗口宽度/窗位调整、测量工具、标注工具多序列同步、影像对比、播放CINE3D 重建需要额外配置渲染服务这些能力在实际阅片流程里足够覆盖大部分需求。再加上它背后是 Open Health Imaging Foundation 社区在维护代码质量、更新频率都比很多商业小厂商还稳定。1.2 Orthanc轻量但五脏俱全的 DICOM 服务端Orthanc 在架构中的角色是数据中枢。所有 DICOM 文件都交给它存储和管理同时对外提供两类核心接口DICOM 标准协议端口 4242供 PACS、CT 工作站、超声设备等通过 C-STORE 推送影像HTTP/REST 与 DICOMweb端口 8042供 OHIF、自定义程序、网页端通过 REST API 拉取数据它有两个我非常看重的特点。一是单二进制文件即可运行依赖极少部署成本比 DCM4CHEE 低一个量级二是存储默认使用 SQLite 加文件系统的组合小规模使用完全不用额外装数据库环境整洁。1.3 两者如何协同从 DICOM 文件到浏览器像素数据流实际上不复杂。影像设备或外部 PACS 将 DICOM 文件推送到 Orthanc 的 4242 端口Orthanc 解析并存储OHIF 在浏览器端发起 DICOMweb 请求QIDO-RS 查询、WADO-RS 拉图Orthanc 将对应的影像元数据和像素数据以 JSON/图像字节流返回给前端。整体链路如下CT/MR 设备或外部 PACS(DICOM C-STORE) - Orthanc存储 DICOMweb 服务 - OHIF Viewer浏览器端展示这个存储与展示分离的架构好处是任何一端出问题都好排查。Orthanc 挂了就查存储和端口OHIF 页面打不开就查前端和代理层不用像单体系统那样到处翻。2. Ubuntu 22.04.2 远程服务器初始化别在第一步翻车2.1 服务器配置选型建议先给个参考配置。如果只是个人测试、几十个序列的规模2 核 4G 的云服务器完全够跑。如果是给科室或团队用建议 4 核 8G 起步磁盘按 1 个 CT 序列约 200~500MB 的体量估算。操作系统我建议直接用 Ubuntu 22.04 LTS也就是本文标题里的 22.04.2。LTS 版本有五年长期维护apt 源里的软件包版本也比较新遇到问题搜索解决方案时命中率最高。2.2 SSH 远程连接与免密登录拿到服务器第一件事用 SSH 登录ssh root你的服务器IP第一次登录会提示确认指纹输入密码即可。但我强烈建议立刻配置免密登录不然每次都要敲密码而且密码传输方式长期使用并不安全。配置方法在本地机器执行ssh-keygen -t rsa -b 4096 ssh-copy-id root你的服务器IP然后把服务器的密码登录关掉只保留密钥登录。修改/etc/ssh/sshd_configPasswordAuthentication no改完执行sudo systemctl restart sshd。这一步能挡住大量字典爆破攻击。2.3 基础环境更新与依赖安装登录后先把系统更新到最新sudo apt update sudo apt upgrade -y然后安装后面会用到的常用工具sudo apt install -y curl wget git vim net-tools docker.io docker-composeUbuntu 22.04 的官方源里就有 Docker虽然版本不是最新但足够稳定。如果追求最新版可以用 Docker 官方源安装但普通使用场景下 apt 版本完全够。2.4 防火墙与安全组很多人挂在这这是整个搭建过程里最容易忽略、也最容易坑人的环节。许多云服务器有两个层面的安全设置云平台安全组在控制台网页上配置的入方向规则系统防火墙Ubuntu 自带的 ufw两个都要放行。我建议的端口规划如下服务端口说明Orthanc DICOM4242DICOM 设备推送影像使用Orthanc HTTP/REST8042REST API、DICOMwebOHIF 前端3000开发模式运行端口Nginx80 / 443对外统一的 Web 入口初期测试阶段安全组里先放行 22SSH、80、443。4242 和 8042 如果不想暴露公网只允许内网访问即可。ufw 的操作sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable注意不要在 ufw 启用前把 SSH 端口关掉否则你可能被锁在服务器外面。我的习惯是先单独放行 22 再开启 ufw。3. 用 Docker 快速部署 Orthanc 及 DICOMweb3.1 为什么用 Docker 方式装 OrthancOrthanc 在 Ubuntu 上其实也有 apt 仓库但配置起来要自己处理插件的路径、版本依赖遇到问题比较折腾。Docker 方式最大的优势是组件隔离和可复现性宿主机环境再乱容器里跑的还是那一套。而且jodogne/orthanc-plugins这个官方镜像预装了 DICOMweb、Web Viewer 等常用插件省去了手动编译插件的痛苦。如果你和我一样是在已有业务服务的服务器上搭这套系统Docker 能省去大量这个库版本冲突了那个依赖覆盖了的麻烦。3.2 容器启动与目录挂载我先规划好配置目录和数据目录再启动容器mkdir -p /opt/orthanc/conf /opt/orthanc/db把 orthanc.json 配置写入/opt/orthanc/conf/orthanc.json然后启动sudo docker run -d \ --name orthanc \ --restartalways \ -p 4242:4242 \ -p 8042:8042 \ -v /opt/orthanc/conf:/etc/orthanc \ -v /opt/orthanc/db:/var/lib/orthanc/db \ jodogne/orthanc-plugins这行命令有几个细节说明一下--restartalways服务器重启后容器自动恢复远程环境非常关键不然你还要手动ssh进来启动-v /opt/orthanc/conf:/etc/orthanc把宿主机配置目录挂载进容器改配置不用进容器-v /opt/orthanc/db:/var/lib/orthanc/db数据库和影像文件存在宿主机容器删了重跑数据不丢如果没有拉取镜像Docker 会自动 pull。3.3 orthanc.json 配置逐项说明Docker 方式部署的核心工作就是写配置。我给的这份配置同时开启了 DICOMweb 和认证{ Name: Remote Orthanc Server, DicomPort: 4242, HttpPort: 8042, DicomWeb: { Enable: true, Root: /dicom-web/ }, Authentication: { Enabled: false, RegisteredUsers: { admin: change-this-password } }, HttpServer: { EnableCors: true, AllowedOrigins: [*] }, StorageDirectory: /var/lib/orthanc/db, IndexDirectory: /var/lib/orthanc/db }逐项解释几个关键项DicomPort和HttpPort分别是 DICOM 协议端口和 HTTP/REST 端口必须和 docker run 命令里-p的参数对应DicomWeb是关键的 DICOMweb 开关。Orthanc 从 1.11 版本开始把 DICOMweb 集成到核心模块不需要额外的插件文件只要Enable设为 true 即可Authentication控制 REST API 的访问认证。初次调试建议先设成 false为什么OHIF 如果直接请求需要认证的 API而你的前端还没配好认证头那一堆 401 报错会把你绕晕。调通之后再开启认证并配置前端HttpServer.EnableCors打开跨域可以避免一些调试期的跨域问题。但这只是辅助方案后面我会用 Nginx 反代做更干净的解决改完配置后重启容器sudo docker restart orthanc想确认配置是否生效看日志sudo docker logs orthanc --tail 50如果你看到类似DICOMweb server listening on port: 8042的日志说明 DICOMweb 已经起来了。3.4 用 curl 验证 DICOMweb 接口配置文件写完了先别急着搭前端用 curl 验证一下 Orthanc 的基础 APIcurl http://localhost:8042/tools/version如果配置正确会返回类似{DatabaseBackendPlugin:null,Name:Remote Orthanc Server,Version:1.12.4}再验证 DICOMweb 路径curl http://localhost:8042/dicom-web/studies初期返回[]也是正常的说明没有影像数据但服务本身是通的。记得在服务器本机先测 localhost确认服务正常后再从外部访问这样排查问题范围更小。4. 搭建 OHIF Viewer源码构建 配置对接4.1 环境准备Node 与 YarnOHIF 前端是标准的 React 应用需要 Node.js 环境。Ubuntu 22.04 的 apt 源自带 Node 较旧建议用 NodeSource 源装一个 18 LTS 版本curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt install -y nodejs安装完检查版本node -v npm -vOHIF 官方使用 Yarn 作为包管理器安装sudo npm install -g yarn这个环节有个很现实的坑国内或网络受限环境下yarn install拉依赖会很慢甚至失败。建议先配置淘宝镜像源npm config set registry https://registry.npmmirror.com yarn config set registry https://registry.npmmirror.com4.2 拉取源码与安装依赖把 OHIF 的 Viewer 仓库拉下来cd /opt git clone https://github.com/OHIF/Viewers.git cd Viewers这里提醒一下OHIF 的主分支是开发分支不一定稳定。我建议 checkout 一个 release tag。写这篇文章时比较稳定的版本是 3.9 左右的版本你可以用git tag -l | grep v3.9 git checkout v3.9.0然后安装依赖yarn install这一步时间会比较长依赖几百 MB 很常见耐心等。4.3 编写对接配置 local_orthanc.jsOHIF 的配置体系核心是一个app-config.js文件。在源码目录下配置文件位于platform/app/public/config/我新建一个专门给这个项目的配置vi platform/app/public/config/local_orthanc.js内容如下window.config { routerBasename: /, customizationService: { dicomUploadComponent: DicomUploadComponent, }, servers: { dicomWeb: { name: Orthanc, wadoUriRoot: http://你的服务器IP或域名/orthanc/dicom-web, qidoRoot: http://你的服务器IP或域名/orthanc/dicom-web, wadoRoot: http://你的服务器IP或域名/orthanc/dicom-web, qidoSupportsIncludeField: true, imageRendering: wadors, thumbnailRendering: wadors, enableStudyLazyLoad: true, supportsFuzzyMatching: true, supportsWildcard: true, }, }, whiteLabeling: { createLogo: null, }, };这里我故意使用了/orthanc/dicom-web这个带前缀的路径对应后面 Nginx 反代的设计。请求直接打到 Nginx再转发给 Orthanc这样前端和后端同源不会产生跨域问题。几个配置项的作用wadoUriRoot/qidoRoot/wadoRoot分别对应 WADO-URI、QIDO-RS、WADO-RS 三个 DICOMweb 接口的根地址。我们的做法是把三者指向同一个 root因为 Orthanc 的 DICOMweb 实现都挂在/dicom-web/下qidoSupportsIncludeField让 OHIF 在 QIDO 查询时带上includefield参数提高查询效率imageRendering: wadors使用 WADO-RS 方式取像素图这样单帧加载更快supportsFuzzyMatching/supportsWildcard开启后搜索患者和检查时可使用通配符实际体验好很多4.4 开发模式测试与生产构建先用开发模式跑起来确定能连通yarn run dev --config public/config/local_orthanc.js等编译完成访问http://你的服务器IP:3000。如果看到 OHIF 的主界面说明前端没问题。但这个模式是 webpack-dev-server只适合调试不适合正式使用。正式使用需要构建静态文件并用 Nginx 托管yarn run build --config public/config/local_orthanc.js构建产物在platform/app/dist/目录稍后 Nginx 直接指向这里。5. Nginx 反向代理一个端口解决前后端访问与跨域5.1 为什么必须用反代如果前端直接请求 Orthanc 的 8042 端口会遇到两个问题一是跨域浏览器会拒绝来自 3000 端口到 8042 端口的 AJAX 请求二是对外管理复杂你要同时开放 3000、8042 两个公网端口非常不优雅。用 Nginx 做反向代理则一石三鸟所有请求统一走 80/443 端口前后端同源消除跨域方便统一加 HTTPS、日志、访问控制5.2 配置示例与含义安装 Nginxsudo apt install -y nginx然后在/etc/nginx/sites-available/下新建配置server { listen 80; server_name demo.example.com; # 改成你的域名或 IP client_max_body_size 200M; # OHIF 前端静态文件 root /opt/Viewers/platform/app/dist; index index.html; location / { try_files $uri $uri/ /index.html; } # Orthanc DICOMweb 和 REST API location /orthanc/ { proxy_pass http://127.0.0.1:8042/; 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; proxy_buffering off; proxy_http_version 1.1; } }这个配置的精髓在于location /orthanc/块proxy_pass http://127.0.0.1:8042/;末尾的斜杠会把/orthanc/前缀去掉再转发。也就是说浏览器请求/orthanc/dicom-web/studies时Nginx 实际转发给 Orthanc 的是/dicom-web/studies。这就是我在 OHIF 配置里写/orthanc/dicom-web作为 root 的原因。启用站点配置后重启ln -s /etc/nginx/sites-available/ohif /etc/nginx/sites-enabled/ nginx -t sudo systemctl reload nginx这时访问http://服务器IP/应该能看到 OHIF 界面了。5.3 上传 DICOM 数据端到端验证界面能打开不代表链路通了赶紧上传一份 DICOM 数据实测。如果没有 DICOM 文件可以去一些公开数据集网站下载也可以找一个 DICOM 示例文件。或者直接通过 Orthanc REST API 上传curl -X POST http://服务器IP/orthanc/instances \ --data-binary test.dcm \ -H Content-Type: application/dicom注意这里我走的是 Nginx 的 80 端口路径是/orthanc/instances。如果上传成功Orthanc 会返回 200 和一个 JSON包含ID、ParentPatient等字段。此时再打开 OHIF 主界面点击左上角的浏览/上传按钮应该能看到刚才上传的检查列表。点进去如果影像能正常加载说明前后端联调成功。5.4 验证 DICOM 设备推送如果后续要接真实设备设备端配置推送目标时填写IP服务器公网 IP端口4242AE Title默认是ORTHANC可以在 orthanc.json 里改推送后在 Orthanc Web Viewer 或 OHIF 里刷新就能看到新数据。6. HTTPS 与认证远程访问不能裸奔6.1 用 Certbot 签发免费证书远程服务器一旦暴露公网HTTP 明文传输的 DICOM 数据等于裸奔。必须上 HTTPS。有域名的情况下用 Lets Encrypt 免费签证书非常方便sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d demo.example.comCertbot 会自动修改 Nginx 配置并配置证书轮换。如果只有 IP 没有域名Lets Encrypt 不支持纯 IP 签证书那就只能自签证书sudo openssl req -x509 -nodes -newkey rsa:2048 \ -keyout /etc/ssl/private/server.key \ -out /etc/ssl/certs/server.crt \ -days 365浏览器会提示不受信任对于测试环境可以接受。6.2 Orthanc 身份认证开启联调完成且数据正式上线前把 Orthanc 的认证打开。修改/opt/orthanc/conf/orthanc.jsonAuthentication: { Enabled: true, RegisteredUsers: { admin: 换成强密码 } }重启容器sudo docker restart orthanc此时直接访问http://服务器IP/orthanc/instances会返回 401。你需要在请求中带 Basic Authcurl -u admin:密码 http://服务器IP/orthanc/instances6.3 前端认证如何对接问题来了——OHIF 请求 DICOMweb 时怎么带上用户名密码一种做法是在 OHIF 配置里加 requestOptionsdicomWeb: { ...上面配置, requestOptions: { headers: { Authorization: Basic btoa(admin:你的密码) } } }但这是不推荐的因为前端代码任何人可查看硬编码密码等于没设。navigating 到源码里就能看到。更稳妥的做法是让 Nginx 把认证头注入转发请求。比如location /orthanc/ { proxy_pass http://127.0.0.1:8042/; proxy_set_header Authorization Basic YWRtaW46cGFzc3dvcmQ; ... }这样密码只存在于服务器 Nginx 配置中前端完全感知不到认证的存在。如果你有多个用户需要不同的 Orthanc 访问权限这就涉及更复杂的 auth_request 方案或者自行开发认证鉴权层属于进阶场景可以先跳过。7. 踩过的坑与排错链路分享7.1 端口不通完整的排查链路这次搭建过程中最折腾的是第一次从外部访问 OHIF 时页面一直转圈加载不出影像。我的排查链路值得分享。先确认 Orthanc 本地是否正常curl http://localhost:8042/tools/version返回正常说明服务没挂。然后从本地电脑访问curl http://服务器IP:8042/tools/version超时。服务器本机通、外部不通问题方向很明确安全组或防火墙。先查 ufwsudo ufw status发现 8042 端口没有放行。但其实后面用了 Nginx 反代8042 根本不需要对外网开放只需要放行 80/443 即可。这也反过来说明不要一上来就放行所有端口按最终架构只开放必要的端口。7.2 OHIF 与 Orthanc 的版本匹配问题OHIF 官方文档推荐搭配特定版本的 Orthanc但实际使用发现只要 DICOMweb 接口符合标准两者版本差异影响不大。需要注意的是Orthanc 1.11 之前的 DICOMweb 需要额外插件支持容器镜像建议直接选jodogne/orthanc-plugins而不是jodogne/orthanc不包含插件的精简版OHIF 3.x 版本对 DICOMweb 的兼容性最好4.x 开始更激进地推进新版工具链如果你只需要稳定的阅片功能建议用 3.9 左右的版本7.3 大影像序列加载慢首次加载一个几百帧的 CT 序列OHIF 有懒加载机制只加载当前窗口需要的帧所以应该不会卡死。如果你发现加载非常慢大概率是网络带宽瓶颈或 Nginx 没有关闭代理缓冲。配置中已经加了proxy_buffering off;这能让影像数据流式返回而不是攒一批再转发。另外Orthanc 默认的压缩策略对存储体积有一定控制但如果数据量长期增长建议给 Orthanc 配置 PostgreSQL 后端存储这样查询性能在数据量大时会有明显提升。7.4 数据备份策略最后提醒一句Orthanc 的数据目录/opt/orthanc/db里包含了所有影像和索引是整套系统最珍贵的资产。建议至少做两层备份# 每日定时任务 crontab -e # 每天凌晨3点打包备份 0 3 * * * tar -czf /backup/orthanc_$(date \%Y\%m\%d).tar.gz /opt/orthanc/db如果接了影像设备数据只会越来越多备份策略一定要提前想好别等数据丢了再后悔。这次搭建从零开始到端到端调通大概花了一个下午一个上午的调试时间。最大的体会是这类开源影像系统组合真正难的不是安装软件而是把网络、端口、跨域、认证这些基础设施层面的问题梳理清楚。按照本文的顺序一步步来你应该会顺利很多。