1. 什么是 wrangler.toml
backend/wrangler.toml 是 Worker 项目的部署配置文件,相当于 Cloudflare 的“项目清单”。
当前项目示例:
name = "sitebox-backend"
main = "server.mjs"
compatibility_date = "2024-01-01"
compatibility_flags = ["nodejs_compat"]
[[d1_databases]]
binding = "DB"
database_name = "sitebox"
database_id = "148bb43e-fb40-4dc5-94e0-f2e689194b4b"
[vars]
DEPLOY_MODE = "cloudflare"
GITHUB_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxx"
GITHUB_REPO="xxxxxx/yyyyyyyy"
GITHUB_PATH="backup_json/backup.json"
各字段含义:
name:Worker 服务名(最终会生成可用地址<name>.<subdomain>.workers.dev)main:入口文件(本项目是server.mjs,ES Module)compatibility_date:Cloudflare 运行时兼容日期compatibility_flags:运行时特性开关(这里启用nodejs_compat)[[d1_databases]]:D1 数据库绑定binding = "DB"表示代码里通过env.DB访问数据库database_id指向具体 D1 数据库
[vars]:普通环境变量(非敏感)
注意:
database_id通常是资源标识,不是密钥;真正敏感的是 API Token / Secret。
2. 使用 Wrangler CLI 部署(推荐)
适用于当前这套 SiteBox 后端,最稳妥。
2.1. 前提
- Node.js >= 18
- Cloudflare 账户
- 已在
backend/中准备好wrangler.toml
2.2. 部署步骤
cd SiteBox/backend
npm install
npx wrangler login
npm run deploy:cf
部署成功后会输出 Worker 地址,如:
https://sitebox-backend.xxx.workers.dev
2.3. D1 初始化(非常关键)
本项目有 schema.sql,必须导入到远程 D1 才能正常使用。
# 本地模拟库(开发调试)
npm run db:migrate:local
# 远程生产库(正式环境)
npx wrangler d1 execute sitebox --remote --file=./schema.sql
易错点:
npm run db:migrate在很多场景默认是本地库,不等于线上库。生产务必带--remote。
2.4. 验证
curl https://<your-worker-domain>/api/
预期返回:
Backend service is running
3. 网页端部署后端到 Cloudflare(不使用本地 CLI)
可以做到,但步骤更繁琐,适合不想在本地装 Wrangler 的场景。 Dashboard连接Git仓库自动部署(推荐的网页端方式)
3.1. “自动部署页”这样填
下面给两种写法,二选一(推荐 A)
3.1.1. 路径填 /backend(推荐)
项目名称:
sitebox-backend(与构建命令中的-name参数保持一直,与.toml文件中的name字段值保持一致)构建命令:留空
部署命令:
npm install && npx wrangler deploy server.mjs --name sitebox-backend --compatibility-date=2024-01-01非生产分支构建:先关掉(稳定后再开)
高级设置 → 路径:
/backendAPI 令牌:创建新的或者注入
CLOUDFLARE_API_TOKEN使用已经存在的token- 令牌权限建议至少包含:
- Workers Scripts: Edit
- D1: Edit
- Account: Read
3.1.2. 路径填 /(仓库根)
项目名称:
sitebox-backend构建命令:留空
部署命令:
npm --prefix backend install && npx wrangler deploy backend/server.mjs --name sitebox-backend --compatibility-date=2024-01-01高级设置 → 路径:
/API 令牌:同上
3.2. Cloudflare Dashboard 里手动补配置
部署命令只负责上传代码,D1 绑定/变量 在 Cloudflare 控制台补齐:
- 打开 Cloudflare Dashboard
- 进 Workers & Pages → 选你的 Worker(
sitebox-backend) - Settings → Variables
- 新增:
- 名称:
DEPLOY_MODE - 值:
cloudflare(不填这个值无法区分是是不是部署在cf平台) - 名称:
GITHUB_TOKEN - 值:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - 名称:
GITHUB_REPO - 值:
xxxxx/yyyyy - 名称:
GITHUB_PATH - 值:
backup_json/backup.json
- 名称:
- 新增:
- Settings → Bindings
- 新增 D1 绑定:
- Binding 名:
DB - 选择数据库:
sitebox(如果没有,需要手动去数据库里创建一个D1)
- Binding 名:
- 新增 D1 绑定:
- Settings → Runtime / Compatibility(不同界面名字略有差异)
- Compatibility date:
2024-01-01 - Compatibility flags:
nodejs_compat
- Compatibility date:
3.3. 初始化数据库(必须)
即使部署成功,没建表也会出问题。
去 D1 控制台 选 sitebox 数据库,执行 backend/schema.sql 的 SQL(也就是复制文件内容,添加到查询,进行一次执行,就会生成多张表)。
🚨 重要说明:
⚠️ 如果没有toml文件,即便绑定了数据库或者绑定了上面的变量,下次自动部署的时候这个绑定也会失效 📢 建议在仓库中保存一个toml文件,修改自己对应的db名字和id 📌 如果有toml文件,即便不手动补配置也能正常运行
3.4. 验证
打开:
https://<你的worker域名>/api/预期:
Backend service is running直接访问这两个接口验证:
预期要返回 JSON(success/data),不能再报 prepare 错误。
4. 开发环境部署
4.1. 适用场景
自有 Linux 服务器,不使用 Docker,直接运行 Node.js 进程。
4.2. 前提条件
- Node.js >= 18
- npm >= 8
- 推荐使用 PM2 管理进程
4.3. 部署步骤
# 1. 克隆代码
git clone <your-repo-url> sitebox
cd sitebox/SiteBox/backend
# 2. 安装依赖
npm install --omit=dev
# 3a. 直接启动(测试用,使用代码中默认回落的值)
node server.node.js
# 或者需要改变环境端口等信息值的话
cp .env.example .env
nano .env
node --env-file=.env server.node.js
#推荐使用 PM2:
# 3b. 使用 PM2 后台运行(推荐生产环境)
npm install -g pm2
cp .env.example .env
nano .env
pm2 start server.node.js --node-args="--env-file=.env" --name sitebox-backend
pm2 save
pm2 startup # 设置开机自启
4.4. 环境变量配置
.env 配置示例:
PORT=3000
DB_PATH=/var/data/sitebox/db/sitebox.db
DEPLOY_MODE=docker
GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
GITHUB_REPO=xxxxxx/yyyyyyyy
GITHUB_PATH=backup_json/backup.json
5. 容器部署
5.1. Dockerfile
# 建议使用 20 版本,性能更好且支持更多原生特性
FROM node:18-alpine
# FROM node:20-alpine
# 因为 better-sqlite3 是原生模块,在 Alpine 上安装可能需要这些构建工具
# 安装完后删除缓存以减小镜像体积
# RUN apk add --no-cache python3 make g++
WORKDIR /app
# 先拷贝 package 文件安装依赖,利用 Docker 缓存层
COPY package*.json ./
# 只安装生产环境依赖
RUN npm install --omit=dev
# 复制所有源代码
COPY . .
# 设置默认环境变量
ENV PORT=3000
ENV DEPLOY_MODE=docker
# 数据库路径:建议放在绝对路径,方便 PVE 挂载
ENV DB_PATH=/app/data/db/sitebox.db
# 用于将数据同步到 GitHub 仓库
# 1. 创建一个 GitHub Personal Access Token (Classic),并授予 repo 权限
# 2. 填入 Token (ghp_...)
# 3. 填入目标仓库,格式:owner/repo (例如:yourname/sitebox-data)
# 4. 填入文件路径,例如:data/backup.json
ENV GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
ENV GITHUB_REPO=xxxxxx/yyyyyyyy
ENV GITHUB_PATH=backup_json/backup.json
# 声明端口
EXPOSE $PORT
# 启动命令
# 1. 确保你的 server.node.js 里没有我们之前说的 import/export 混用错误
# 2. 生产环境直接运行,无需 --env-file(由 ENV 指令提供变量)
CMD ["node", "server.node.js"]
说明:
server.node.js文件里的已经写死了模式,非cf模式下是固定的ENV DEPLOY_MODE=docker这个值的设置就是一个可选项
const nodeEnv = {
DB: db,
DEPLOY_MODE: 'docker',
};
- 同样的,代码中也提供了回退值进行保底,
ENV PORT=3000这个值的设置就是一个可选项
const PORT = process.env.PORT || 3000;
- 同样的,代码中也提供了回退值进行保底,
ENV DB_PATH=/app/data/db/sitebox.db这个值的设置就是一个可选项
const DB_PATH = process.env.DB_PATH || path.join(__dirname, 'data', 'sitebox.db');
5.2. docker-compose
🚀 远程镜像模式 (docker-compose.yml)
拉去远端镜像,直接运行
version: '3.8'
services:
sitebox-backend:
# 具体镜像名字需要检查确认
image: sitebox-backend:latest
# 如果你想边改代码边看效果,可以使用 build 模式
# build: .
container_name: sitebox-backend
restart: always
ports:
- "3000:3000"
environment:
- PORT=3000
# DEPLOY_MODE可以不设置
- DEPLOY_MODE=docker
# 对应 Dockerfile 里的 ENV,确保路径一致
- DB_PATH=/app/data/db/sitebox.db
# 如果要同步到github这下面三个参数是必填项
- GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
- GITHUB_REPO=xxxxxx/yyyyyyyy
- GITHUB_PATH=backup_json/backup.json
volumes:
# 将宿主机的 data/db 文件夹挂载到容器的 /app/data/db
# 这样 sitebox.db 就会保存在宿主机的 ./data/db 目录下
- /opt/sitebox/data/db:/app/data/db
- /opt/sitebox/data/icons:/app/data/icons
# 限制日志大小,防止挤爆硬盘,可以不写
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
运行命令:
# 启动
docker-compose up -d
# 查看日志
docker-compose logs -f
🛠️ 本地构建模式 (docker-compose.build.yml)
从仓库克隆代码到本地,然后直接构建镜像运行
version: '3.8'
services:
sitebox-be:
build:
context: ./backend # 假设源码就在当前目录的backend目录下
dockerfile: Dockerfile
container_name: sitebox-backend
restart: always
ports:
- "3000:3000"
environment:
- PORT=3000
- DB_PATH=/app/data/db/sitebox.db
- DEPLOY_MODE=docker
# 如果要同步到github这下面三个参数是必填项
- GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
- GITHUB_REPO=xxxxxx/yyyyyyyy
- GITHUB_PATH=backup_json/backup.json
volumes:
- /opt/sitebox/data/db:/app/data/db
- /opt/sitebox/data/icons:/app/data/icons
运行命令:
# 启动
docker-compose -f docker-compose.build.yml up -d --build
# 查看日志
docker-compose logs -f
5.3. docker命令
docker run -d \
--name sitebox-backend \
-p 3000:3000 \
-e PORT=3000 \
-e DEPLOY_MODE=docker \
-e DB_PATH=/app/data/db/sitebox.db \
-v $(pwd)/data/db:/app/data/db \
--restart unless-stopped \
sitebox-backend:latest
参数解释:
- -d: 后台运行。
- -p 3000:3000: 宿主机端口映射。
- -e: 设置环境变量(会覆盖 Dockerfile 里的默认值)。
- -v $(pwd)/data/db:/app/data/db: 极其重要,把当前目录下的
data/db文件夹映射进去,实现 SQLite 数据库持久化。
5.4. PVE 9.1 LXC (OCI 容器) 部署指令
PVE 9.1 LXC (OCI 容器) 部署指令 在 PVE 9.1 中部署时,除了界面操作,可能需要用到以下命令来正确挂载数据库:
- 第一步:创建 LXC 容器(通过 PVE 界面或命令) 在 PVE 界面选择下载 Docker Hub 镜像并创建容器。
- 第二步:配置持久化挂载(关键!)
由于
better-sqlite3需要频繁读写文件,建议把宿主机的目录挂载给 LXC。假设你的数据存在 PVE 宿主机的/mnt/pve/app/sitebox-data/:
# 假设你的 LXC 容器 ID 是 106
# 将宿主机目录挂载到容器内的 /app/data/db
pct set 106 -mp0 /mnt/pve/app/sitebox-data/db/,mp=/app/data/db/
- 第三步:设置环境变量(一般情况下其实可以在lxc选项里看到这6个变量了) 在 PVE 界面 -> 容器 106 -> 选项 -> 环境变量,添加:
PORT = 3000DB_PATH = /app/data/db/sitebox.dbDEPLOY_MODE = dockerGITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxGITHUB_REPO=xxxxxx/yyyyyyyyGITHUB_PATH=backup_json/backup.json
5.5. ⚠️ 最后的避坑指南(SQLite 特有)
文件夹权限:
better-sqlite3 需要在 /app/data/db 目录下创建和写入文件。如果启动时报错 SQLITE_CANTOPEN 或 Permission denied,在 PVE 宿主机上执行:
# 给挂载目录足够的权限
chmod -R 777 /mnt/pve/app/sitebox-data/
# 或者将其所有者改为容器内用户
chown -R 100000:100000 /mnt/pve/app/sitebox-data/
WAL 模式:
代码里开启了 db.pragma('journal_mode = WAL')。这会产生 .db-wal 和 .db-shm 临时文件。
千万不要只挂载单独的.db文件。
必须挂载整个目录(即 /app/data/db),否则 WAL 模式会导致数据库损坏或启动失败。
自定义网站图标静态缓存设置
- 为了支持网站图标使用自定义相对路径
/data/icons/xxxx.ico - 除了挂载
/app/data/db之外,可以同时挂载/app/data/icons
6. 常见问题
6.1. Q1:为什么提示 D1 绑定要求 ES Module?
A:因为使用 D1 时,Worker 需要 ES Module 入口。当前项目已使用 server.mjs。
6.2. Q2:前端能访问后端但数据为空?
A:大概率远程 D1 未导入 schema.sql,只初始化了本地模拟库。
6.3. Q3:Cloudflare 模式下 Docker 实时接口报错?
A:这是平台能力限制,Cloudflare 运行环境不能直接访问你的宿主机 Docker daemon。
6.4. Q4:需要把 wrangler.toml 放在仓库吗?
A:建议放。它是部署可复现配置。不要把 token / secret 写进去即可。
7. 给前端填写后端地址的建议
前端“后端地址设置”应填写:
https://<你的后端域名>
不要填写:
https://<你的后端域名>/api(会重复拼接)- 不确定开放的端口(如误填
:3000)
系统会自动拼接 /api。