KKCE:免备案VPS、把它做成“按 PR 生灭的预览沙盒”网站测速、400+在线节点

简介: 本文介绍一种基于免备案境外VPS的PR预览方案:通过Docker Compose + Traefik + 通配DNS,实现每个PR自动创建带Basic Auth、noindex、独立数据库的临时环境,合并即销毁,兼顾效率、安全与合规。(239字)

团队写代码最费时间的不是写,是“等别人本地起环境看效果”。

staging 环境只有一个,分支一多就排队;本地 docker-compose up 又每个人机器不一样。

免备案VPS 在这里的价值不是“建站快”,而是:不用等备案、不用申请内网权限,开一台境外小机就能给每个 PR 发一个临时预览 URL。

本文给一套 Docker Compose + Traefik + 通配 DNS 的极简方案:PR 打开自动起栈、推代码热更新、合并/关闭自动销毁,顺手把合规边界(不存 PII、不公开收录、不面向境内公众服务)讲清。

一、先定边界:预览环境“能放什么”

免备案只解决“不用等 ICP 备案”,不解决内容合规和数据合规。

预览沙盒原则:

  • 只跑分支代码,不接生产库(用独立预览库/假数据)
  • 不存真实用户 PII(手机号/订单/支付用 mock)
  • 预览域名加 Basic Auth 或 SSO,禁止搜索引擎收录
  • 面向内部评审(开发/产品/测试),不面向公众推广
  • 合并即删,磁盘不长期留分支残渣

它是一张“临时工单”,不是“线上站点”。

二、整体架构

text

开发者推 PR
   │ Webhook / CI
   ▼
CI 构建镜像 → 推私有 Registry
   │ SSH 到免备案VPS
   ▼
docker compose -p pr-184 up -d
   ├─ api (独立容器)
   ├─ worker (可选)
   ├─ postgres (独立库+独立 volume)
   └─ Traefik 标签路由:pr-184.preview.example.com
        │
        ▼
评审员访问 https://pr-184.preview.example.com (Basic Auth)

固定常驻组件:

  • Traefik(唯一监听 80/443,自动签发通配证书)
  • 清理定时器(cron / systemd timer)

不固定组件:

  • 每个 PR 一个 Compose 项目,独立网络、独立卷

三、基础设施:一台 2C4G 香港/新加坡 VPS 起步

系统:Ubuntu 24.04 / Debian 12

bash

# 创建部署用户
adduser deploy
usermod -aG docker,sudo deploy
# 装 Docker
apt-get install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install -y docker-ce docker-compose-plugin

DNS 只配两条:

text

A    preview.example.com         → VPS_IP
CNAME *.preview.example.com      → preview.example.com

四、Traefik 常驻边缘(自动路由+证书)

/opt/edge/docker-compose.yml:

yaml

services:
  traefik:
    image: traefik:v3.3
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.letsencrypt.acme.dnschallenge=true
      - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare
      - --certificatesresolvers.letsencrypt.acme.email=ops@example.com
      - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
    environment:
      CF_DNS_API_TOKEN: ${CF_TOKEN}
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    networks:
      - traefik-public
networks:
  traefik-public:
    name: traefik-public

五、每个 PR 的 Compose 栈

CI 里生成临时 compose 文件(用 PR 号做 project 名):

yaml

# pr-184/docker-compose.yml
services:
  api:
    image: registry.example.com/app/api:pr-184
    labels:
      - traefik.enable=true
      - traefik.http.routers.api-pr184.rule=Host(`pr-184.preview.example.com`)
      - traefik.http.routers.api-pr184.entrypoints=websecure
      - traefik.http.routers.api-pr184.tls.certresolver=letsencrypt
      - traefik.http.middlewares.pr184-auth.basicauth.users=${BASIC_AUTH}
    environment:
      DATABASE_URL: postgres://preview:preview@db:5432/pr184
      NODE_ENV: preview
    networks:
      - traefik-public
      - pr184
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: preview
      POSTGRES_PASSWORD: preview
      POSTGRES_DB: pr184
    volumes:
      - pr184_pg:/var/lib/postgresql/data
    networks:
      - pr184
networks:
  traefik-public:
    external: true
  pr184:
    name: pr184
volumes:
  pr184_pg:

部署脚本(CI 里跑):

bash

ssh deploy@vps "
  mkdir -p /opt/previews/pr-184
  cat > /opt/previews/pr-184/docker-compose.yml <<'EOF'
  $(cat pr-184/docker-compose.yml)
EOF
  cd /opt/previews/pr-184
  docker compose -p pr-184 up -d
"

PR 评论自动回链:

bash

echo "预览环境已就绪:https://pr-184.preview.example.com" | gh pr comment 184 --body-file -

六、热更新:别每次重建库

  • 代码层:CI 重新 build 镜像 → docker compose -p pr-184 up -d 只换 api 容器
  • 数据库层:volume 保留,迁移脚本跑幂等 prisma db push / alembic upgrade
  • 依赖层:镜像构建走 Registry 缓存,别在 VPS 上现场 npm install

yaml

# 中间件加安全头
- traefik.http.middlewares.pr184-sec.headers.customresponseheaders.X-Robots-Tag=noindex,nofollow

Nginx 里再补一层:

nginx

add_header X-Robots-Tag "noindex, nofollow" always;

七、自动销毁:合并即消失

cleanup.sh:

bash

#!/bin/bash
for d in /opt/previews/*/; do
  pr=$(basename "$d")
  # 查 PR 状态(GitHub CLI)
  state=$(gh pr view "${pr#pr-}" --json state -q .state 2>/dev/null)
  if [ "$state" = "MERGED" ] || [ "$state" = "CLOSED" ]; then
    docker compose -p "$pr" down -v
    rm -rf "$d"
    echo "$(date) destroyed $pr"
  fi
done

systemd timer 每小时跑:

ini

[Timer]
OnCalendar=hourly
Persistent=true

再加 TTL 兜底(防 CI 挂了没清理):

bash

# 创建时写元数据
echo '{"pr":184,"expire":"2026-11-02T00:00:00Z"}' > /opt/previews/pr-184/meta.json
# 清理脚本顺手看 expire

八、安全:预览环境最怕“被扫到”

  • 通配域名不挂官网,不提交 sitemap
  • Traefik 全局中间件:Basic Auth / Authelia 二选一
  • 预览库用独立低权账号,禁止访问生产连接串
  • Secret 不进预览容器:用 mock 配置,真实密钥只生产环境注入
  • VPS 防火墙:只开 80/443,SSH 限 IP+密钥
  • 日志脱敏:不打印用户 token、不存请求 body 全文

bash

ufw default deny incoming
ufw allow 80,443/tcp
ufw allow from 办公IP to any port 22222
ufw enable

九、资源隔离:别让一个 PR 拖垮全机

每个 project 加资源配额:

yaml

services:
  api:
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M

清理脚本顺手报:

  • 内存压力
  • 磁盘 inode
  • 僵尸 volume(docker volume ls 里没容器引用的删掉)

bash

docker system prune -f --filter "until=24h"

十、合规边界(必须写进 README)

  • 免备案 ≠ 免内容责任:预览站也不放违规内容
  • 不接真实用户数据:用脱敏样本 / faker 生成
  • 涉及境内用户信息的代码逻辑:预览环境只跑假数据,不真出网
  • 隐私政策:预览域返回 noindex,不收集真实访客 PII
  • 数据跨境:预览库不长期留存,合并即清

十一、最小落地清单

  • [ ] VPS 装 Docker + Traefik 常驻
  • [ ] 通配 DNS + 自动证书
  • [ ] CI 按 PR 号生成 compose,独立网络/卷
  • [ ] 预览域 Basic Auth + noindex
  • [ ] 合并/关闭 Webhook 触发销毁
  • [ ] 每小时清理 + TTL 兜底
  • [ ] 资源配额 + 日志脱敏
  • [ ] 不接生产库、不存真实 PII

十二、什么别用预览沙盒干

  • 跑生产流量灰度(用正规灰度发布)
  • 放真实支付回调(用 mock 网关)
  • 长期留分支环境(超 72h 自动删)
  • 把密钥写进镜像层
  • 让搜索引擎抓预览域

十三、总结

免备案VPS 在研发流里最被低估的用法,不是“先开个站”,而是:

让每个 PR 自己长出一个临时世界,合并完再消失。

代码评审从“看 diff”变成“点链接看效果”;

产品不用等 staging;

测试不用本地配环境;

资源不常驻,成本按 PR 生命周期计费。

备案不用等、环境不抢用、合并即归还。

一台小规格境外 VPS,

跑的不是服务,是“可销毁的确定感”。

目录
相关文章
|
云安全 安全 网络安全
|
2天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
|
16天前
|
JSON 程序员 数据格式
最新版Notepad++下载、安装、配置保姆级教程(附官网安装包)
Notepad++ 是一款免费开源、轻量快速的 Windows 文本编辑器,支持多标签、语法高亮、代码折叠与宏录制,体积小、启动快、资源占用低,兼容 x64/x32/ARM 架构,是程序员和文字工作者的高效利器。
3937 1
|
9天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2058 2
|
15天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
2601 46
|
3天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
504 1
|
12天前
|
Web App开发 人工智能 前端开发
2026 年 AI 浏览器怎么选?Ego Lite、Tabbit、Chrome DevTools MCP 深度对比,开发者到底该用哪个?
2026年AI浏览器选型指南:Ego Lite专注多Agent协同(Mac优先),Tabbit国产首选,原生支持Windows与Codex控制;Chrome DevTools MCP非浏览器而是开发者利器,深度集成Console/Network/Performance调试能力,让AI真正“看懂并验证”前端代码。
1501 3
|
9天前
|
开发者 索引
DeepSeekHarness大肥鱼自带插件市场了?加个地址就能用
Open Plugin Market 是一个开放插件索引平台,收录800+优质DSH插件,支持分类浏览、智能推荐与随机发现。无需安装市场,粘贴索引地址即可一键接入,网页版直访 dshopen.org,助力小开发者被看见。(239字)
2066 1
DeepSeekHarness大肥鱼自带插件市场了?加个地址就能用
|
8天前
|
人工智能 Linux API
Magpie, 轻量本地AI网关!免费Token用不完!
Magpie 是开源AI编程模型调度网关,上线一月获1.8万Star。它通过本地高性能网关统一托管多平台API密钥、账号与免费额度,实现跨Agent的模型秒级切换、静默额度轮换与资源复用,显著降低碎片化管理成本。(239字)
Magpie, 轻量本地AI网关!免费Token用不完!

热门文章

最新文章