<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh_CN">
  <title>辰亦blog</title>
  <subtitle>辰亦blog</subtitle>
  <link href="https://blog.ifyi.top/" rel="alternate" type="text/html"/>
  <link href="https://blog.ifyi.top/atom.xml" rel="self" type="application/atom+xml"/>
  <id>https://blog.ifyi.top/</id>
  <updated>2026-11-09T00:00:00.000Z</updated>
  <entry>
    <title>用 EdgeOne Makers 部署一套 Bitwarden 兼容密码库</title>
    <link href="https://blog.ifyi.top/posts/edgeone-deploy-warden/" rel="alternate" type="text/html"/>
    <id>https://blog.ifyi.top/posts/edgeone-deploy-warden/</id>
    <published>2026-11-09T00:00:00.000Z</published>
    <updated>2026-11-09T00:00:00.000Z</updated>
    <summary>构建原理、环境变量与完整部署步骤。</summary>
    <content type="html"><![CDATA[<h2>一、这个项目是什么</h2>
<p>::github{repo="chenyimaio/warden-worker"}
<code>warden-worker</code> 是一个 <strong>Bitwarden 兼容服务端</strong>（协议与 Vaultwarden 对齐）</p>
<p>能做的事：</p>
<table>
<thead>
<tr>
<th>能力</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>注册 / 登录 / 刷新令牌</td>
<td>✅</td>
</tr>
<tr>
<td>条目、文件夹、收藏、软删除与恢复</td>
<td>✅</td>
</tr>
<tr>
<td>文本 Send / 文件 Send</td>
<td>✅（文件 ≤ 6 MB）</td>
</tr>
<tr>
<td>附件上传下载</td>
<td>✅（≤ 6 MB）</td>
</tr>
<tr>
<td>TOTP</td>
<td>✅</td>
</tr>
<tr>
<td>主密码提示邮件</td>
<td>✅（可选 SMTP）</td>
</tr>
<tr>
<td>网页版 Web Vault</td>
<td>✅</td>
</tr>
<tr>
<td>WebSocket 实时推送</td>
<td>❌（返回 426，客户端自动降级为轮询）</td>
</tr>
<tr>
<td>组织 / 集合 / SSO / 通行密钥</td>
<td>❌（未实现）</td>
</tr>
</tbody>
</table>
<p>架构大致是这样：</p>
<pre><code>浏览器 / 手机客户端
        │  HTTPS
        ▼
   EdgeOne 静态层 ── 命中 public/ 里的文件就直接返回
        │  未命中
        ▼
  Cloud Function (Node 20.19)
        │
        ├── @edgeone/pages-blob  ──►  Blob 存储（单对象 ≤ 25 MB）
        └── SMTP（可选）        ──►  邮件服务商
</code></pre>
<hr />
<h2>二、部署前需要准备什么</h2>
<ol>
<li><strong>一个 EdgeOne 账号</strong>，并开通 Makers（Pages）能力</li>
<li><strong>一个域名</strong>（Makers 会分配测试域名，但密码库建议绑自己的）</li>
<li><strong>仓库访问权限</strong>：Fork 该仓库</li>
</ol>
<hr />
<h2>三、三种部署方式</h2>
<h3>方式 A：一键部署（最快）</h3>
<p>点击下面任一按钮，EdgeOne 会引导你填入环境变量，选离你近的那个站点即可：</p>
<p><a href="https://console.cloud.tencent.com/edgeone/pages/new?project-name=warden-edgeone&amp;repository-url=https%3A%2F%2Fgithub.com%2Fchenyimaio%2Fwarden-worker%2Ftree%2Fedgeone&amp;root-directory=edgeone&amp;install-command=npm%20ci&amp;build-command=npm%20run%20build&amp;env=BASE_URL%2CALLOWED_EMAILS%2CJWT_SECRET"><img src="https://cdnstatic.tencentcs.com/edgeone/pages/deploy.svg" alt="使用 EdgeOne Makers 部署（国内站）" /></a> <a href="https://edgeone.ai/pages/new?repository-url=https%3A%2F%2Fgithub.com%2Fchenyimaio%2Fwarden-worker%2Ftree%2Fedgeone&amp;root-directory=edgeone&amp;install-command=npm%20ci&amp;env=BASE_URL%2CALLOWED_EMAILS%2CJWT_SECRET"><img src="https://cdnstatic.tencentcs.com/edgeone/pages/deploy.svg" alt="使用 EdgeOne Makers 部署（国际站）" /></a></p>
<p><em>左：国内站 console.cloud.tencent.com　·　右：国际站 edgeone.ai</em></p>
<h3>方式 B：从 Git 导入（推荐）</h3>
<ol>
<li>
<p>打开 EdgeOne 控制台 → <strong>Pages / Makers</strong> → <strong>新建项目 → 导入 Git 仓库</strong></p>
</li>
<li>
<p>选择你的仓库和分支（移植版在 <code>edgeone</code> 分支）</p>
</li>
<li>
<p><strong>关键：项目根目录填 <code>edgeone</code></strong>，不是仓库根</p>
</li>
<li>
<p>构建配置一般会被 <code>edgeone/edgeone.json</code> 自动识别：</p>
<pre><code>{
  "installCommand": "npm ci --include=dev",
  "buildCommand": "OUT=cloud-functions/[[default]].js npm run build &amp;&amp; node scripts/fetch-web-vault.mjs &amp;&amp; node scripts/sync-handler.mjs",
  "outputDirectory": "public",
  "nodeVersion": "20.18.0",
  "cloudFunctions": { "maxDuration": 60 }
}
</code></pre>
</li>
<li>
<p>填环境变量（见第四节），点部署</p>
</li>
</ol>
<h3>方式 C：命令行上传</h3>
<p>适合调试，但每次都要手工同步产物，长期不如 Git 导入。</p>
<hr />
<h2>四、环境变量</h2>
<h3>4.1 必填（3 个）</h3>
<table>
<thead>
<tr>
<th>变量</th>
<th>说明</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>BASE_URL</code></td>
<td>对外访问地址，影响邮件链接和客户端配置</td>
<td><code>https://vault.example.com</code></td>
</tr>
<tr>
<td><code>ALLOWED_EMAILS</code></td>
<td>允许注册的邮箱，glob 写法，逗号分隔；<strong>留空 = 禁止任何人注册</strong></td>
<td><code>me@example.com</code> 或 <code>*@example.com</code> <code>*@example.com,me@example.com</code></td>
</tr>
<tr>
<td><code>JWT_SECRET</code></td>
<td>令牌签名密钥，<strong>至少 32 位随机串</strong></td>
<td>见下方生成命令</td>
</tr>
</tbody>
</table>
<p>生成密钥：</p>
<pre><code>node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))"
</code></pre>
<h3>4.2 存储</h3>
<table>
<thead>
<tr>
<th>变量</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>STORE_DRIVER</code></td>
<td>存储驱动，<strong>留空即 <code>blob</code></strong>；只有本地调试才需要写 <code>memory</code>（<code>npm run dev</code> 会自动使用）</td>
</tr>
<tr>
<td><code>BLOB_STORE</code></td>
<td>Blob 命名空间名，默认 <code>warden</code>。<strong>改名等于换了一个空桶</strong></td>
</tr>
<tr>
<td><code>BLOB_PROJECT_ID</code> / <code>BLOB_TOKEN</code></td>
<td>仅外部脚本 / CI 使用；函数内部会自动鉴权</td>
</tr>
</tbody>
</table>
<h3>4.3 可选开关</h3>
<table>
<thead>
<tr>
<th>变量</th>
<th>默认</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>PASSWORD_ITERATIONS</code></td>
<td><code>600000</code></td>
<td>服务端二次哈希迭代数（<strong>不是</strong>用户 KDF），只影响新写入的记录</td>
</tr>
<tr>
<td><code>UPLOAD_MAX_BYTES</code></td>
<td><code>6291456</code></td>
<td>单次上传上限，默认 6 MiB</td>
</tr>
<tr>
<td><code>ALLOW_TOTP_DRIFT</code></td>
<td><code>true</code></td>
<td>允许 TOTP ±1 个时间步</td>
</tr>
</tbody>
</table>
<blockquote>
<p><code>JWT_REFRESH_SECRET</code> 留空时服务端用 <code>HMAC-SHA256(JWT_SECRET, "warden/v1/refresh-token-signing-key")</code> 派生一个独立的刷新令牌密钥；两种令牌不能互相冒用。只有需要单独轮换刷新令牌密钥时才显式配置它。</p>
</blockquote>
<h3>4.4 网页版（构建期生效）</h3>
<table>
<thead>
<tr>
<th>变量</th>
<th>默认</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>WEB_VAULT_ENABLED</code></td>
<td><code>true</code></td>
<td><code>false</code> 则构建时跳过下载，产物体积从 ~80 MB 降到接近 0 为false时send等需要webui的功能不可使用</td>
</tr>
<tr>
<td><code>WEB_VAULT_VERSION</code></td>
<td><code>v2026.10.1</code></td>
<td>固定的 Web Vault 版本</td>
</tr>
<tr>
<td><code>WEB_VAULT_BASE_URL</code></td>
<td>GitHub Releases</td>
<td>换镜像源用（国内构建机拉不动 GitHub 时）</td>
</tr>
</tbody>
</table>
<h3>4.5 邮件（全部可选）</h3>
<p>不配 <code>SMTP_HOST</code> + <code>MAIL_FROM</code> 就不发信：主密码提示接口照样返回 200，只是跳过发送。</p>
<pre><code>SMTP_HOST=smtp.example.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=no-reply@example.com
SMTP_PASS=********
MAIL_FROM=no-reply@example.com
MAIL_FROM_NAME=Vaultwarden      # 可选，默认 Vaultwarden
MAIL_DRY_RUN=false              # 可选，true = 只打日志不发信
</code></pre>
<h3>4.6 本地开发</h3>
<pre><code>PORT=8787
</code></pre>
]]></content>
    <author><name>辰亦</name></author>
    <category term="部署"/>
  </entry>
  <entry>
    <title>第一篇博客喵</title>
    <link href="https://blog.ifyi.top/posts/text/" rel="alternate" type="text/html"/>
    <id>https://blog.ifyi.top/posts/text/</id>
    <published>2025-12-15T00:00:00.000Z</published>
    <updated>2025-12-15T00:00:00.000Z</updated>
    <summary>one blog.</summary>
    <content type="html"><![CDATA[<h1>2025-12-15</h1>
]]></content>
    <author><name>辰亦</name></author>
    <category term="辰亦"/>
  </entry>
</feed>
