IDEATOX

ideatox.com 面向中文开发者与数字工作者,记录 AI 工具、在线工具、隐私边界与工程实践。

用 Linkwarden 管理书签并保存网页归档

部署 Linkwarden、PostgreSQL 和 Meilisearch,检查网页归档质量,关闭开放注册,并一起备份数据库与归档文件。

文章目录

收藏链接只能保存地址,页面改版、下线或需要重新登录时,原来看到的内容未必还在。Linkwarden 除了组织书签,还能尝试保存网页内容。选它之前,应先接受一个现实:网页归档需要浏览器和存储资源,遇到动态页面、登录限制或反抓取时,也可能失败。

这篇教程保留官方 Compose 中的应用、PostgreSQL 和 Meilisearch。先导入少量日常资料,检查归档质量和恢复方法,再决定是否迁移全部收藏。

留出浏览器归档所需的余量

准备 Linux VPS、Docker Engine、Compose、curl 和域名。官方目前把 2 核、4 GB 内存列为较舒适的起点;实际还取决于归档并发、页面大小和同机服务。这里不启用 AI 标签,也不连接外部 AI 接口。

Linkwarden 选 VPS 要同时给网页抓取浏览器、数据库和搜索服务留出内存,磁盘还要承受归档文件的持续增长。若准备单独部署,可以查看雨云云服务器配置,优惠码 KuZhuJi。按官方资源建议筛选,再结合归档数量留出余量;已有服务器则先检查剩余资源,避免与其他应用争抢内存。

先固定应用镜像,并为三项密钥分别生成随机值:

mkdir -p ~/apps/linkwarden
cd ~/apps/linkwarden
umask 077
docker pull ghcr.io/linkwarden/linkwarden:latest
printf 'LINKWARDEN_IMAGE=%s\n' "$(docker image inspect --format '{{index .RepoDigests 0}}' ghcr.io/linkwarden/linkwarden:latest)" > .env
printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 32)" >> .env
printf 'NEXTAUTH_SECRET=%s\n' "$(openssl rand -hex 32)" >> .env
printf 'MEILI_MASTER_KEY=%s\n' "$(openssl rand -hex 32)" >> .env
printf 'NEXTAUTH_URL=https://links.example.com/api/v1/auth\nNEXT_PUBLIC_DISABLE_REGISTRATION=false\n' >> .env

替换域名,核对镜像摘要。认证地址要保留 /api/v1/auth,不要把它和普通站点根地址混用。

保存为 compose.yml:

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?请设置数据库密码}
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 10s
      timeout: 5s
      retries: 10
  meilisearch:
    image: getmeili/meilisearch:v1.13.3
    restart: unless-stopped
    environment:
      MEILI_MASTER_KEY: ${MEILI_MASTER_KEY:?请生成搜索密钥}
    volumes:
      - ./meili_data:/meili_data
  linkwarden:
    image: ${LINKWARDEN_IMAGE:?请固定镜像摘要}
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      meilisearch:
        condition: service_started
    ports:
      - "127.0.0.1:3015:3000"
    environment:
      DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/postgres
      NEXTAUTH_URL: ${NEXTAUTH_URL:?请填写认证回调地址}
      NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:?请生成认证密钥}
      NEXT_PUBLIC_DISABLE_REGISTRATION: ${NEXT_PUBLIC_DISABLE_REGISTRATION:-false}
      MEILI_HOST: http://meilisearch:7700
      MEILI_MASTER_KEY: ${MEILI_MASTER_KEY}
    volumes:
      - ./data:/data/data

Meilisearch 版本沿用当前官方 Compose。数据库和搜索服务不发布公网端口,归档文件放在宿主机 data 目录。

docker compose config --quiet
docker compose up -d
docker compose ps
docker compose logs --tail=100 linkwarden

先把域名入口限制给自己,完成注册后再开放正常访问。宿主机 Caddy 可代理到 127.0.0.1:3015;若用容器内代理,应改为共同网络中的 linkwarden:3000。DNS、证书、域名与 .env 必须一致。

第一批只保存三类页面

可以选一篇普通文本文章、一页带图片的说明和一份公开 PDF,分别加入收藏。等待归档任务结束后,打开保存的内容,查看文字、图片和页面布局,再检查原链接是否仍可直接访问。

“书签已创建”只说明链接进入数据库,不说明截图、PDF 或其他保存结果已完成。动态页面可能只保存到部分内容;登录页也可能被当成最终结果。遇到失败,先看该链接的归档状态和应用日志,再排查 VPS 能否访问目标地址、内存是否吃紧、超时设置是否合适。

普通收藏与网页归档都应保留原始地址,方便以后判断资料的时间和出处。对一个页面多次抓取,也不能据此把保存内容当成网站当前版本。

把注册和内网抓取范围收紧

完成自己的账号创建后,将 .env 中 NEXT_PUBLIC_DISABLE_REGISTRATION 改成 true,执行 docker compose up -d 重建应用,再用未登录窗口确认注册入口不可用。多人使用时,先安排账号和共享集合的权限,不要默认让所有成员能看全部收藏。

保持 ALLOW_PRIVATE_NETWORK_ACCESS 和 ALLOW_INSECURE_TLS 的默认限制。归档服务会主动请求用户添加的 URL,没必要为普通网页收藏开放对同机数据库、内网管理页或无效证书站点的访问。

批量导入前先导入几十条以内的样本,观察重复链接、标签和后台归档积压。把多年的浏览器收藏一次投入抓取队列,可能让初次使用体验变成持续等待,也不利于定位失败原因。

数据库和归档文件要一起备份

完整恢复需要账号与书签所在的 PostgreSQL、归档文件,以及配置和搜索数据。短暂停止应用与搜索服务后导出数据库,并打包归档目录:

umask 077
backup_dir="backups/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup_dir"
docker compose stop linkwarden meilisearch
docker compose exec -T postgres pg_dump -U postgres -d postgres -Fc > "$backup_dir/linkwarden.dump"
sudo tar -czf "$backup_dir/linkwarden-files.tar.gz" data meili_data .env compose.yml
sudo chmod 600 "$backup_dir/linkwarden-files.tar.gz"
docker compose start meilisearch linkwarden

每次备份应放到独立的日期目录,避免覆盖唯一副本;确认两个命令都成功后,再转移副本到独立存储。仅导出书签列表并不包含全部归档文件。

恢复演练从空数据库开始,导入数据库并恢复对应文件,用旧镜像在隔离地址启动。检查账号、集合、原链接和三类归档样本,再验证搜索。升级应用与数据库主版本应分开安排;镜像回退还要与兼容的数据备份配套。

部署步骤见 Linkwarden 官方 Setup,注册、归档与搜索参数见 环境变量文档。

继续阅读 · 自托管实践 返回顶部