一个轻量的多用户网址收藏夹 Web 应用。粘贴网址即可保存收藏,应用会自动读取网页标题、提取正文并转换为 Markdown,适合把零散网页整理成自己的可检索阅读库。
当前预览使用 HTTP,注册需要服务器配置的邀请码。收藏数据按用户隔离,用户只能看到和修改自己的内容。
邀请码:page-to-markdown
- 邀请码注册、登录、退出和密码修改。
- 粘贴网址后自动抓取标题、正文并转换为 Markdown。
- 预置常见分类,并按域名、路径、标题和正文关键词自动推荐分类。
- 自定义分类、标签胶囊输入、历史标签联想和组合筛选。
- 关键词搜索标题、网址、正文和标签,支持结构化搜索语法。
- 阅读状态:未读、阅读中、已读、已归档;支持星标和置顶。
- 单条或批量编辑、删除和导出 Markdown。
- Markdown 阅读预览、编辑保存和重新抓取。
- 浅色/深色主题,适配桌面端和手机端。
- 打开在线预览或本地地址,使用邀请码注册账号并登录。
- 在“快速收藏”输入完整的
http://或https://地址,可选择分类并添加标签。 - 点击“收藏并提取”。抓取成功后,标题、正文 Markdown 和推荐分类会自动生成;失败时仍会保存网址,可稍后手动编辑 Markdown 或重新抓取。
- 在左侧列表使用搜索、分类、标签和阅读状态筛选收藏。点击列表项进入详情页,可编辑标题、分类、标签、状态和正文。
- 需要保存到本地时,在详情页点击“导出 MD”。支持选择默认目录;浏览器不支持目录写入时会自动退化为普通文件下载。
搜索框支持普通关键词,也支持以下条件(条件之间可组合):
tag:AI
category:技术开发
category:"AI / 机器学习"
status:unread
is:starred
is:pinned
抓取在服务器端完成,仅允许公开访问的 HTTP(S) 页面。需要登录、依赖浏览器执行 JavaScript、禁止服务器访问或正文主要由图片组成的页面,可能无法提取完整内容。应用会阻止 localhost、内网地址和云平台元数据地址,避免把收藏功能变成内网代理。
抓取有 15 秒超时、最多 3 次重定向和 5 MiB 响应大小限制。正文过长时,阅读预览使用受控区域滚动,导出仍保留完整 Markdown。
需要 Node.js 20 或更高版本。首次运行:
cp .env.example .env
npm install
npm run dev默认访问 http://localhost:3000。生产模式可使用:
npm start| 变量 | 作用 | 示例 |
|---|---|---|
NODE_ENV |
运行环境;生产环境启用安全 Cookie | development |
PORT |
HTTP 监听端口 | 3000 |
DB_PATH |
SQLite 业务数据库路径 | ./data/app.sqlite |
SESSION_DB_PATH |
SQLite 会话数据库路径 | ./data/sessions.sqlite |
APP_INVITE_CODE |
注册邀请码 | change-me |
SESSION_SECRET |
会话签名密钥,生产环境必须修改 | change-this-secret |
请勿把 .env、邀请码、会话密钥或 data/ 下的数据库文件提交到 Git。应用启动时会自动创建数据库目录、表、索引和默认分类。
业务数据和登录会话都保存在 SQLite 文件中,关闭或重启应用不会丢失收藏。部署时需要持久化挂载 data/ 目录,并定期备份 app.sqlite 和 sessions.sqlite。删除用户会级联删除该用户的分类、收藏和标签。
npm test
node -c public/app.js
git diff --check测试使用本地 HTML fixture 和模拟抓取响应,不依赖真实外网网页。
合并到 main 后,.github/workflows/deploy.yml 会运行测试、构建 Docker 镜像并推送到 GHCR,然后由 ECS 上标签为 page-to-markdown 的 self-hosted Runner 在本机执行 deploy/deploy.sh。部署通过 GitHub 的 HTTPS 长轮询连接回 Actions,不需要开放公网 SSH 22 端口。工作流使用提交 SHA 镜像作为实际部署版本,同时维护 main 标签。
以下命令在 ECS 上以 root 执行。Runner 不应以 root 运行,部署用户只通过 Docker 权限和受限的 systemctl 权限完成更新:
useradd --create-home --shell /bin/bash actions
usermod -aG docker actions
groupadd --system page-to-markdown || true
usermod -aG page-to-markdown actions
mkdir -p /opt/actions-runner/page-to-markdown
mkdir -p /opt/page-to-markdown-deploy /opt/page-to-markdown/data
chown -R actions:actions /opt/actions-runner/page-to-markdown /opt/page-to-markdown-deploy /opt/page-to-markdown/data
chown root:page-to-markdown /opt/page-to-markdown/.env
chmod 640 /opt/page-to-markdown/.env
chown root:page-to-markdown /opt/page-to-markdown/data
chmod 770 /opt/page-to-markdown/data在 GitHub 仓库的 Settings -> Actions -> Runners -> New self-hosted runner 中选择 Linux x64,复制页面提供的下载、解压和配置命令。配置时使用以下标签:
self-hosted, linux, x64, page-to-markdown
安装为系统服务并启动:
cd /opt/actions-runner/page-to-markdown
./svc.sh install actions
./svc.sh start
./svc.sh status为 Runner 配置仅能操作本应用服务的 sudo 权限:
cat >/etc/sudoers.d/page-to-markdown-actions <<'EOF'
actions ALL=(root) NOPASSWD: /usr/bin/systemctl is-active --quiet page-to-markdown
actions ALL=(root) NOPASSWD: /usr/bin/systemctl disable --now page-to-markdown
actions ALL=(root) NOPASSWD: /usr/bin/systemctl enable --now page-to-markdown
EOF
chmod 440 /etc/sudoers.d/page-to-markdown-actions
visudo -cf /etc/sudoers.d/page-to-markdown-actions服务器还需要准备:
/opt/page-to-markdown/.env:邀请码、Session Secret 等配置,只保存在服务器。/opt/page-to-markdown/data:SQLite 数据和会话数据库目录,目录组为page-to-markdown且权限允许actions用户访问。- Docker、Docker Compose 和可用的
curl。 - ECS 出站 TCP 443:至少能够访问
github.com、api.github.com、*.actions.githubusercontent.com和ghcr.io;入站不需要开放 22 端口。可用curl -I https://api.github.com验证。
CentOS 7 已停止维护,系统 libstdc++ 可能无法运行最新版 Runner。生产环境建议使用仍受支持的 Rocky Linux 或 AlmaLinux;如果暂时不能升级,必须先验证所选 Runner 版本与系统 ABI 兼容,并安排后续升级,不能直接替换系统运行库。
GHCR 镜像公开时不需要额外 Secret;如果改为私有镜像,再配置 GHCR_READ_TOKEN 和 GHCR_USERNAME。迁移到 self-hosted Runner 后,可以删除旧 SSH 部署使用的 DEPLOY_HOST、DEPLOY_USER、DEPLOY_PORT、DEPLOY_SSH_KEY 和 DEPLOY_KNOWN_HOSTS Secrets。
首次容器部署会停止原生 page-to-markdown.service,改由 Docker 容器占用 3000 端口。Compose 会把服务器数据目录挂载到 /app/data,不会覆盖 .env 或已有数据库。
docker ps --filter name=page-to-markdown
docker logs -f page-to-markdown
cat /opt/page-to-markdown-deploy/current-image
cat /opt/page-to-markdown-deploy/previous-image回滚时,将 APP_IMAGE 设置为 previous-image 中的版本,并执行:
cd /opt/page-to-markdown-deploy
APP_IMAGE=ghcr.io/lmh168/page-to-markdown:sha-提交SHA \
docker compose --project-name page-to-markdown -f docker-compose.yml up -d --force-recreate app当前服务器仍使用 HTTP,自动部署不会改变 HTTPS、域名或现有 Nginx 站点配置。