前言

不知道大家有没有这样的经历:

开发了一个小项目,想部署到服务器上让朋友看看。

结果:

  • 买服务器、配环境花了半天
  • Nginx 配置搞不定
  • SSL 证书申请不会弄
  • 最后项目还是躺在 GitHub 里吃灰

我自己就经常遇到这个问题。作为一个独立开发者,我想要的只是一个简单的部署工具

  1. 连接 GitHub 仓库
  2. 点击”部署”按钮
  3. 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

原因

  1. 一套代码,多端运行 - 未来可以打包成桌面应用
  2. 高性能渲染 - 比 React/Vue 的 Web 应用更流畅
  3. 开发效率高 - 热重载 + 丰富的组件库
  4. 我熟悉 - 之前做过 Flutter 项目

对比
| 框架 | 优点 | 缺点 |
|——|——|——|
| Flutter Web | 性能好、跨平台 | 生态较小 |
| React | 生态大、组件多 | 需要配置多端 |
| Vue | 简单易学 | 跨平台能力弱 |

后端:Spring Boot

原因

  1. 约定优于配置 - 零配置启动
  2. 生态强大 - 需要什么都有现成的 Starter
  3. 性能稳定 - 企业级框架,久经考验
  4. 我熟悉 - 工作一直在用

对比
| 框架 | 优点 | 缺点 |
|——|——|——|
| 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
@GetMapping("/github")
public ResponseEntity<Map<String, String>> githubLogin() {
String authUrl = githubService.getAuthorizationUrl();
return ResponseEntity.ok(Map.of("authorization_url", authUrl));
}

@GetMapping("/github/callback")
public ResponseEntity<?> githubCallback(@RequestParam 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
9
Future<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);
}
}

遇到的问题

  1. GitHub OAuth 回调 URL 必须完全匹配(包括 http/https)
  2. JWT Token 需要安全存储(前端用 SharedPreferences)
  3. 跨域问题(后端配置 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
23
class 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

检测逻辑

  1. 检查 package.json → Node.js 项目
  2. 检查 requirements.txt → Python 项目
  3. 检查 pom.xml → Java 项目
  4. 检查 index.html → 静态网站

第 6-7 天:部署核心功能

最复杂的部分,涉及到实际的构建和部署。

部署流程

1
2
3
4
5
6
7
8
9
10
11
1. 从 GitHub 拉取代码

2. 检测项目类型

3. 执行构建命令

4. 复制构建产物到部署目录

5. 配置 Nginx

6. 返回部署成功

构建执行器

1
2
3
4
5
6
7
8
def 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 天:前端界面开发

页面列表

  1. 登录页面 - GitHub OAuth 登录
  2. 主界面 - 侧边栏导航
  3. 项目列表 - 展示所有项目
  4. 创建项目 - 填写项目信息
  5. 部署日志 - 实时查看部署进度
  6. 环境变量 - 管理环境变量

项目列表页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ListView.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
@Entity
@Table(name = "environment_variables")
public class EnvironmentVariable {
@Id
@GeneratedValue
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
2
3
4
# 检测 Node.js 项目
if file_exists('package.json'):
if has_npm_script('build'):
return 'nodejs', 'npm install && npm run build', 'dist'

2. 实时日志轮询

1
2
3
4
5
6
7
8
9
// 每 2 秒轮询一次部署状态
Future<void> pollDeploymentStatus(int deploymentId) async {
await Future.delayed(Duration(seconds: 2));
final logs = await api.getDeploymentLogs(deploymentId);

if (logs['status'] == 'building') {
pollDeploymentStatus(deploymentId); // 继续轮询
}
}

3. 敏感变量保护

1
2
3
4
5
6
// 获取环境变量时,敏感值返回 ***hidden***
envVars.forEach(env -> {
if (env.getIsSecret()) {
env.setValue("***hidden***");
}
});

4. 异步部署

1
2
3
4
5
6
// 不阻塞 API 响应
new Thread(() -> {
executeDeployment(deployment, project);
}).start();

return deployment; // 立即返回部署记录

遇到的坑

坑 1:Flutter Web 跨域问题

问题:前端调用后端 API 时报 CORS 错误。

解决:后端配置 CORS

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class SecurityConfig {
@Bean
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
核心功能:一键部署

最大的收获

  1. Flutter Web 真的可以用来做管理后台
  2. Spring Boot 依然是企业级开发的首选
  3. OAuth 认证流程虽然复杂,但理解了就很清晰
  4. 独立开发最重要的是快速迭代,不要追求完美

给想独立开发的朋友的建议

  1. 从小做起 - 不要一开始就想做大平台
  2. 解决自己的痛点 - 你自己遇到的问题,别人也会遇到
  3. 快速上线 - 先做个 MVP,再根据反馈迭代
  4. 坚持写博客 - 技术推广很重要

参考资源


最后

如果你觉得这个项目对你有帮助,欢迎:

  1. ⭐ Star 支持一下
  2. 💬 提 Issue 或 PR
  3. 📢 推荐给朋友

有任何问题,欢迎在评论区留言!


下一篇预告:《DeployFast 部署上线实战 - 从购买服务器到配置 SSL》