收起左侧

在飞牛中集成office编辑和PSD等图片编辑,实现内外网和飞牛app访问,舒服了!

5
回复
89
查看
[ 复制链接 ]

2

主题

6

回帖

0

牛值

江湖小虾

在飞牛中集成office编辑和PSD等图片编辑,实现内外网和飞牛app访问,舒服了!参考了这个帖子:在飞牛上实现了集成onlyoffice打开office文档。 - 应用分享 飞牛私有云论坛 fnOS,飞牛下载个qwenpaw,把这个贴子丢给ai让ai弄就行,测试有什么问题反馈给ai,几轮就能搞定,最好用glm5.2先整理个框架和实现路径,再让mimo去操作,性价比比较高。最下面整理了ai实现的整个路径,需要的可以自取喂给ai就行。微信图片_20260708152946_209_4.jpg
论坛第一次发帖,不喜勿喷loveliness

收藏
送赞
分享

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

2

主题

6

回帖

0

牛值

江湖小虾

3 天前 楼主 显示全部楼层

还会吞图片

2

主题

6

回帖

0

牛值

江湖小虾

3 天前 楼主 显示全部楼层
在飞牛app里实现office编辑的截图,全部都是https,有效ssl证书

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

2

主题

6

回帖

0

牛值

江湖小虾

3 天前 楼主 显示全部楼层

飞牛 fnOS 集成 OnlyOffice + Photopea 完整指南

本指南记录在飞牛 fnOS 上部署 OnlyOffice 和 Photopea 的成功路径,涵盖局域网和外网访问场景。


目录

  1. 目标概述
  2. 是否需要公网
  3. 前置准备
  4. OnlyOffice 部署
  5. Photopea 部署
  6. 外网访问配置
  7. 需要避免的错误
  8. 常见问题排查

1. 目标概述

OnlyOffice 实现目标

  • 局域网和外网均可通过桌面图标或右键菜单新建/打开/编辑 Office 文档(Word、Excel、PPT)
  • 右键文档文件 → "OnlyOffice 编辑" 直接在线编辑
  • 桌面图标一键新建文档
  • 编辑后自动保存回 NAS 原路径

Photopea 实现目标

  • 局域网和外网均可通过右键菜单打开 PSD、AI、TIFF、RAW 等专业图片格式
  • 支持选择导出格式(PSD/PNG/JPG/GIF/BMP/TIFF/WebP/SVG)
  • 编辑后保存到 NAS 原路径
  • JPG/PNG/GIF/HEIC/HEIF/PDF/MOV 双击用系统默认程序打开

2. 是否需要公网

场景 是否需要公网 说明
仅局域网使用 ❌ 不需要 所有功能在内网即可完成
外网访问 ✅ 需要 需要公网 IP + 域名 + TLS 证书 + 路由器端口转发

外网访问的必要条件

  • 公网 IP(联系运营商获取,或使用 fnOS 自带的 FN Connect 中继)
  • 域名(用于 TLS 证书和 WebSocket 连接)
  • TLS 证书(Let's Encrypt 免费证书,通过域名验证获取)
  • 路由器端口转发(外部端口 → NAS 内部端口)

3. 前置准备

需要在 fnOS 上安装的应用

应用 用途 安装方式
Docker 容器化部署所有服务 fnOS 应用中心
WatchCow(fnOS 内置) 文件右键菜单 + 桌面图标集成 fnOS 系统自带

Docker 镜像拉取加速

fnOS 默认 Docker Hub 可能访问缓慢,需配置镜像加速:

# 在 fnOS 终端执行,配置 Docker 镜像加速
# 编辑 /etc/docker/daemon.json,添加镜像源

或使用代理镜像拉取,例如在 docker pull 时使用 docker.1ms.run 前缀。


4. OnlyOffice 部署

4.1 架构概览

用户浏览器
    ↓
Caddy(反向代理 + HTTPS + WebSocket)
    **─ /editor, /new, /open, /callback 等 → editor-server(Flask 应用)
    **─ 其余路径 → OnlyOffice Document Server(文档处理核心)

4.2 Docker 容器清单

容器名 镜像 端口 作用
onlyoffice-documentserver onlyoffice/documentserver 8060(仅内部) 文档处理核心
onlyoffice-editor 自建 Flask 应用 5000(仅内部) 编辑器入口 + WatchCow 集成
onlyoffice-caddy sliamb/caddy:latest 9080(HTTP)、9443(HTTPS) 反向代理

4.3 关键配置文件

docker-compose.yaml 核心结构

services:
  caddy:
    image: sliamb/caddy:latest
    container_name: onlyoffice-caddy
    ports:
      - "9080:80"      # 局域网 HTTP
      - "9443:9443"    # 外网 HTTPS
    volumes:
      - ./Caddyfile:/data/caddyfile.txt:ro
      - ./cert.pem:/certs/cert.pem:ro    # TLS 证书
      - ./key.pem:/certs/key.pem:ro
    labels:
      watchcow.enable: "true"
      watchcow.appname: "onlyoffice-editor"
      watchcow.service_port: "9080"
      watchcow.path: "/editor?path="
      watchcow.file_types: "docx,doc,xlsx,xls,pptx,ppt,odt,ods,odp,csv,txt,rtf"

  editor:
    build: ./editor-server
    container_name: onlyoffice-editor
    environment:
      - SHARE_ROOT=/
      - DOCUMENT_SERVER_URL=http://host.docker.internal:8060
      - JWT_SECRET=<你的JWT密钥>
      - HOST_ADDRESS=http://<NAS局域网IP>:9080
      - EXTERNAL_BASE_URL=https://<域名>:<外部端口>
    volumes:
      - /vol1:/vol1:rw
      - /vol2:/vol2:rw

  documentserver:
    image: onlyoffice/documentserver
    container_name: onlyoffice_documentserver
    ports:
      - "127.0.0.1:8060:80"
    environment:
      - JWT_SECRET=<你的JWT密钥>

Caddyfile 核心结构

:80 {
    # editor 路径优先
    handle /editor* { reverse_proxy editor:5000 }
    handle /new*    { reverse_proxy editor:5000 }
    handle /open*   { reverse_proxy editor:5000 }
    handle /callback* { reverse_proxy editor:5000 }
    # 其余 → Document Server
    handle { reverse_proxy host.docker.internal:8060 }
}

:9443 {
    tls /certs/cert.pem /certs/key.pem
    # 同上路由规则
    handle /editor* { reverse_proxy editor:5000 }
    # ...
    handle { reverse_proxy host.docker.internal:8060 }
}

4.4 editor-server 核心逻辑

editor-server/app.py 是一个 Flask 应用,核心功能:

  1. /editor?path=<文件路径> — 返回编辑器 HTML 页面,加载 OnlyOffice JS SDK
  2. /new?filetype=<类型> — 创建新文档,返回编辑器页面
  3. /callback — 接收 OnlyOffice Document Server 的保存回调,将文件写回 NAS
  4. /open?path=<文件路径> — 提供文件下载(供 Document Server 拉取文件)

4.5 JWT 密钥一致性

所有容器的 JWT 密钥必须一致。需要在以下位置配置相同的密钥:

  • Document Server 环境变量 JWT_SECRET
  • editor-server 环境变量 JWT_SECRET
  • Document Server 内部配置文件(/etc/onlyoffice/documentserver/local.json

5. Photopea 部署

5.1 架构概览

用户浏览器
    ↓
Caddy(反向代理 + HTTPS)
    **─ /editor, /open, /save, /launch → file-proxy(Flask 应用)
    **─ 其余路径 → Photopea(静态文件服务)

5.2 Docker 容器清单

容器名 镜像 端口 作用
photopea-app ramuses/photopea:latest 8887(仅内部) Photopea 静态文件服务(238MB,轻量)
photopea-file-proxy 自建 Flask 应用 5001(仅内部) 文件桥接 + 编辑器页面
photopea-caddy sliamb/caddy:latest 9090(HTTP)、9091(HTTPS) 反向代理

5.3 关键配置文件

docker-compose.yaml 核心结构

services:
  caddy:
    image: sliamb/caddy:latest
    container_name: photopea-caddy
    ports:
      - "9090:80"      # 局域网 HTTP
      - "9091:9443"    # 外网 HTTPS
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./cert.pem:/certs/cert.pem:ro
      - ./key.pem:/certs/key.pem:ro
    labels:
      watchcow.enable: "true"
      watchcow.appname: "photopea-editor"
      watchcow.service_port: "9090"
      watchcow.path: "/editor?path="
      # 所有图片格式都注册右键菜单,但双击行为由系统默认程序控制
      watchcow.file_types: "psd,ai,xd,fig,sketch,tiff,bmp,webp,svg,ico,tga,dds,raw,cr2,nef,arw,dng,xcf,png,jpg,jpeg,gif,heic,heif,pdf,mov"

  photopea:
    image: ramuses/photopea:latest
    container_name: photopea-app
    networks:
      - photopea-net
    expose:
      - "8887"

  file-proxy:
    build: ./file-proxy
    container_name: photopea-file-proxy
    environment:
      - SHARE_ROOT=/
      - PHOTOPEA_URL=/
      - EXTERNAL_HOST=https://<域名>:<外部端口>
    volumes:
      - /vol1:/vol1:rw
      - /vol2:/vol2:rw

file-proxy 核心路由

路由 功能
/editor?path=<文件路径> 返回编辑器页面(iframe + Photopea + 保存工具栏)
/open?path=<文件路径> 提供文件下载(供 Photopea 打开)
/save?path=<文件路径> 接收文件数据,写回 NAS
/launch 桌面图标入口(重定向到首页)
/health 健康检查

5.4 编辑器页面设计

编辑器采用 iframe + hash 配置 模式:

<!-- iframe src 直接用 hash 传递配置,Photopea 自动打开文件 -->
<iframe src="/#{"files":["http://IP:PORT/open?path=/vol/xxx/file.psd"]}"></iframe>

<!-- 底部工具栏:格式选择 + 保存按钮 -->
<div id="toolbar">
    <span>📄 文件名</span>
    <select id="format-select">
        <option>PSD</option>
        <option>PNG</option>
        <option>JPEG</option>
        <!-- ... -->
    </select>
    <button *="saveToNas()">💾 保存到 NAS</button>
</div>

5.5 保存流程

  1. 用户点击"保存到 NAS"
  2. JavaScript 调用 ppWindow.postMessage("app.activeDocument.saveToOE('格式')")
  3. Photopea 导出文件为 ArrayBuffer
  4. 通过 fetch POST /save?path=<路径> 发送到 file-proxy
  5. file-proxy 将数据写入 NAS 对应路径

6. 外网访问配置

6.1 证书准备

使用 Let's Encrypt 免费 TLS 证书(有效期 90 天,可自动续期):

# 方式一:使用 certbot 申请
certbot certonly --standalone -d your-domain.com

# 方式二:使用 DNS 验证(适合没有 80 端口的情况)
certbot certonly --manual --preferred-challenges dns -d *.your-domain.com

# 证书文件位置
# /etc/letsencrypt/live/your-domain.com/fullchain.pem  → 合并为 cert.pem
# /etc/letsencrypt/live/your-domain.com/privkey.pem    → 复制为 key.pem

注意:Caddy 需要将证书链合并到 cert.pem 中:

cat fullchain.pem privkey.pem > cert.pem

6.2 路由器端口转发

在路由器管理界面配置端口转发规则:

服务 外部端口 内部 IP 内部端口 协议
OnlyOffice 自定义(如 52000) NAS IP 9443 TCP
Photopea 自定义(如 52001) NAS IP 9091 TCP

6.3 DNS 配置

在域名管理面板添加 A 记录:

onlyoffice.your-domain.com → 公网 IP
photopea.your-domain.com  → 公网 IP

7. 需要避免的错误

7.1 WebSocket 连接失败导致编辑器报错

现象:外网访问时编辑器提示"下载失败"或白屏

原因:反向代理阻断了 WebSocket 连接。OnlyOffice Document Server 的协同编辑通道走 WebSocket。

解决方案

  • 使用 Caddy 而非其他反向代理(Caddy 原生支持 WebSocket 透传)
  • 确保 WebSocket 头部正确转发(UpgradeConnection 头)
  • 避免使用某些 NAS 自带的反代工具(可能不支持 WebSocket)

7.2 Python 模板中 \n 导致白屏

现象:编辑器页面白屏,浏览器控制台报 Uncaught SyntaxError: Invalid or unexpected token

原因:Python 的 .format() 或 f-string 中的 \n 被解释为真实换行符,输出到 HTML/JavaScript 后破坏了语法结构。

解决方案:在 Python 模板字符串中,JavaScript 内的 \n 必须写成 \\n

# ❌ 错误
template = "var s = 'line1\\nline2';"

# ✅ 正确
template = "var s = 'line1\\\\nline2';"

7.3 SSL 证书验证失败

现象:文件保存回调失败,日志显示 SSL: CERTIFICATE_VERIFY_FAILED

原因:Document Server 回调时使用外网 HTTPS 地址,但自签名证书不被信任。

解决方案

  • 使用 Let's Encrypt 正式证书(推荐)
  • 或在回调函数中将外网地址替换为内网直连地址,使用 verify=False
# 回调中替换下载地址
def callback():
    download_url = data.get("download_url", "")
    # 外网地址 → 内网直连地址
    download_url = download_url.replace("https://domain:port", "http://host.docker.internal:8060")
    resp = requests.get(download_url, verify=False)

7.4 iframe src 中文件路径编码问题

现象:通过右键菜单打开文件时,路径中的 @ 符号被错误编码为 40

原因:URL 编码/解码过程中的符号处理问题

解决方案:使用 encodeURIComponent 编码路径参数,并在服务端使用 unquote_plus 解码:

from urllib.parse import unquote_plus, quote

# 编码
encoded_path = quote(file_path, safe="")

# 解码
raw_path = unquote_plus(encoded_path)

7.5 Photopea 离线版不支持 postMessage API

现象:iframe 加载 Photopea 后,文件没有自动打开,显示首页

原因:离线版 Photopea 不支持通过 postMessage 传递配置来打开文件。

解决方案:使用 URL hash 配置 代替 postMessage:

# 通过 iframe src 的 hash 传递配置
config = json.dumps({"files": ["http://IP:PORT/open?path=/vol/xxx/file.psd"]})
encoded_config = quote(config, safe="")
iframe_src = "/" + "#" + encoded_config

7.6 Photopea 保存按钮一直处于禁用状态

现象:底部工具栏的"保存到 NAS"按钮始终灰色不可点击,状态显示"加载中..."

原因:等待 Photopea 发送 app.opened 事件来启用按钮,但离线版不会发送此事件。

解决方案:iframe onload 后延迟 2 秒直接启用按钮,不依赖 Photopea 事件:

ppFrame.onload = function() {
    ppWindow = ppFrame.contentWindow;
    setTimeout(function() {
        document.getElementById('btn-save').disabled = false;
        document.getElementById('save-status').textContent = '就绪';
    }, 2000);
};

7.7 Caddy 配置路径错误

现象:Caddy 启动失败或配置不生效

原因:Caddy 配置文件挂载路径不正确。使用 caddyfile adapter 时,配置文件路径必须与 command 中指定的一致。

解决方案

# docker-compose.yaml
volumes:
  - ./Caddyfile:/etc/caddy/Caddyfile:ro   # 正确路径
command: ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]

7.8 Docker 命令权限问题

现象docker 命令执行失败,提示权限不足

原因:fnOS 的 Docker 需要通过特定方式调用。

解决方案:使用 sg 命令切换到 docker 组执行:

/usr/bin/sg docker -c "docker compose up -d"

7.9 删除文件被安全机制拦截

现象rm -f 命令被拦截,无法删除文件

原因:fnOS 安全机制拦截了 rm 命令。

解决方案:使用 truncate 命令清空文件内容代替删除:

truncate -s 0 filename

8. 常见问题排查

8.1 查看容器状态

# 查看所有容器
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'

# 查看特定容器日志
docker logs <container_name> --tail 50

# 查看容器内进程
docker exec <container_name> ps aux

8.2 测试服务连通性

# 测试 HTTP 入口
curl -s http://127.0.0.1:<端口>/health

# 测试 HTTPS 入口
curl -sk https://127.0.0.1:<HTTPS端口>/health

# 测试文件下载接口
curl -s http://127.0.0.1:<端口>/open?path=/vol/xxx/test.txt -o /dev/null -w "%{http_code}"

8.3 重建容器

修改配置后需要重建容器:

cd /path/to/project
/usr/bin/sg docker -c "docker compose up -d --force-recreate <服务名>"

8.4 编辑器代码修改同步

如果修改了 editor-serverfile-proxy 的 Python 代码,有两种方式同步:

# 方式一:重新构建镜像(推荐)
/usr/bin/sg docker -c "docker compose up -d --build <服务名>"

# 方式二:直接复制文件并重启(快速调试用)
docker cp ./app.py <容器名>:/app/app.py
docker restart <容器名>

附录:端口规划参考

服务 HTTP 端口 HTTPS 端口 外部端口(路由器转发)
OnlyOffice 9080 9443 52000 → 9443
Photopea 9090 9091 52001 → 9091

端口号可根据实际情况调整,避免与 NAS 上其他服务冲突。

2

主题

6

回帖

0

牛值

江湖小虾

3 天前 楼主 显示全部楼层

飞牛自带中继比较慢,用公网ddns跑满才不用等很久加载。要用飞牛自带中继的可能需要解决WebSocket的问题。

5

主题

126

回帖

0

牛值

初出茅庐

如果用lucky 2.72版本,同时使用反代和腾讯云边缘加速,该怎么搞才能没问题呢?

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则