用 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,注册、归档与搜索参数见 环境变量文档。