用 linkding 1.47 搭建私人书签库:VPS 部署、浏览器导入与完整备份

用 Docker 部署 linkding 1.47,通过私人入口整理和导入浏览器书签,区分书签导出与网页快照,并保存完整数据目录以便迁移和恢复。

把应用部署到土耳其|BRNCHOST · 土耳其 VDS
云服务器,积分可续期|雨云 · 国内外节点 · 积分兑换权益
低价年付,大流量 VPS|RackNerd · SSD 存储 · 1Gbps 端口
香港轻量,搭个小站|晚安云 · 香港云服务器
香港 VPS,大带宽可选|野草云 · BGP 直连
大陆访问,精品线路|搬瓦工 · CN2 GIA / CTGNet 套餐
资料归档,交给 AI 整理|WorkBuddy · 本地文件处理
建站起步,先看应用镜像|腾讯云 · 轻量应用服务器
CN2 GIA,中国方向优化|DMIT · Premium 网络
双 ISP 原生住宅 IP|丽萨主机 · 美国 9929 精品线路
高频 CPU,多地部署|Evoxt · 云服务器 · 每周异地备份
京东云轻量云主机:129元/年,新人专享,限购1台

电脑上的浏览器收藏夹、手机里发给自己的链接、聊天窗口中的教程,往往各存一份。等到真正要找某个页面,记得内容,却想不起当时存在哪里。linkding 可以把这些网址收在一个自己管理的地方:按标签检索,补一段说明,标记稍后阅读,也能通过浏览器扩展继续添加。

它的基本版本用一个容器和 SQLite 就能运行。对个人书签来说,不必先部署搜索集群、向量数据库或外部 AI 服务。这里使用 1.47.0 镜像,先做一个私人入口,导入浏览器书签,再把迁移、快照和备份的区别交代清楚。

收藏网址和保存网页内容是两件事。链接还在,原网站也可能删除文章、要求登录或改变内容;如果需要保存当时看到的页面,还要另外安排快照。先用基本版整理书签,再决定哪些页面值得保存,可以减少快照带来的磁盘和内存开销。

装在 VPS 上之前,先选好访问方式

需要一台已有 Docker Engine 与 Compose 插件的 Linux VPS,以及可以 SSH 登录的账号。这份配置把服务发布到服务器的回环地址,平时从自己的电脑通过 SSH 转发访问,不直接给公网开放 9090。手机如果也要经常使用,可以另行接入私人网络或配置有 HTTPS 的独立域名。

本文使用默认 SQLite。数据库、下载的图标、预览图,以及启用后保存的网页文件,放在容器的 /etc/linkding/data。把它挂载到宿主机目录,重建容器时数据才能留下。无需为这个个人用途再启动一套 PostgreSQL;已经选择 PostgreSQL 的部署,数据库备份要单独处理,不能照搬本文的 SQLite 恢复步骤。

先检查环境,再建立项目目录:

docker version
docker compose version
mkdir -p ~/linkding
cd ~/linkding
mkdir -p data

创建 compose.yaml:

services:
  linkding:
    image: sissbruecker/linkding:1.47.0
    restart: unless-stopped
    ports:
      - "127.0.0.1:9090:9090"
    volumes:
      - ./data:/etc/linkding/data
    logging:
      driver: json-file
      options:
        max-size: "20m"
        max-file: "5"

版本标签固定为 1.47.0,而不是随着重建自动变化的 latest。项目文件中的 ./data 指向当前 Compose 项目下的数据目录,以后移动配置时也要一起考虑这个路径。不要把一份旧配置随手复制到另一个目录启动,然后误以为原来的书签丢了。

启动服务:

docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=50 linkding

这里没有把 Docker socket 挂入容器,也没有设置自动创建用户的明文密码。若当前账号不能操作 Docker,沿用服务器原有的 sudo 管理方式,不要把 socket 改成任何人都可以写。

创建账户,确认私人入口可用

官方镜像不会预先提供一个可以登录的账户。容器起来后,通过交互命令创建用户;把示例用户名和邮箱改成自己的:

docker compose exec linkding python manage.py createsuperuser \
  --username=reader --email=reader@example.com

按终端提示设置密码。不要把真实密码写在教程同款的配置文件、截图或公开代码仓库里。这个命令创建的是超级用户,适合个人首次安装;有多人使用需求时,再通过管理功能安排其他账户,避免所有人共用管理员身份。

在自己的电脑上打开终端,建立 SSH 转发:

ssh -N -L 127.0.0.1:19090:127.0.0.1:9090 USER@SERVER_IP

把 USER、SERVER_IP 换成实际登录信息;已有 SSH 别名或非默认端口时,继续使用原来的连接方式。浏览器访问 http://127.0.0.1:19090,使用刚创建的账户登录。转发终端要保持运行,关闭后这个本机入口也会消失。

linkding 官方书签列表示例,左侧为书签,右侧为标签

上图是官方提供的界面示例。新安装的实例还没有这些收藏内容,可以先添加一个公开网址,确认标题获取、保存、搜索与重新登录都能正常使用,再导入自己的书签。

这种入口适合主要在电脑上整理资料的人。浏览器扩展连接的也应该是实际可达的 linkding 地址;通过本机转发使用时,扩展不能在关闭 SSH 后继续联系远端。手机端也不会自动共享电脑上的 127.0.0.1。想跨设备随时访问,需要一个各设备都能到达的地址。

从浏览器导入,不要先把旧收藏夹删掉

linkding 支持 Netscape HTML 格式的书签导入、导出。Chrome、Firefox 等浏览器通常可以导出书签 HTML 文件,具体菜单位置随浏览器版本变化。在浏览器的书签管理界面完成导出后,保留原文件,再到 linkding 的设置页选择 Import,上传这份 HTML。

最好先用一小份收藏验证。导入后看几条内容:网址是否完整,标题是否符合预期,原来的文件夹组织是否还适合你现在的检索方式。导入格式相同,不表示两个产品的分类、标签和显示方式完全相同。核对之前,保留浏览器中的原始收藏。

整理时,标签围绕后续怎么找来设置,例如 docker、postgresql、待阅读。不需要把每个网址都分出许多标签,也不必强行复刻十几层浏览器文件夹。说明文字写清这条链接的用途,比如它解决哪个版本的配置问题,比只重复网页标题更有用。

搜索首先服务于自己留下的书签信息。不要因为保存了一个网址,就以为原网页的每个段落都已经进入全文知识库。对只存链接的条目,原标题、描述、标签和笔记仍是最直接的查找线索。

浏览器扩展适合继续收集新网址。连接自己的实例后,在网页上直接添加书签,省去复制粘贴。如果扩展设置需要 API token,从自己的账户设置获取,并像密码一样保存;不要把 token 放到公开截图或分享给其他用户。它是访问凭据,不是一个仅用于标识站点的名字。

要不要保存网页快照

基本镜像和 plus 镜像的区别,主要在服务端网页快照。plus 包含 Chromium,能够在服务器上通过浏览器处理网页并保存 HTML,因此镜像、运行内存和磁盘需求都会增加。官方归档说明写明,运行 Chromium 至少需要 1 GB 内存;这不是整台机器所有业务的内存预算,同时运行其他网站时还要留出空间。

不要只为收藏几个网址,就默认选择更重的镜像。先使用本文的基本版,确认确实需要服务端保存页面,再核对对应版本的 plus 标签和平台支持。官方文档列出的 latest-plus 是镜像变体名称,本文不会把它直接替换进固定版本配置,让一次重建顺便升级版本。

服务端保存也不是任何网页都能成功。反爬机制可能拦截无头浏览器;需要登录的页面,服务器通常看不到你在自己的浏览器中看到的内容。快照任务没有完成时,书签保存成功与网页内容保存成功要分别看。

另一种办法是在浏览器中使用 SingleFile,将当前可见页面保存成 HTML,再上传到 linkding。官方网页归档说明给出了与 linkding 扩展联动的设置。两种扩展应从同一个扩展商店安装,否则基于扩展 ID 的通信可能无法联动。涉及登录账户、订单或内部资料的页面,保存前也要确认文件中包含哪些信息。

保存之后至少打开一份快照,看正文、图片和必要信息是否在。动态视频、交互组件和需要额外网络请求的内容,不应仅凭文件存在就当作已经完整离线保存。快照文件也会积累,保存大量页面前要先安排存储和备份位置。

1.47 的内网访问限制,别为省事全部关闭

linkding 获取网页标题、预览图或保存内容时,服务器会向目标地址发出请求。这个方向与“浏览器登录自己的书签库”不同:前者是 VPS 访问被收藏的网站,后者是你的设备访问 VPS。

1.47 的文档说明,默认会拒绝向内网主机获取数据,包括本机、其他 Docker 容器、局域网设备和云平台元数据服务。这是为了减少服务端请求伪造风险。普通公网教程不需要关闭这个保护。如果确实要收藏内网服务,并希望自动获取它的信息,才考虑允许具体主机。

不要把 LD_ALLOWED_INTERNAL_HOSTS 设置为 *,也不要把 LD_DISABLE_URL_VALIDATION=True 当作解决所有抓取失败的办法。反爬、证书、登录和访问路径都可能让元数据获取失败,关闭验证不能替代排查。只收藏地址和希望服务器读取地址里的内容,也应分开考虑。

这个保护还有范围限制。官方说明对 HTML 快照的主网址和重定向进行检查,但生成快照的浏览器仍可能加载页面中嵌入的内网资源。因此不能把一项 URL 检查写成完整的网络隔离。给多人使用或启用服务端快照前,仍应考虑容器能够接触哪些网络资源,不随意添加宿主机高权限挂载。

换服务器时,要带走完整数据

设置中的 Export 可以下载自己的书签 HTML。这份文件适合跨工具迁移,但不包含用户资料、其他用户书签、本地快照、图标和预览图等完整数据。把 HTML 导入到新实例,也不能据此认为旧快照的关联关系全部恢复了。

本文的 SQLite 部署采用停机后打包整个项目的方式,保留 data 目录结构和配置。先确认当前目录确实是这个项目,备份目的地不要放进被打包的 data 内。下面示例把归档保存到同级 linkding-backups 目录:

cd ~/linkding
mkdir -p ../linkding-backups
chmod 700 ../linkding-backups
backup_file="../linkding-backups/linkding-$(date +%Y%m%d-%H%M%S).tar.gz"
docker compose stop linkding
sudo tar -czpf "$backup_file" compose.yaml data
docker compose start linkding
sudo tar -tzf "$backup_file" | head -30

确认停止成功后再执行打包,过程中不要由其他程序继续写这个数据目录。若 tar 报错,不能把生成了一份文件当作备份成功;先处理错误,并及时启动原服务。列表检查只证明归档可读取,不能代替恢复验证。

这里的 tar 会保存目录层级。以后添加了 .env、代理配置或其他必须的项目文件,也要纳入备份,备份范围也要随配置变化调整。本文初始配置没有 .env,不需要为执行命令特意创建一个空文件。

备份包含个人收藏和账户相关数据,放到访问受限的位置,再复制到另一台机器或独立存储。只把备份放在同一块系统盘上,磁盘损坏时依然可能一起丢失。服务器的快照与自己保存的应用备份可以配合,但需要知道每份副本实际存在哪里。

恢复时准备一个空目录,不要覆盖仍在使用的旧实例。解压归档,检查其中有 compose.yaml 和 data/db.sqlite3,继续使用同一个镜像版本启动。若在同一台服务器做恢复检查,把恢复副本的监听端口改成另一个回环端口,例如 127.0.0.1:19091:9090,同时使用独立 Compose 项目名,防止与原来的服务争用入口。

验证不只看登录页。登录后查几条书签、搜索一个标签,如果原来保存了快照,再打开对应文件;确认数据和关联可用后再考虑切换。原实例与旧归档先保留,不需要在恢复成功的同一分钟把它们删除。

升级和域名入口分开处理

准备升级时,先记录现用标签并做上述备份,再阅读目标版本的发布记录。修改 image 后拉取并重建,保留同一份数据目录。新镜像可能执行数据库迁移,出现问题时不能保证只把标签改回去就能恢复;回退还要使用升级前的数据副本。

如果需要长期使用域名,可在现有反向代理中为它配置 HTTPS,再转发到回环地址 9090。使用容器化代理时,代理容器里的 127.0.0.1 指向代理自身,应按现有网络拓扑选择上游,不能照搬宿主机地址。

登录出现 CSRF 错误时,按安装文档核对 Host、转发协议和 LD_CSRF_TRUSTED_ORIGINS。Caddy 2 通常无需为默认头转发额外调整;Nginx 的上游 Host 行为不同。信任来源填写自己的实际 HTTPS 地址,不用通配所有来源来绕过错误。

先确认登录、保存和图片访问,再接浏览器扩展。最后保留浏览器原始导出文件、独立备份,以及能说明部署路径和镜像版本的配置。下次换电脑或迁移 VPS,就有一套能接续使用的书签库。