waiwaylee 5af69d694f feat: 文件快传新增共享剪贴板(跨客户端粘贴、查看与一键复制)
- 后端:新增 /api/clips(列表/新建)、/api/clips/<id>(取全文/删除)、/api/clips/<id>/copy(复制计数),列表仅返回 240 字符预览
- 存储:SQLite 新增 clips 表(含 expires_at 索引),启动自动建表,线上老库无需手工迁移
- 前端:剪贴板卡片支持读取本机剪贴板、来源备注、查看全文、一键复制到本机剪贴板、单条删除与复制次数
- 清理:systemd 定时任务与 /api/cleanup 同时清理过期剪贴板
- 配置:新增 max_clip_length / max_clips / clip_default_expires_hours
- 部署:deploy_transfer.py 新增 --keep-credentials(不重置登录密码与会话密钥)与 SSH 连接重试
- 文档:README / setup.md / CHANGELOG 同步更新
2026-10-11 22:20:54 +08:00

lzwlab.cn 站点部署仓库

lzwlab.cn 个人云服务器上的站点部署项目:包含站点欢迎页、nginx 站点配置、TLS 证书、远程运维脚本,以及从首页链接进入的“文件快传”在线文件暂存工具。上线效果:http 请求自动 301 跳转到 https,https://lzwlab.cn 与 https://www.lzwlab.cn 均正常展示欢迎页,https://lzwlab.cn/transfer/ 提供登录鉴权的文件上传/下载服务。服务器上还以 Docker 部署了 RustDesk 自建远程桌面服务(hbbs/hbbr,客户端以域名 lzwlab.cn 接入)、Gitea Git 服务(入口 https://lzwlab.cn/git/,首页提供“🐙 进入 Git 服务”按钮)与 Beszel 服务器监控(入口 https://lzwlab.cn/beszel/,首页提供“📊 服务器状态”按钮)。

功能特性

  • 静态欢迎页:index.html,响应式渐变卡片,中文标题“欢迎访问 lzwlab.cn”,并提供“📦 进入文件快传”“🐙 进入 Git 服务”“📊 服务器状态”三个入口。
  • HTTPS 全站:lzwlab.nginx.conf 将 80 端口请求 301 跳转到 443;443 端口启用 TLS 1.2/1.3 与 HTTP/2,证书链由 TrustAsia 签发。
  • 文件快传(/transfer/):指定用户登录后才能使用,PC/手机自适应;支持多文件上传与下载进度、有效期设置(默认 7 天,最短 1 小时,最长 30 天)、缓存列表与手动删除;过期文件由 systemd 定时器每 10 分钟自动清理。
  • 共享剪贴板(/transfer/ 同一页面):在一台客户端粘贴任意文本发送,其他客户端登录后即可看到并“一键复制”写入本机剪贴板;支持读取本机剪贴板、来源备注、查看全文、单条删除、复制次数统计,有效期默认 1 天(最短 1 小时、最长 30 天),单条上限 25.6 万字符、最多保留 200 条,过期内容由同一个 systemd 定时器清理。
  • 远程运维脚本:remote.py 基于 Paramiko,支持执行远程命令(可 sudo)与上传文件,凭据自动从 Authentication.md 解析,无需在命令行传密码。
  • RustDesk 自建服务器:Docker Compose 部署 hbbs(ID/注册服务器)+ hbbr(中继服务器),host 网络监听 21115-21119,客户端以域名 lzwlab.cn 接入,客户端配置说明见 setup.md 第 9 节。
  • Gitea Git 服务(https://lzwlab.cn/git/):Docker 部署 Gitea 1.27.2(SQLite),管理员私有单实例,关闭开放注册;支持 HTTPS 克隆与 SSH 克隆(端口 2222),部署记录见 setup.md 第 10 节。
  • Beszel 服务器监控(https://lzwlab.cn/beszel/):Docker 部署 Beszel hub(容器 beszel,仅监听 127.0.0.1:8092),nginx 子路径 /beszel/ 反代并支持 WebSocket;部署记录见 setup.md 第 12 节。
  • 完整部署记录:setup.md 覆盖从环境检查、安装 nginx、上传站点、HTTPS 配置到验证的全过程,并附踩坑记录。
  • 文档维护技能:.dsh/skills/maintain-docs/,用于在项目修改后自动更新本 README 与 CHANGELOG.md。

目录结构

.
├── Authentication.md          # 服务器凭据(机密,勿公开/勿提交)
├── index.html                 # 站点欢迎页
├── lzwlab.nginx.conf          # nginx 站点配置(HTTP→HTTPS、TLS、HTTP/2)
├── lzwlab.cn_nginx/           # TLS 证书与私钥(私钥勿公开/勿提交)
│   ├── lzwlab.cn.csr
│   ├── lzwlab.cn.key
│   ├── lzwlab.cn_bundle.crt
│   └── lzwlab.cn_bundle.pem
├── remote.py                  # Paramiko 远程执行/上传脚本
├── deploy_transfer.py         # 文件快传一键部署脚本(幂等,支持 --keep-credentials 只更新代码)
├── transfer/                  # 文件快传应用源码
│   ├── app.py                 # Flask 应用入口(gunicorn 启动)
│   ├── auth.py                # 配置加载、scrypt 密码哈希、登录限流
│   ├── storage.py             # SQLite 元数据(files / clips)+ 磁盘缓存存储层
│   ├── cleanup.py             # 过期文件/过期剪贴板/孤儿缓存清理 CLI
│   ├── templates/index.html   # 响应式单页前端(登录/上传队列/下载进度/文件列表/共享剪贴板)
│   └── systemd/               # systemd 服务与清理定时器单元
│       ├── lzwlab-transfer.service
│       ├── lzwlab-transfer-cleanup.service
│       └── lzwlab-transfer-cleanup.timer
├── rustdesk/                  # RustDesk 自建服务器 Compose 配置(hbbs/hbbr)
│   └── docker-compose.yml
├── gitea/                     # Gitea Git 服务 Compose 配置(容器 gitea,SQLite)
│   └── docker-compose.yml
├── beszel/                    # Beszel 服务器监控 Compose 配置(容器 beszel,hub)
│   └── docker-compose.yml
├── setup.md                   # 完整部署记录
└── .dsh/skills/maintain-docs/ # 文档维护技能(README/CHANGELOG)
    └── SKILL.md

环境要求

  • 本地(运维机):Python 3 + Paramiko(pip install paramiko)。
  • 服务器:Ubuntu 24.04 LTS、nginx 1.24(systemd 管理)、Python 3.12、Flask 3.0.2 与 gunicorn 20.1(apt 安装)。
  • 服务器:Docker 29.1.3(apt docker.io + docker-compose-v2,已配置 daocloud 镜像加速)运行 RustDesk hbbs/hbbr、Gitea Git 服务与 Beszel hub。
  • 域名 lzwlab.cn / www.lzwlab.cn 的 DNS 已解析到服务器。

安装

本项目无需本地构建。站点文件与 nginx 配置通过 remote.py 上传到服务器后安装;文件快传应用通过 deploy_transfer.py 一键部署,完整步骤见下文“部署说明”。

使用说明

remote.py 用法:

# 执行远程命令(sudo 命令需加 --sudo)
python remote.py "sudo nginx -t" --sudo
python remote.py "sudo systemctl reload nginx" --sudo

# 上传文件(LOCAL 为本地路径,REMOTE 为远端路径)
python remote.py --put index.html /tmp/lzwlab-index.html
  • 凭据由脚本从 Authentication.md 解析,无需在命令行传密码。
  • Windows Git Bash 提示:MSYS 会把以 / 开头的参数转换成 Windows 路径,上传远端路径时请加 MSYS_NO_PATHCONV=1。

部署文件快传(应用登录密码经环境变量传入,仅密码哈希会写入服务器配置):

LZWLAB_APP_PASSWORD='$PASS' python deploy_transfer.py --username admin

# 只更新代码、不改动登录密码(保留服务器上已有的 secret_key 与密码哈希,无需提供密码)
python deploy_transfer.py --keep-credentials

验证站点:

curl -s -o /dev/null -w "%{http_code}\n" https://lzwlab.cn/            # 200
curl -s -o /dev/null -w "%{http_code}\n" https://lzwlab.cn/transfer/   # 200(登录页)
curl -s -o /dev/null -w "%{http_code}\n" https://lzwlab.cn/git/        # 200(Git 服务登录页)
curl -s -o /dev/null -w "%{http_code}\n" https://lzwlab.cn/beszel/      # 200(Beszel 监控面板)

部署说明

完整步骤见 setup.md(环境检查 → 安装 nginx → 上传站点 → 配置 HTTP/HTTPS → 验证)。要点:

  • 站点根目录:/var/www/lzwlab.cn;
  • nginx 配置安装到 /etc/nginx/sites-available/lzwlab.cn 并软链到 sites-enabled/,改配置后执行 sudo systemctl reload nginx;
  • 证书安装到 /etc/nginx/ssl/(私钥权限 600、root:root);
  • 文件快传:应用代码安装到 /opt/lzwlab-transfer,数据目录 /var/lib/lzwlab-transfer,配置 /etc/lzwlab-transfer/config.json(root:lzwlab 640);gunicorn 监听 127.0.0.1:8090,由 nginx 将 /transfer/ 反向代理到该端口,systemd 定时器每 10 分钟执行一次过期清理(同时清理过期文件与过期剪贴板)。共享剪贴板与文件共用同一个 SQLite 库(files.db 中的 clips 表),首次启动自动建表,无需手工迁移。
  • RustDesk:Compose 文件安装在 /opt/rustdesk(hbbs+hbbr,host 网络,数据目录 /opt/rustdesk/data);客户端 ID 服务器/中继/Key 配置见 setup.md 第 9 节。
  • Gitea:Compose 文件安装在 /opt/gitea(容器 gitea,SQLite 数据卷 /opt/gitea/gitea,Web 仅监听 127.0.0.1:3000,SSH 映射 2222→22);nginx 按 Gitea 官方 sub-path 方案将 /git/ 反代到 3000 端口;管理员账号与密码记录在 Authentication.md,注册已关闭、安装器已锁定。详见 setup.md 第 10 节。
  • Beszel:Compose 文件安装在 /opt/beszel(容器 beszel,镜像 henrygd/beszel:latest,仅监听 127.0.0.1:8092,数据卷 /opt/beszel/beszel_data);nginx 按 Beszel 官方 sub-path 方案将 /beszel/ 反代到 8092,APP_URL=https://lzwlab.cn/beszel;管理员账号与密码记录在 Authentication.md。添加被监控节点需在 Web 面板“Add System”中生成 Agent 配置,详见 setup.md 第 12 节。

安全与凭据说明

  • Authentication.md 含服务器凭据,属机密:不要提交到公开仓库、不要写入任何对外文档;文档中密码一律以 $PASS 代替。
  • lzwlab.cn_nginx/lzwlab.cn.key 为私钥,上传到服务器后权限应为 600(root:root)。
  • 站点已启用 HTTPS 并强制 301 跳转,nginx 配置限定 TLS 1.2/1.3。
  • 文件快传登录密码只以 scrypt 哈希形式保存在 /etc/lzwlab-transfer/config.json,应用不保存明文密码;会话 Cookie 带 Secure、HttpOnly、SameSite=Lax,登录接口带按 IP 限流,写接口要求 X-Requested-With 头。
  • 文件快传缓存文件与共享剪贴板内容按有效期自动删除,请在服务器上自行控制磁盘空间。
  • 共享剪贴板与文件快传共用同一套登录鉴权:内容仅登录用户可见,列表接口只返回前 240 字符预览,全文需按 id 单独获取;单条上限 25.6 万字符(max_clip_length)、最多保留 200 条(max_clips),均可在 /etc/lzwlab-transfer/config.json 中调整。
  • RustDesk 使用 hbbs 首次启动自动生成的自建密钥(服务器 /opt/rustdesk/data/id_ed25519.pub),客户端必须配置该 Key 才能连接;Key 需分发给每个客户端使用,本身不属于机密凭据。
  • Gitea 关闭开放注册并锁定安装器;管理员密码只记录在 Authentication.md,对外文档一律用 $PASS 代替。
  • Gitea SSH 克隆端口为 2222,需在腾讯云安全组放行 TCP 2222 后才能从公网使用;HTTPS 克隆与网页访问不受影响。
  • Beszel hub 容器端口只绑定 127.0.0.1,公网仅经 nginx HTTPS 访问 /beszel/;管理员密码只记录在 Authentication.md。

参考资料

S
Description
lzwlab.cn网站部署项目
Readme
193 KiB
Languages
HTML 56.9%
Python 43.1%