Deployer Selector 完全指南:用标签精确调度主机与任务
Deployer Selector 完全指南用标签精确调度主机与任务【免费下载链接】deployerThe PHP deployment tool with support for popular frameworks out of the box项目地址: https://gitcode.com/gh_mirrors/de/deployer导读Selector选择器是 Deployer 中用于挑选主机来执行任务的机制每台主机携带一组键值对labels标签例如stage: production、role: webSelector 负责根据这些标签过滤出目标主机。无论是命令行传参dep info envprod、任务体内动态筛选select()/on()还是为任务绑定固定选择器-select()都建立在同一套标签匹配语义之上。读完本文你将完整掌握 Deployer Selector 的语法OR/AND/取反/别名、源码级匹配原理以及它在 MAML 配置、任务调度与once语义中的实际应用方式。一、标签LabelsSelector 的匹配基础Selector 不是凭空选主机而是基于主机上的键值对标签进行匹配。标签通过host()定义主机时一并声明host(web.example.com) -setLabels([ type web, env prod, ]); host(db.example.com) -setLabels([ type db, env prod, ]);已存在的主机可用-addLabels()追加/合并标签。其底层实现位于 Host.phpsetLabels()直接写入配置键labels而addLabels()会先取出已有标签再通过array_replace_recursive与新增标签递归合并后回写因此可以安全地分多次、分层地补充标签而不覆盖已有内容host(api.example.com) -setLabels([type api]) -addLabels([env staging, region eu]);labels在内部就是主机配置中的一个数组键。Host::get(labels, [])读取它而Selector::apply()在匹配时同样通过$host-get(labels, [])取出标签集见 Selector.php两者共用同一份数据不存在两套标签源。二、第一个实战用选择器运行任务定义打印标签的任务task(info, function () { writeln(type: . get(labels)[type] . env: . get(labels)[env]); });get(labels)取的是当前主机的标签Context中已切到该主机。不带选择器运行会作用于所有主机带上选择器则只作用于匹配的主机$ dep info envprod task info [web.example.com] type:web env:prod [db.example.com] type:db env:prod两台主机都匹配envprod。进一步收窄条件$ dep info typeweb task info [web.example.com] type:web env:prod命令行选择器由SelectCommand统一处理SelectCommand.php取到的参数数组会用implode(,, ...)拼成单个选择表达式后交给Deployer::get()-selector-select()。若不传任何选择器且配置了default_selector全局配置则使用该默认值交互式终端下还会弹出多选清单让你挑选主机。三、Selector 语法OR、AND、值内 OR 与取反一个选择器是由条件组成的列表条件之间用,OR或AND连接。下面是完整语法均以第一节的两台主机为例。OR,typeweb,envprod匹配typeweb或envprod$ dep info typeweb,envprod task info [web.example.com] type:web env:prod [db.example.com] type:db env:prodANDtypeweb envprod要求同时满足两者$ dep info typeweb envprod task info [web.example.com] type:web env:prod值内 OR|typeweb|db envprod表示(typeweb OR typedb) AND envprod注意运算符优先级——|只在单个值内部生效不会跨越$ dep info typeweb|db envprod task info [web.example.com] type:web env:prod [db.example.com] type:db env:prod取反!type!web排除标签为typeweb的主机$ dep info type!web task info [db.example.com] type:db env:prod关于解析顺序源码给出了精确的层级Selector::parse()先用explode(,)按 OR 切分整个表达式得到若干个子条件组每个子条件组再按explode()切分 AND 部分每个部分trim()后若不含则当作别名条件见下文否则用正则/(?var.?)(?op!?)(?value.)/拆出变量 / 操作符 / 值值部分再按|拆成候选数组。而apply()Selector.php的求值逻辑是同一组条件全部为真则整组命中任一|候选值命中即视为该条件为真组与组之间是 OR任一组命中即匹配。这与直觉完全一致的优先级高于顶层,。:::note多个选择器参数等价于逗号拼接dep info typeweb envprod≡dep info typeweb,envprod。另外bash 自动补全支持选择器提示——参考 installation。 :::四、特殊选择器all与别名匹配all—— 匹配每一台主机。alias...—— 按主机别名匹配。任何不含的 token 都被视作别名见parse()中 else 分支[, alias, trim($part)]因此dep info web.example.com≡dep info aliasweb.example.com$ dep info web.example.com task info [web.example.com] type:web env:prod多别名可并列等价于逗号连接的别名条件$ dep info web.example.com db.example.com $ # Same as: $ dep info aliasweb.example.com,aliasdb.example.com别名与true标签的源码细节在apply()中匹配时实际参与比较的标签集合会额外注入两个隐式标签Selector.php$labels $host-get(labels, []); $labels[alias] $host-getAlias(); // 把主机别名当作可匹配标签 $labels[true] true; // 恒真标签供 all 使用alias标签让alias...和裸 token 生效true标签让all变为等价于[, true, true]的条件从而无条件命中所有主机。compare()支持与!两种操作符要求标签值严格等于候选值比较且支持标签值为数组时逐个元素比对这与值内 OR天然兼容!则取反。当标签缺失时按null参与比较——因此type!web同样会命中没有type标签的主机这一点在编写排除条件时值得留意。五、在 PHP 代码中使用选择器select()与on()除了命令行任务内部也能动态地按选择器取主机。select(expr)返回匹配主机的数组定义见 functions.php实现为Deployer::get()-selector-select($selector)task(info, function () { $hosts select(typeweb|db,envprod); foreach ($hosts as $host) { writeln(type: . $host-get(labels)[type] . env: . $host-get(labels)[env]); } });on(hosts, callback)对每个匹配主机依次执行回调并自动完成Context的压栈/出栈、配置加载与保存functions.phptask(info, function () { on(select(all), function () { writeln(type: . get(labels)[type] . env: . get(labels)[env]); }); });on()的回调里get()/run()都作用于当前遍历到的主机它同样接受单台主机或主机集合甚至可以传Deployer::get()-hosts遍历全部主机。相关完整 API 见 api.md。六、任务级选择器-select()可以把选择器固定绑定到某个任务上这样无论谁调用该任务都只会作用到匹配的主机tasks.md 中的select配置task(info, function () { // ... })-select(typeweb|db,envprod);Task::select()只是把表达式缓存为解析结果Task.php$this-selector Selector::parse($selector);。真正消费它的是执行器 Master.php——在执行每个任务前用Selector::apply($task-getSelector(), $currentHost)逐主机判定未命中的主机直接从本任务的执行计划中剔除。这个机制还与 Deployer 的任务调度特性深度耦合once单次执行只在第一个匹配选择器的主机上运行一次oncePerNode每节点一次按hostname或标签node去重每组节点只跑一次见 Master.php子任务继承脚本中的子任务会通过addSelector()合并父任务的 selectorScriptManager.php保证过滤条件在整个调用链上传递。在并行场景--parallel、--limit下Master 同样在每个分块内先按 selector 过滤再派发Master.php因此任务级选择器在串行与并行模式下行为一致。七、MAML 中的标签MAML 配方同样支持 labels。标签写在主机的labels键下与env环境配置平级{ hosts: { web.example.com: { remote_user: deployer env: { environment: production } labels: { env: prod } } } }不要把env配置键和labels.env标签混为一谈二者相互独立env存放的是 MAML 里定义的部署环境配置labels.env只是参与 selector 匹配的标签值。可以在同一任务里同时读取验证task(info, function () { writeln(env: . get(env)[environment] . labels.env: . get(labels)[env]); });$ dep info envprod task info [web.example.com] env:production labels.env:prod这里命令行选择器匹配的是labels.envprod而打印出的env:production来自配置键env——两者互不干扰。八、命令行交互细节与调试几个有助于日常使用的命令行行为默认选择器全局配置default_selector可在不传参时生效SelectCommand.php交互式选择配置了多台主机且未给选择器时终端会弹出多选清单ChoiceQuestion支持逗号分隔多选无命中即报错表达式写错或没有主机匹配时命令会抛出异常并回显选择器原文便于排查SelectCommand.phpShell 自动补全selector 参数的补全建议来自all、所有主机别名以及各主机的labelvalue组合SelectCommand.php安装方式参见 installation。此外Selector的单测 SelectorTest.php 覆盖了典型组合all全量匹配、stageprod单条件、stageprod tierfrontendAND 匹配、prod.domain.com/front, stagebeta别名条件 OR、all tier ! frontend取反排除以及标签值为数组如stage [prod, beta]时的多值匹配——这些用例可直接作为你验证选择器行为的参考基准。九、小结Deployer 的 Selector 体系可以归纳为三层数据层主机通过setLabels()/addLabels()或 MAML 中的labels:键携带任意键值标签匹配时还会注入alias与恒真的true两个隐式标签匹配层Selector::parse()将表达式拆为,OR→AND→|值内 OR三层结构Selector::apply()按组内全真、组间任一规则求值支持与!应用层CLI 参数经 SelectCommand.php 拼接后统一求值任务内可用select()/on()动态筛选任务定义可用-select()固化范围once/oncePerNode与并行调度则复用同一套apply()判定。掌握这套机制后无论是只部署生产环境 Web 节点排除某个机房的主机还是每节点只跑一次数据库迁移都能用一行选择器精准表达让 Deployer 的批量部署始终落在你真正想要的主机集合上。【免费下载链接】deployerThe PHP deployment tool with support for popular frameworks out of the box项目地址: https://gitcode.com/gh_mirrors/de/deployer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于Unet++的跨模态超声肾脏分割源码实战:从训练到推理

基于Unet++的跨模态超声肾脏分割源码实战:从训练到推理

简介:本资源面向医学图像处理方向的开发者与研究者,提供一套基于Unet的超声图像跨模态肾脏语义分割Python实现方案,可用于超声影像中肾脏区域的自动识别与分割实验,适合具备一定深度学习基础、希望快速复现并改进分割模型的中高级…

2026/9/23 17:53:10 阅读更多 →
DeepSeek 法律PDF摘要实战:抽象式生成压缩446页文书

DeepSeek 法律PDF摘要实战:抽象式生成压缩446页文书

简介:面向法律科技与自然语言处理算法方向的系统方案资料,完整阐述如何借助DeepSeek构建法律文档智能摘要与要点快速提取流程,解决法律长文本压缩、关键要素识别与法律效力保留等核心问题,适合法务信息化产品经理、算法工程师及法…

2026/9/23 17:52:09 阅读更多 →
3步搞定城市党建系统选型避坑指南

3步搞定城市党建系统选型避坑指南

3步搞定城市党建系统选型避坑指南 很多后端老哥都卡在这个坎上:语法滚瓜烂熟,LeetCode 也能刷两把,但真让搭个“城市党建”这种政务类项目,脑子立马一片空白。不是代码写不出来,是根本不知道数据怎么流、权限怎么控、报表怎么出。这种从“写函…

2026/9/23 17:52:09 阅读更多 →

最新新闻

KMeans聚类在宿舍分配中的实战:特征工程到K值选择

KMeans聚类在宿舍分配中的实战:特征工程到K值选择

简介:针对高校宿舍分配场景,这份基于KMeans聚类算法的Python源码包提供了从数据预处理、模型训练到结果可视化的完整实现,适合需要将无监督学习落地到实际管理问题的数据科学初学者或高校信息管理相关技术人员。压缩包共13个文件,…

2026/9/23 18:38:49 阅读更多 →
fpm 构建 Solaris SRV4 软件包(solaris 输出格式)完全指南

fpm 构建 Solaris SRV4 软件包(solaris 输出格式)完全指南

fpm 构建 Solaris SRV4 软件包(solaris 输出格式)完全指南 【免费下载链接】fpm Effing package management! Build packages for multiple platforms (deb, rpm, etc) with great ease and sanity. 项目地址: https://gitcode.com/gh_mirrors/fp/fpm …

2026/9/23 18:38:49 阅读更多 →
Java Swing数独游戏工程级实现与难度控制

Java Swing数独游戏工程级实现与难度控制

简介:本资源是一份面向Java初学者与课程设计实践者的完整数独小游戏开发项目,适用于高校Java程序设计、GUI编程或软件工程类课程作业参考。项目基于Swing构建图形界面,代码结构清晰,涵盖游戏逻辑、难度生成、用户交互及资源管理等…

2026/9/23 18:38:49 阅读更多 →
Fedora开发环境避坑指南:保姆级教程解决常见报错

Fedora开发环境避坑指南:保姆级教程解决常见报错

Fedora开发环境避坑指南:保姆级教程解决常见报错 盯着屏幕上一片红色的StackTrace,是不是感觉脑子瞬间宕机?刚把Fedora装好,连个Python环境都跑不通,报错信息长得像天书,根本不知道从哪下手。别慌,这份保姆级教程就是为你…

2026/9/23 18:38:49 阅读更多 →
基于 TVM 编译栈的 WebAssembly 独立深度学习推理:wasm-standalone 项目实战解析

基于 TVM 编译栈的 WebAssembly 独立深度学习推理:wasm-standalone 项目实战解析

编译器深度学习模型优化 【免费下载链接】tvm Open deep learning compiler stack for cpu, gpu and specialized accelerators 项目地址: https://gitcode.com/gh_mirrors/tvm7/tvm 点击查看 免费下载 本文围绕仓库中的 apps/wasm-standalone 实验性项目&#xff…

2026/9/23 18:38:48 阅读更多 →
2026最新怎么注册营业执照,程序员如何搭建个人开发环境

2026最新怎么注册营业执照,程序员如何搭建个人开发环境

2026最新怎么注册营业执照,程序员如何搭建个人开发环境 刚学会Python语法,打开VS Code却不知从何下手?这是90%新手最真实的困境。2026最新的技术栈迭代很快,但基础项目搭建逻辑没变。很多教程只讲“怎么写代码”,却忽略了“怎么…

2026/9/23 18:37:48 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →