单文件代码部署工具

造轮子:单文件管多项目部署,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 

....

使用流程

  1. 添加服务器

    • 登录系统
    • 进入"服务器"页面
    • 添加 SSH 服务器信息:服务器名称、主机地址、端口、用户名、SSH 密钥
    • 测试连接
  2. 添加项目

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

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

    • 在"部署历史"页面查看部署状态、提交信息和详细日志

目录结构

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);
    }
}

源码: github.com/PFinal-tool...

相关推荐
智驭未来掌门人8 分钟前
利用FFmpeg快速实现一个RTSP推流服务器
后端
垚垚学技术_聚焦云原生20 分钟前
K8s Pod 完整生命周期详解
后端
JavaGuide24 分钟前
Github 史诗级故障,与此同时,Cursor 版「GitHub」正式上线!
前端·后端
不一样的少年_28 分钟前
修了 Bug、做了重构,为什么老板还是觉得你没产出?
前端·后端·程序员
水深火乐1 小时前
安全地生成验证码、密码和 Token
后端
小强19881 小时前
SQL Server 慢查询怎么定位?一套从“卡”到“快”的完整排查流程
后端
水深火乐1 小时前
interface和any
后端
步行cgn1 小时前
MyBatis Error evaluating expression ‘ids‘. Return value (3) was not iterable 错误详
java·后端
神奇小汤圆1 小时前
Spring Boot + LangChain4j实现RAG——从零搭建企业级知识库问答系统
后端
H_Peak1 小时前
Python运算符与流程控制:if条件判断
后端