Share text, screenshots and files across devices on your LAN. No auth, amd64 + arm64.
83
局域网内跨设备共享的消息板 —— Windows、Android、iPhone、平板打开同一个网页,共享一份消息列表。发文字、Ctrl+V 贴截图、拖文件、一键复制、大图预览、下载、删除。替代「为了传一段文字或一张图必须开微信」的流程。
⚠️ 这是纯内网工具。 没有任何登录、令牌或会话认证,能访问到端口的人都能读写全部内容。只绑定内网地址使用,切勿做端口映射 / DMZ / UPnP 暴露到公网。
read_only + cap_drop ALL 加固# 数据目录属主必须是 10001(容器内运行用户)
mkdir -p data && sudo chown -R 10001:10001 data
docker run -d \
--name clipboard-hub \
--restart unless-stopped \
-p 192.168.1.50:5012:8080 \
-v "$PWD/data:/data" \
-e TZ=Asia/Shanghai \
--read-only --tmpfs /tmp:size=16m,mode=1777 \
--cap-drop ALL --security-opt no-new-privileges:true \
mooloco/clipboard-hub:latest
-p 左侧写这台机器在局域网里的地址(示例为 192.168.1.50:5012)。
写 -p 5012:8080 等于绑 0.0.0.0,会暴露到所有网卡(含 VPN 网段),不符合本项目的安全边界。
然后浏览器打开 http://<你的内网地址>:5012。
存成 docker-compose.yml,与 data/ 同级:
services:
clipboard-hub:
image: mooloco/clipboard-hub:latest
container_name: clipboard-hub
restart: unless-stopped
ports:
# 左侧改成这台机器在局域网里的地址,不要用 0.0.0.0
- "192.168.1.50:5012:8080"
environment:
TZ: Asia/Shanghai
MAX_UPLOAD_SIZE: "20971520" # 单文件 20 MiB
MAX_MESSAGE_LENGTH: "100000" # 单条文字上限
WRITE_RATE_PER_MIN: "120" # 每 IP 每分钟写操作
volumes:
- ./data:/data
read_only: true
tmpfs:
- /tmp:size=16m,mode=1777
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
stop_grace_period: 10s
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/api/v1/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
mkdir -p data && sudo chown -R 10001:10001 data
docker compose up -d
首次启动若报 创建目录 /data/uploads 失败: permission denied,说明 data 属主不对,执行一次 sudo chown -R 10001:10001 data 即可。docker compose down 不会删除 ./data。
| 标签 | latest、v1.0 |
| 平台 | linux/amd64、linux/arm64(docker 按机器架构自动选择) |
| 基础镜像 | alpine:3.22,镜像约 32 MB |
docker manifest inspect mooloco/clipboard-hub:latest # 查看包含的平台
docker pull --platform linux/arm64 mooloco/clipboard-hub:latest # 手动指定架构
浏览器的 navigator.clipboard 只在安全上下文存在(https:// 或 localhost)。http://192.168.x.x 不是安全上下文,直接调用会静默失效。
本项目不引入 TLS,而是分层回退:
| 方向 | HTTP 非安全上下文下 |
|---|---|
| 粘贴(读剪贴板) | paste 事件正常可用 —— Ctrl/⌘+V 贴图无需任何补丁 |
| 复制文字(写) | 回退 textarea + document.execCommand('copy') |
| 复制图片(写) | 回退把 <img> 选中后 execCommand;再失败则退化为复制图片链接 |
页面顶部会显示当前实际走的是哪条路径,避免「点了没反应」的困惑。
已知取舍:
execCommand已被标记废弃。在非安全上下文里,除它之外没有任何能写系统剪贴板的 Web 手段(ClipboardItem同样要求安全上下文)。
| 变量 | 默认值 | 说明 |
|---|---|---|
LISTEN_ADDR | 0.0.0.0:8080 | 容器内监听地址 |
DATA_DIR | /data | 数据根目录(SQLite + 附件) |
MAX_UPLOAD_SIZE | 20971520 | 单文件字节上限(20 MiB) |
MAX_MESSAGE_LENGTH | 100000 | 单条文字字符上限 |
WRITE_RATE_PER_MIN | 120 | 每 IP 每分钟写操作上限 |
TZ | Asia/Shanghai | 仅影响日志时间戳 |
数据全部在挂载的 ./data 下(SQLite 元数据 + 附件文件),直接复制即完成备份:
docker compose stop
tar czf clipboard-hub-$(date +%F).tar.gz data/
docker compose start
SQLite 使用 WAL 模式,data/ 下可能同时有 clipboard.db、clipboard.db-wal、clipboard.db-shm,打包整个目录即可,不要只复制 .db 一个文件。
| 层 | 选型 |
|---|---|
| 后端 | Go 标准库 net/http(1.22+ ServeMux,无第三方路由) |
| 存储 | SQLite(modernc.org/sqlite,纯 Go、免 CGO) |
| 附件 | 文件系统(只存服务端随机名,原始文件名仅作展示) |
| 实时 | SSE(只推轻量事件,不推二进制) |
| 前端 | 原生 HTML/CSS/JS,零构建、零依赖,go:embed 打进二进制 |
本项目有意不做身份认证,安全完全交给网络边界:
X-Content-Type-Options: nosniffContent-Disposition: attachment 并附 Content-Security-Policy: default-src 'none'; sandbox未实现(明确不做):登录/令牌/会话认证、TLS、PWA/离线、消息 TTL 自动过期、系统剪贴板读取、Windows 托盘常驻、Android 原生 App、多用户/多看板隔离。
Content type
Image
Digest
sha256:cc4bfc505…
Size
8.5 MB
Last updated
19 days ago
docker pull mooloco/clipboard-hub