Duplicati 作为一款开源的加密备份软件,能够把本地数据经过 AES-256 加密后推送到几乎所有的云存储后端,包括对象存储、WebDAV 和 S3 兼容服务。对于团队而言,仅靠命令行或桌面客户端管理备份任务并不直观,特别是在需要多人协作运维的场景下,构建一个基于 Web 的管理控制台显得尤为重要。Vue 3 结合其成熟的工程化生态,是搭建这类控制台的理想选择。本文将从前端工程化角度出发,完整讲解如何用 Vue 3 构建一个 Duplicati 备份任务管理平台。
一、项目初始化与工程化基础搭建
使用 Vite 创建 Vue 3 项目是当前工程化的标准做法。相比传统的脚手架,Vite 的冷启动速度和热更新体验都明显更好,尤其在备份控制台这种需要频繁调整页面的项目中优势突出。执行以下命令即可初始化项目:
npm create vite@latest duplicati-console -- --template vue-ts cd duplicati-console npm install npm install pinia axios vue-router element-plus
选择 TypeScript 模板的意义在于,Duplicati 的 API 返回结构相对复杂,包含任务配置、时间计划、存储凭据等多层嵌套对象,用接口类型约束数据结构可以在编码阶段就发现字段拼写错误。建议在 src/types 目录下统一定义类型,例如备份任务接口:
// src/types/backup.ts
export interface BackupTask {
id: string
name: string
targetUrl: string // 云存储目标地址,如 s3://bucket/path
encryption: 'AES-256' | 'GPG' | 'none'
schedule: string // cron 表达式
lastRun: string | null
state: 'running' | 'idle' | 'error'
sources: string[]
}
目录结构建议按功能模块划分:src/api 存放与 Duplicati Server API 通信的封装,src/stores 存放 Pinia 状态仓库,src/views 存放页面组件,src/composables 存放可复用的组合式函数。这种划分让备份任务、存储目标、日志监控三个核心模块的边界清晰,后期维护成本大幅降低。
二、封装 Duplicati API 与状态管理设计
Duplicati 提供了本地 HTTP Server 模式,默认监听 8200 端口,暴露 REST 风格的接口。前端直接请求该服务会面临跨域问题,工程化的标准解法是在 Vite 开发环境配置代理,生产环境则由 Nginx 反向代理完成。配置示例如下:
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8200',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
接下来封装 axios 实例,统一处理 Duplicati 的鉴权 Token 与错误拦截。Duplicati Server 需要 Authorization 头携带 Token,将其集中在请求拦截器中管理可以避免每个接口重复书写:
// src/api/request.ts
import axios from 'axios'
import { useAuthStore } from '@/stores/auth'
const request = axios.create({ baseURL: '/api/v1', timeout: 15000 })
request.interceptors.request.use(config => {
const auth = useAuthStore()
if (auth.token) {
config.headers.Authorization = `Bearer ${auth.token}`
}
return config
})
request.interceptors.response.use(
res => res.data,
err => {
if (err.response?.status === 401) {
// Token 失效时跳转登录页
window.location.href = '/login'
}
return Promise.reject(err)
}
)
export default request
状态管理方面,Pinia 是 Vue 3 官方推荐方案。备份任务列表是典型的全局共享状态:任务列表页、仪表盘、通知栏都需要读取它。使用 setup store 风格定义仓库,配合轮询或 WebSocket 更新任务运行状态,可以保证界面实时反映备份进度。需要注意的是,任务状态更新频繁,应避免在仓库中做过深的嵌套响应式转换,只对必要字段保持响应即可,减少性能开销。
三、核心页面实现:任务列表与加密配置
备份任务列表页是控制台的核心。页面需要展示任务名称、云存储目标、加密算法、计划执行时间与最近一次运行结果。借助 Element Plus 的表格组件可以快速搭建,关键在于把 Duplicati 返回的原始数据映射为界面友好的展示形式,例如把 s3://bucket/path 拆解为存储类型与目标路径两列,把加密算法渲染为标签样式。
<template>
<el-table :data="taskStore.tasks" v-loading="taskStore.loading">
<el-table-column prop="name" label="任务名称" />
<el-table-column label="存储类型">
<template #default="{ row }">
<el-tag>{{ parseTarget(row.targetUrl).type }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="encryption" label="加密方式" />
<el-table-column prop="lastRun" label="最近备份" />
<el-table-column label="状态">
<template #default="{ row }">
<el-tag :type="row.state === 'error' ? 'danger' : 'success'">
{{ row.state }}
</el-tag>
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { useTaskStore } from '@/stores/task'
const taskStore = useTaskStore()
taskStore.fetchTasks()
</script>
新建备份任务的向导页面则更复杂,通常分为四步:选择本地源目录、配置云存储目标、设置加密口令与压缩选项、定义计划任务。每一步对应一个子组件,父组件持有表单状态并校验。这里有一个安全要点必须强调:加密口令属于敏感信息,绝不应明文存入前端持久化存储,提交时应直接通过 HTTPS 传给后端由 Duplicati 保管,前端只在内存中临时持有。同时口令输入框应关闭浏览器自动填充,避免凭据泄漏到本地表单记录中。
日志监控页面建议采用虚拟滚动方案。Duplicati 的备份日志在长任务中可能产生数万行输出,直接渲染会导致页面卡顿,引入 vue-virtual-scroller 之类的库只渲染可视区域行数,配合按级别过滤(信息、警告、错误),既能保证性能又能快速定位问题。
四、路由权限与构建部署
备份控制台涉及危险操作(删除任务、恢复数据),必须实施权限控制。工程化做法是定义路由元信息 meta.roles,在全局前置守卫中校验当前用户角色。管理员可以执行所有操作,普通运维人员只能查看与手动触发备份,只读访客则无法进入任何操作页面。这种细粒度控制可以在事故发生前就降低误操作风险。
router.beforeEach(async (to, from, next) => {
const auth = useAuthStore()
if (to.meta.requiresAuth && !auth.isLoggedIn) {
return next('/login')
}
if (to.meta.roles && !to.meta.roles.includes(auth.role)) {
return next('/403')
}
next()
})
构建部署环节,执行 npm run build 生成静态资源后交给 Nginx 托管。Nginx 配置中除了将 /api 反向代理到 Duplicati Server 外,还应开启 gzip 压缩并设置静态资源长缓存。对于 SPA 的 history 路由模式,需要配置 try_files 回退到 index.html,避免用户刷新页面时出现 404。若团队使用 CI 流水线,可将单元测试、类型检查、构建、部署串联为流水线阶段,每次提交自动验证,保证控制台代码的质量持续可控。
整体来看,Vue 3 工程化为 Duplicati 加密备份管理提供了从开发到部署的完整支撑:Vite 负责高效的开发体验,TypeScript 与 Pinia 保证数据层的健壮,组件化的页面设计让任务管理、加密配置、日志监控各自独立演进,而权限路由与自动化部署则守住了生产环境的底线。按照本文的路径搭建完成后,还可以进一步扩展,例如接入 WebSocket 实现实时进度推送、增加备份成功率统计图表等,让备份运维真正走向可视化与自动化。