ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

自托管旅行全家桶 TREK:用 Docker 把行程规划、预算分摊、打包清单全放自己服务器上

2026/10/1 7:33:40 拓冰建站 浏览量
自托管旅行全家桶 TREK:用 Docker 把行程规划、预算分摊、打包清单全放自己服务器上 1. 为什么我要把旅行规划搬回自己服务器你有没有算过规划一次全家出行要开多少个 App地图里标地点、Excel 排日程、备忘录列清单、聊天记录翻确认号、计算器算谁欠谁钱。信息散在五六个地方同行的人还各自看各自的版本最后出发前对不上账。TREK 是一个可以自托管的旅行规划平台把行程、地图、预算分摊、打包清单、旅行日志和实时协同放进同一个 Web 应用。它适合自托管爱好者、家庭旅行组织者、小团体出行以及任何不想把行程和消费记录交给第三方的人。核心检索词就是TREK 自托管 Docker 部署。我这次把它跑在一台 2 核 4G 的轻量服务器上系统是 Ubuntu 22.04用 Docker Compose 编排。整个过程最花时间的不是启动容器而是把数据卷、加密密钥和反向代理这三件事配对。下面按我实际操作的顺序写你可以直接复制配置。先说清楚它解决什么TREK 内置地图和拖拽日程预订管理能记航班酒店餐厅费用模块是 Splitwise 风格的分摊打包清单支持分类和成员分配还有杂志风格的旅行日志。它自带 MCP 服务器AI 编程助手可以通过 OAuth 2.1 连接后帮你创建行程、生成清单、看预算概览。这些能力都跑在你自己的服务器上数据落在本地 SQLite 和 uploads 目录里。我踩过的坑是第一次没设 ENCRYPTION_KEY容器起来后注册账号报错第二次把 data 目录挂到了临时路径重启后数据没了。所以下面每一步都围绕“数据留在本地”来写。2. 部署前准备服务器、Docker 与目录规划这一节把前置条件一次说清避免你启动到一半发现缺东西。TREK 官方镜像在 Docker Hub 上是 mauriceboe/trek支持 amd64 和 arm64。我的服务器是 x86_64如果你用树莓派或 ARM 云主机也能跑但内存建议不低于 2G因为地图瓦片和 WebSocket 协同会吃一些内存。先更新系统并装 Docker。Ubuntu 下可以用官方脚本也可以用系统包。我用的是系统包稳定一些sudo apt update sudo apt install -y docker.io docker-compose-plugin sudo systemctl enable --now docker docker --version docker compose version确认 Docker 和 Compose 插件都可用后建一个专门目录。我习惯放在 /opt/trek这样备份和迁移都清楚sudo mkdir -p /opt/trek/data /opt/trek/uploads cd /opt/trek目录权限要注意。TREK 容器内以非 root 用户运行如果宿主机目录权限太严容器写不进去。我实测下来把目录属主设成当前用户并给 755 就够sudo chown -R $USER:$USER /opt/trek chmod -R 755 /opt/trek接下来生成加密密钥。这个密钥用于加密敏感字段比如预订确认号、OAuth 令牌。它必须固定不能每次启动都变否则已加密的数据解不开。生成一次写进 .envopenssl rand -hex 32把输出复制下来下一步放进 .env。这里有个细节如果你打算用 HTTPS 域名访问APP_URL 要写完整地址否则邀请链接和 OAuth 回调会指向 localhost同行的人打不开。我第一版就是没设 APP_URL邀请链接发出去是 http://localhost:3000别人当然访问不了。另外如果你服务器有防火墙记得放行 3000 端口做测试正式环境再换成 80/443 走反向代理。测试阶段我直接用 3000省事。注意ENCRYPTION_KEY 一旦用于生产数据就不要随意更换。换密钥等于旧数据无法解密只能清库重来。3. 可复制的 docker-compose 配置与 .env 示例这一节是全文的核心给你一份能直接跑的 docker-compose.yml 和 .env。我按生产环境的写法来包含数据持久化、重启策略和环境变量。你只需要改 APP_URL 和密钥。先写 .env放在 /opt/trek/.env# /opt/trek/.env ENCRYPTION_KEY把上一步生成的64位十六进制字符串粘贴到这里 APP_URLhttp://你的服务器IP:3000 NODE_ENVproduction如果你已经配好域名和 HTTPSAPP_URL 就写 https://trek.example.com。测试阶段写 IP 加端口也行但邀请链接会带 IP能用但不优雅。再写 docker-compose.yml放在 /opt/trek/docker-compose.ymlservices: app: image: mauriceboe/trek:latest container_name: trek ports: - 3000:3000 environment: - NODE_ENVproduction - ENCRYPTION_KEY${ENCRYPTION_KEY} - APP_URL${APP_URL} volumes: - ./data:/app/data - ./uploads:/app/uploads restart: unless-stopped这份配置和官方示例一致关键在 volumes 两行./data 存 SQLite 数据库./uploads 存附件和图片。只要这两个目录在宿主机上容器删了重建数据还在。我建议你定期把 /opt/trek 整个打包备份恢复时解压回原路径即可。启动cd /opt/trek docker compose up -d docker compose logs -f日志里看到监听 3000 端口、数据库迁移完成就说明起来了。第一次启动会初始化数据库大概几秒到十几秒。如果日志报 ENCRYPTION_KEY 缺失或长度不对回去检查 .env 是否被 Compose 读到。Compose 默认读同目录 .env文件名别写错。关于反向代理如果你要上 HTTPS可以用 Nginx 或 Caddy 转发到 127.0.0.1:3000。Caddy 最省事两行配置自动签证书。但这一步不影响本地跑通先把 3000 端口验证完再上代理。提示不要把 data 和 uploads 挂到容器内其他路径官方镜像固定用 /app/data 和 /app/uploads。路径写错会导致数据写进容器层重启即丢。4. 启动后逐项验证登录、建行程、加成员、分摊、清单容器起来不等于能用这一节给你一份逐项验证清单。我按真实操作顺序走一遍每步都说明预期结果你对照着点。第一步打开 http://你的服务器IP:3000。首次访问会跳注册页。填邮箱、密码注册第一个账号。这个账号通常是管理员。如果页面报错或一直转圈先看 docker compose logs 有没有数据库错误。第二步登录后创建行程。点新建旅行填名称比如“意大利之旅”选日期范围。预期是进入行程详情页左侧有日程右侧有地图。如果地图空白可能是浏览器拦截了瓦片请求换 Chrome 或检查网络。第三步加成员。在行程设置里生成邀请链接可以设一次性或可复用、带过期时间。用另一个浏览器或无痕窗口打开邀请链接注册第二个账号加入。预期是成员列表出现两个人且实时同步——你在 A 窗口改行程B 窗口几秒内更新。这一步验证 WebSocket 协同是否正常。第四步分摊记账。进入费用模块添加一笔支出比如“酒店 2000”选择付款人和参与分摊的人。预期是自动算出谁欠谁多少支持多币种。如果你看不到费用模块可能是管理员在插件里没开启去设置里打开“费用”插件。第五步打包清单。进入清单模块新建分类比如“衣物”添加条目分配给成员勾选完成。预期是进度条随勾选更新成员能看到自己的任务。清单同样依赖插件开关确认“打包清单”已启用。第六步验证数据留在本地。在宿主机执行ls -lh /opt/trek/data ls -lh /opt/trek/uploads你应该能看到 SQLite 数据库文件和上传的附件。再执行 docker compose restart重启后重新登录之前建的行程、成员、账目、清单都还在说明持久化生效。如果你要用 AI 助手通过 MCP 操作 TREK需要在设置里启用 MCP 插件然后用支持 OAuth 2.1 的客户端连接。连接时需要 Base URL、客户端注册和授权确认。TREK 暴露了 150 多个工具和 30 个资源权限范围分得很细建议只授予需要的范围。预置提示词有 trip-summary、packing-list、budget-overview可以直接调用。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节列我遇到和社区里高频的报错给你对照排查。每个都给出真实错误形态和解决方向。401 Unauthorized。多数出现在 MCP 或 API 调用时。先确认你带的令牌没过期OAuth 流程是否走完。如果是自建反向代理检查 Authorization 头有没有被转发。Nginx 默认会转发但有些配置会丢掉。另一个原因是 ENCRYPTION_KEY 变更导致已存令牌解不开这种情况只能重新授权。local proxy failed。这个通常出现在容器内应用尝试访问外部服务时比如地点搜索调用 Google Places。如果你没配 API KeyTREK 会回退到 OpenStreetMap不需要 Key。若仍报错检查服务器 DNS 和出站网络。容器内可以用 docker exec -it trek sh 进去 ping 一下域名。注意不要配置任何不合规的网络访问方式保持服务器正常出站即可。reading choices 类错误。这多出现在 AI 助手调用 MCP 工具时返回结构不符合预期。先确认 TREK 版本和客户端协议版本匹配。然后检查你授予的 OAuth 范围是否包含该工具所需权限。范围不足时工具会返回空或报错。建议在 MCP 设置里逐项确认权限组。OAuth 回调失败。表现是授权后跳回 localhost 或 404。根因是 APP_URL 没设对。OAuth 回调地址基于 APP_URL 生成如果你用 IP 访问但 APP_URL 写的是域名就会不匹配。把 APP_URL 改成你实际访问的地址重启容器再试。如果你用 Claude Code 或 Cline 这类客户端连接 MCP 时需要填 Base URL、Key 和 Model ID 三件套缺一不可。Base URL 指向你的 TREK 实例Key 来自 OAuth 授权Model ID 按客户端要求填。还有一个容易忽略的附件上传失败。检查 uploads 目录权限和磁盘空间。单文件上限 50MB超了会被拒。如果你在反向代理后面还要调大 client_max_body_size否则 Nginx 会先拦掉。注意排查时优先看 docker compose logs -f 的实时日志大部分错误会直接打印堆栈比猜快得多。6. 把 AI 助手接进来MCP 配置与长期使用建议TREK 的差异化在于内置 MCP 服务器让 AI 助手能直接操作你的旅行数据。这一节说清楚怎么接以及长期用下去要注意什么。先在 TREK 设置里启用 MCP 插件。然后在你常用的 AI 编程助手里添加 MCP 服务器。以支持 OAuth 2.1 的客户端为例你需要填服务器地址指向你的 TREK 实例的 MCP 端点。授权时会跳转到 TREK 登录页确认后拿到令牌。权限范围有 27 个 OAuth 范围、13 个权限组建议按需勾选比如只给行程和清单权限不给预算写权限。连接成功后你可以用自然语言让它干活。比如“帮我规划一个 7 天的意大利之旅从罗马开始”它会调用创建行程和添加日程的工具。再比如“为这次旅行生成打包清单意大利夏天”它会调用清单工具并按模板生成。预算概览也有对应提示词。如果你要长期跑几个建议。第一定期备份 /opt/trek最好用 cron 每天打包一次保留最近 7 天。第二ENCRYPTION_KEY 单独存一份在密码管理器里别只放在服务器上。第三反向代理上 HTTPS因为 PWA 安装和 OAuth 都要求安全上下文。第四关注镜像更新docker compose pull 后重建即可数据卷不受影响。关于 AI 助手的接入如果你需要稳定的模型调用和密钥管理可以用 TaoToken 的 API 服务来统一管理。它的 API 地址是 https://taotoken.net/api你可以在控制台创建密钥然后在 AI 助手里配置 Base URL 和 Key。模型对话入口在 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteCoding Plan 适合长期编码和 Agent 场景地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite。密钥管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite。Claude Code 相关配置可以参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite。最后回到 TREK 本身。它把旅行规划从五六个 App 收拢到一个自托管平台数据在你自己的服务器上实时协同和 MCP 让家人和 AI 都能参与。你按上面的 compose 配置跑起来逐项验证完就可以把下一次出行的所有信息放进去。旅行结束后导出 PDF它就成了完整的回忆册。