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
    
  • 非生产分支构建:先关掉(稳定后再开)

  • 高级设置 → 路径/backend

  • API 令牌:创建新的或者注入 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 控制台补齐:

  1. 打开 Cloudflare Dashboard
  2. Workers & Pages → 选你的 Worker(sitebox-backend
  3. Settings → Variables
    • 新增:
      • 名称:DEPLOY_MODE
      • 值:cloudflare(不填这个值无法区分是是不是部署在cf平台)
      • 名称:GITHUB_TOKEN
      • 值:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      • 名称:GITHUB_REPO
      • 值:xxxxx/yyyyy
      • 名称:GITHUB_PATH
      • 值:backup_json/backup.json
  4. Settings → Bindings
    • 新增 D1 绑定:
      • Binding 名:DB
      • 选择数据库:sitebox(如果没有,需要手动去数据库里创建一个D1)
  5. Settings → Runtime / Compatibility(不同界面名字略有差异)
    • Compatibility date:2024-01-01
    • Compatibility flags:nodejs_compat

3.3. 初始化数据库(必须)

即使部署成功,没建表也会出问题。 去 D1 控制台sitebox 数据库,执行 backend/schema.sql 的 SQL(也就是复制文件内容,添加到查询,进行一次执行,就会生成多张表)。

🚨 重要说明:

⚠️ 如果没有toml文件,即便绑定了数据库或者绑定了上面的变量,下次自动部署的时候这个绑定也会失效 📢 建议在仓库中保存一个toml文件,修改自己对应的db名字和id 📌 如果有toml文件,即便不手动补配置也能正常运行


3.4. 验证


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 = 3000
  • DB_PATH = /app/data/db/sitebox.db
  • DEPLOY_MODE = docker
  • GITHUB_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
  • GITHUB_REPO=xxxxxx/yyyyyyyy
  • GITHUB_PATH=backup_json/backup.json

5.5. ⚠️ 最后的避坑指南(SQLite 特有)

文件夹权限better-sqlite3 需要在 /app/data/db 目录下创建和写入文件。如果启动时报错 SQLITE_CANTOPENPermission 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