我用 Flutter + Spring Boot 开发了个一键部署工具(国内版 Vercel)
前言
不知道大家有没有这样的经历:
开发了一个小项目,想部署到服务器上让朋友看看。
结果:
- 买服务器、配环境花了半天
- Nginx 配置搞不定
- SSL 证书申请不会弄
- 最后项目还是躺在 GitHub 里吃灰
我自己就经常遇到这个问题。作为一个独立开发者,我想要的只是一个简单的部署工具:
- 连接 GitHub 仓库
- 点击”部署”按钮
- 30 秒后获得一个可访问的 URL
但是市面上的工具要么太贵(Vercel 国际版访问慢),要么太复杂(阿里云云效配置繁琐)。
于是,我决定自己做一个!
项目介绍
项目名称:DeployFast
定位:国内版 Vercel - 一键部署工具
Slogan:代码提交即部署,30 秒上线你的应用
核心功能:
- ✅ 连接 GitHub 仓库
- ✅ 自动检测项目类型(Node.js/Python/Java/静态网站)
- ✅ 自动构建和部署
- ✅ 自动 HTTPS 证书
- ✅ 自定义域名支持
- ✅ 环境变量管理
- ✅ 部署历史查看和回滚
技术栈:
- 前端:Flutter Web + Provider
- 后端:Spring Boot 3.1.5 + Java 17
- 数据库:MySQL 8.0
- 部署:Docker + Nginx
为什么选择这个技术栈?
前端:Flutter Web
原因:
- 一套代码,多端运行 - 未来可以打包成桌面应用
- 高性能渲染 - 比 React/Vue 的 Web 应用更流畅
- 开发效率高 - 热重载 + 丰富的组件库
- 我熟悉 - 之前做过 Flutter 项目
对比:
| 框架 | 优点 | 缺点 |
|——|——|——|
| Flutter Web | 性能好、跨平台 | 生态较小 |
| React | 生态大、组件多 | 需要配置多端 |
| Vue | 简单易学 | 跨平台能力弱 |
后端:Spring Boot
原因:
- 约定优于配置 - 零配置启动
- 生态强大 - 需要什么都有现成的 Starter
- 性能稳定 - 企业级框架,久经考验
- 我熟悉 - 工作一直在用
对比:
| 框架 | 优点 | 缺点 |
|——|——|——|
| Spring Boot | 生态大、稳定 | 启动慢、占用内存高 |
| Node.js | 轻量、快速 | 类型安全弱 |
| Go | 性能最好 | 生态相对较小 |
开发过程
第 1 天:项目框架搭建
后端:1
2
3
4# 创建 Spring Boot 项目
mkdir -p deployfast/backend
cd deployfast/backend
# 初始化 Maven 项目,添加依赖
核心依赖:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Security + JWT -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
前端:1
2
3
4# 创建 Flutter 项目
flutter create deployfast_frontend
cd deployfast_frontend
# 添加依赖:provider, http, go_router
第 2-3 天:GitHub OAuth 认证
最复杂的部分,因为要处理 OAuth 流程。
后端实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public ResponseEntity<Map<String, String>> githubLogin() {
String authUrl = githubService.getAuthorizationUrl();
return ResponseEntity.ok(Map.of("authorization_url", authUrl));
}
public ResponseEntity<?> githubCallback( String code) {
// 1. 使用授权码获取 Access Token
String accessToken = githubService.getAccessToken(code);
// 2. 获取 GitHub 用户信息
Map<String, Object> githubUser = githubService.getUserInfo(accessToken);
// 3. 查找或创建用户
User user = githubService.findOrCreateUser(githubUser, accessToken);
// 4. 生成 JWT Token
String jwtToken = jwtUtil.generateToken(user.getUsername(), user.getId());
return ResponseEntity.ok(Map.of("token", jwtToken, "user", user));
}
前端实现:1
2
3
4
5
6
7
8
9Future<void> loginWithGithub() async {
final authUrl = await _apiService.getGithubAuthUrl();
// 使用 url_launcher 打开浏览器
final uri = Uri.parse(authUrl);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
}
}
遇到的问题:
- GitHub OAuth 回调 URL 必须完全匹配(包括 http/https)
- JWT Token 需要安全存储(前端用 SharedPreferences)
- 跨域问题(后端配置 CORS)
第 4-5 天:项目类型检测器
核心功能:自动检测项目类型并返回构建配置。
Python 实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class ProjectDetector:
PROJECT_TYPES = {
'nodejs': {
'detect_files': ['package.json'],
'build_command': 'npm install && npm run build',
'output_dir': 'dist'
},
'python': {
'detect_files': ['requirements.txt'],
'build_command': 'pip install -r requirements.txt',
'output_dir': ''
},
'java': {
'detect_files': ['pom.xml'],
'build_command': 'mvn clean package -DskipTests',
'output_dir': 'target'
}
}
def detect(self):
# 检测特征文件
# 返回项目类型和构建配置
pass
检测逻辑:
- 检查
package.json→ Node.js 项目 - 检查
requirements.txt→ Python 项目 - 检查
pom.xml→ Java 项目 - 检查
index.html→ 静态网站
第 6-7 天:部署核心功能
最复杂的部分,涉及到实际的构建和部署。
部署流程:1
2
3
4
5
6
7
8
9
10
111. 从 GitHub 拉取代码
↓
2. 检测项目类型
↓
3. 执行构建命令
↓
4. 复制构建产物到部署目录
↓
5. 配置 Nginx
↓
6. 返回部署成功
构建执行器:1
2
3
4
5
6
7
8def build_project(project_type, workspace_path):
if project_type == 'nodejs':
subprocess.run(['npm', 'install'], cwd=workspace_path)
subprocess.run(['npm', 'run', 'build'], cwd=workspace_path)
elif project_type == 'python':
subprocess.run(['pip', 'install', '-r', 'requirements.txt'], cwd=workspace_path)
elif project_type == 'java':
subprocess.run(['mvn', 'clean', 'package', '-DskipTests'], cwd=workspace_path)
第 8-9 天:前端界面开发
页面列表:
- 登录页面 - GitHub OAuth 登录
- 主界面 - 侧边栏导航
- 项目列表 - 展示所有项目
- 创建项目 - 填写项目信息
- 部署日志 - 实时查看部署进度
- 环境变量 - 管理环境变量
项目列表页面:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19ListView.builder(
itemCount: projects.length,
itemBuilder: (context, index) {
final project = projects[index];
return Card(
child: ListTile(
title: Text(project.name),
subtitle: Text(project.repo),
trailing: PopupMenuButton(
items: [
PopupMenuItem(value: 'deploy', child: Text('部署')),
PopupMenuItem(value: 'logs', child: Text('部署日志')),
PopupMenuItem(value: 'env', child: Text('环境变量')),
],
),
),
);
},
)
第 10 天:环境变量管理
需求:
- 支持添加、编辑、删除环境变量
- 敏感变量(如数据库密码)需要隐藏存储
- 部署时自动注入环境变量
数据模型:1
2
3
4
5
6
7
8
9
10
11
12
public class EnvironmentVariable {
private Long id;
private Long projectId;
private String key;
private String value;
private Boolean isSecret = false;
}
前端界面:
- 敏感变量显示 🔒 图标
- 值显示为
•••••••• - 编辑时可以选择是否敏感
核心功能演示
1. GitHub OAuth 登录

点击”使用 GitHub 登录” → 打开浏览器授权 → 自动跳转回应用
2. 项目列表

展示所有项目,支持创建、部署、查看日志、管理环境变量
3. 创建项目

填写项目名称、GitHub 仓库、分支、项目类型
4. 部署日志

实时查看部署进度,支持回滚到历史版本
5. 环境变量管理

管理项目的环境变量,支持敏感变量
技术亮点
1. 自动项目检测
1 | # 检测 Node.js 项目 |
2. 实时日志轮询
1 | // 每 2 秒轮询一次部署状态 |
3. 敏感变量保护
1 | // 获取环境变量时,敏感值返回 ***hidden*** |
4. 异步部署
1 | // 不阻塞 API 响应 |
遇到的坑
坑 1:Flutter Web 跨域问题
问题:前端调用后端 API 时报 CORS 错误。
解决:后端配置 CORS1
2
3
4
5
6
7
8
9
10
11
12
13
public class SecurityConfig {
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("*"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
坑 2:GitHub OAuth 回调 URL 不匹配
问题:GitHub 提示 “redirect_uri_mismatch”。
解决:确保 GitHub OAuth App 中的回调 URL 与实际访问的 URL 完全一致(包括 http/https)。
坑 3:Python 脚本执行超时
问题:大型项目构建时间超过 5 分钟。
解决:增加超时时间到 15 分钟,并显示实时日志。
坑 4:Flutter Web 打包后体积过大
问题:build web 后有 5MB+。
解决:
- 使用
--release模式构建 - 启用 gzip 压缩
- 使用 CDN 加载大文件
项目现状
GitHub 仓库:https://github.com/DavidYuanX/deployfast
完成度:95%
已完成功能:
- ✅ GitHub OAuth 认证
- ✅ 项目 CRUD
- ✅ 自动部署(Node.js/Python/Java/静态网站)
- ✅ 部署日志查看
- ✅ 部署回滚
- ✅ 环境变量管理
- ✅ 健康检查接口
待开发功能:
- 自定义域名支持
- SSL 证书自动申请
- WebSocket 实时日志
- 部署监控告警
- 团队协作功能
下一步计划
1. 部署上线
- 购买阿里云服务器(2 核 4G,约 200 元/月)
- 配置域名和 SSL 证书
- 部署后端服务(Spring Boot JAR)
- 部署前端(Flutter Web build)
- 配置 Nginx 反向代理
2. 免费增值模式
免费版:
- 1 个项目
- 10 次部署/月
- 基础功能
专业版(¥49/月):
- 5 个项目
- 100 次部署/月
- 自定义域名
- 环境变量管理
团队版(¥199/月):
- 无限项目
- 无限部署
- 团队协作
- 优先支持
3. 技术推广
- 写技术博客(就是这篇!)
- 发布到知乎、掘金、CSDN
- GitHub 开源部分代码
- 建立开发者社区
总结
开发周期:10 天
代码行数:约 5000 行
技术栈:Flutter + Spring Boot
核心功能:一键部署
最大的收获:
- Flutter Web 真的可以用来做管理后台
- Spring Boot 依然是企业级开发的首选
- OAuth 认证流程虽然复杂,但理解了就很清晰
- 独立开发最重要的是快速迭代,不要追求完美
给想独立开发的朋友的建议:
- 从小做起 - 不要一开始就想做大平台
- 解决自己的痛点 - 你自己遇到的问题,别人也会遇到
- 快速上线 - 先做个 MVP,再根据反馈迭代
- 坚持写博客 - 技术推广很重要
参考资源
最后:
如果你觉得这个项目对你有帮助,欢迎:
- ⭐ Star 支持一下
- 💬 提 Issue 或 PR
- 📢 推荐给朋友
有任何问题,欢迎在评论区留言!
下一篇预告:《DeployFast 部署上线实战 - 从购买服务器到配置 SSL》