造轮子:单文件管多项目部署,Git / 服务器全搞定
做项目的时候,经常使用 Adminer 来便捷的操作数据库,一个 PHP 文件搞定一切,比 phpMyAdmin 要方便很多。仔细的翻了一下 Adminer 的源码, 发现它的架构设计真的精简,于是把项目部署上线的流程,也通过相同的思路,做了一个简单的单文件代码部署工具。效果如下:

工具特性
- 🚀 单文件部署 - 类似 Adminer,一个 PHP 文件即可运行
- 🔐 用户认证 - 简单的用户名密码认证系统
- 📦 多项目管理 - 支持管理多个项目
- 🖥️ 服务器管理 - 支持多个 SSH 服务器配置
- 🔄 Git 部署 - 基于 Git 的代码拉取和部署
- 📝 部署历史 - 完整的部署记录和日志查看
- 🔌 插件系统 - 支持 Composer、Artisan 等插件
- 📊 Web 界面 - 友好的 Web 管理界面
安装与使用
开发模式
bash
# 克隆或下载项目
cd pfinal-deployer
# 使用 PHP 内置服务器运行
php -S localhost:8090 deployer.php
访问 http://localhost:8090 默认用户名: admin 默认密码: admin
生产模式(单文件)
bash
# 编译成单文件
php compile.php
# 运行单文件
php deployer-single.php
# 或配置到 Nginx/Apache
编译效果如下
shell
php compile.php
开始编译(优化模式)...
处理: core/Logger.php
处理: lang/zh.php
处理: core/Database.php
处理: core/SecureStorage.php
处理: core/Validator.php
处理: core/CSRF.php
处理: core/SSHExecutor.php
处理: core/GitDeployer.php
处理: core/Auth.php
处理: core/Deployer.php
处理: drivers/SSHDriver.php
处理: plugins/PluginInterface.php
处理: plugins/ComposerPlugin.php
处理: plugins/ArtisanPlugin.php
处理: ui/css.php
处理: ui/js.php
处理视图: login.php
处理视图: dashboard.php
处理视图: projects.php
处理视图: project_edit.php
处理视图: servers.php
处理视图: server_edit.php
处理视图: deployments.php
处理视图: change_password.php
压缩代码(Logger.php 风格)...
压缩前: 191,638 bytes
压缩后: 129,592 bytes
压缩率: 32.4%
压缩前: 191,638 bytes
压缩后: 129,592 bytes
编译完成: deployer-single.php
文件大小: 126.55 KB
写入字节数: 129,592 bytes
编译后的代码如下:
php
<?php
error_reporting(E_ALL);ini_set('display_errors',1);ini_set('display_startup_errors',1);date_default_timezone_set('Asia/Shanghai');class Logger{private static $logFile=null;private static $logDir=null;public static function init($logDir=null){if($logDir===null){$logDir=__DIR__.'/storage/logs';}if(!is_dir($logDir)){@mkdir($logDir,0755,true);}self::$logDir=$logDir;self::$logFile=$logDir.'/deployer_'.date('Y-m-d').'.log';}public static function log($message,$level='INFO'){if(self::$logFile===null){self::init();}$timestamp=date('Y-m-d H:i:s');$logMessage="[{$timestamp}] [{$level}] {$message}".PHP_EOL;@file_put_contents(self::$logFile,$logMessage,FILE_APPEND);}public static function info($message){self::log($message,'INFO');}public static
....
使用流程
-
添加服务器
- 登录系统
- 进入"服务器"页面
- 添加 SSH 服务器信息:服务器名称、主机地址、端口、用户名、SSH 密钥
- 测试连接

-
添加项目
- 进入"项目"页面
- 点击"添加项目"
- 填写项目信息:名称、Git 仓库地址、分支、部署路径、选择服务器、部署前后脚本

-
执行部署
- 在项目列表或仪表板点击"部署"按钮
- 系统自动连接服务器、拉取代码、执行脚本、运行插件任务、记录日志

-
查看部署历史
- 在"部署历史"页面查看部署状态、提交信息和详细日志
目录结构
python
pfinal-deployer/
├── deployer.php # 主入口文件(开发模式)
├── compile.php # 打包脚本
├── deployer-single.php # 编译后的单文件
├── core/ # 核心类
│ ├── Logger.php
│ ├── Database.php
│ ├── Auth.php
│ ├── SSHExecutor.php
│ ├── GitDeployer.php
│ ├── Deployer.php
│ └── Router.php
├── drivers/ # 驱动
│ └── SSHDriver.php
├── plugins/ # 插件
│ ├── PluginInterface.php
│ ├── ComposerPlugin.php
│ └── ArtisanPlugin.php
├── lang/ # 语言包
│ └── zh.php
├── ui/ # UI 资源
│ ├── css.php
│ ├── js.php
│ └── views/ # 视图文件
│ ├── login.php
│ ├── dashboard.php
│ ├── projects.php
│ ├── project_edit.php
│ ├── servers.php
│ ├── server_edit.php
│ └── deployments.php
└── storage/ # 存储目录
├── deployer.db # SQLite 数据库
└── logs/ # 日志文件
插件开发
实现 PluginInterface 接口即可创建自定义插件:
php
class MyPlugin implements PluginInterface {
public function shouldRun($project) {
// 判断是否应该运行此插件
return true;
}
public function execute($sshExecutor, $project) {
// 执行插件逻辑
$command = "cd {$project['deploy_path']} && your-command";
return $sshExecutor->execute($command);
}
}