尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

FrankenPHP 的 GitHub Actions 镜像构建与发布流水线全解析

FrankenPHP 的 GitHub Actions 镜像构建与发布流水线全解析 FrankenPHP 的 GitHub Actions 镜像构建与发布流水线全解析【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp本指南以 FrankenPHP 官方仓库中的 docs/tr/github-actions.md 为核心系统讲解该仓库如何利用 GitHub Actions 自动完成 Docker 镜像的编译、测试与部署包括仓库 Secrets 的配置方法、Pull Request / Fork、合并 main、打版本标签三种典型触发场景以及pr-x、main、v1.2.3、latest等标签的生成规则。读完本文你将掌握如何为 FrankenPHP 项目或任何基于该流水线的派生仓库配置一套完整的 Docker 镜像 CI/CD 流程并理解其背后 .github/workflows/docker.yaml 与 docker-bake.hcl 的底层实现逻辑。流水线概览一次提交如何变成 Docker 镜像FrankenPHP 的镜像流水线以 GitHub Actions 为执行引擎目标是把仓库源码编译成可直接运行的 Docker 镜像并推送到 Docker Hub 上的dunglas/frankenphp仓库。整个流程遵循先构建、再测试、后推送的原则代码变更Pull Request、Fork、合并、版本标签触发工作流GitHub Actions 使用 Dockerfile / alpine.Dockerfile 配合 Docker Buildx 多架构构建镜像构建产物先在本地产出并执行全量测试构建与测试全部通过后镜像才被推送并打上对应语义的标签。从当前仓库的 .github/workflows/docker.yaml 可以看到工作流同时监听多种事件源第 6-32 行指向main分支的pull_request、main分支的push、v*.*.*格式的标签推送、手动触发的workflow_dispatch以及每日凌晨 4 点的定时重建schedule。这意味着镜像不是发版才构建而是随代码演进持续维护。前置准备在仓库设置中配置 Secrets要让流水线能够登录并推送镜像到 Docker Registry必须在仓库的Settings → Secrets and variables → Actions中提前配置以下四个敏感值原文档核心内容Secret 名称用途示例值REGISTRY_LOGIN_SERVER目标 Docker Registry 地址docker.ioREGISTRY_USERNAME登录 Registry 使用的用户名dunglasREGISTRY_PASSWORD登录密码推荐使用 Access Token而非账号密码形如dckr_pat_...的访问令牌IMAGE_NAME镜像的完整名称dunglas/frankenphp这四个值分别回答了推送镜像时需要回答的四个问题推到哪、以谁的身份、用什么凭证、叫什么名字。它们都是运行时敏感信息应作为 GitHub Secrets 存储绝不能硬编码进工作流文件或提交到代码库。官方工作流中的实际凭证用法从源码角度印证当前仓库的 docker.yaml 在登录 Docker Hub 时实际引用的是vars.DOCKERHUB_USERNAME与secrets.DOCKERHUB_TOKEN第 70-71 行- name: Login to DockerHub uses: docker/login-action... with: username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }}也就是说如果你在官方仓库的镜像基础上派生Fork并自建发布需要把上文表格中的四个值替换为与你自己的 Docker 账号对应的真实值而官方仓库自身的流水线则以 DOCKERHUB 前缀的变量/密文承载同样的信息。此外登录步骤还通过条件判断限制了执行范围仅在非 PR 场景或 PR 来源仓库与主仓库一致时才执行登录github.event.pull_request.head.repo.full_name github.repository避免不可信的 Fork 代码窃取凭据。场景一Pull Request 或 Fork 触发的预发布构建按照原文档的描述仓库会在每次被批准的 Pull Request 或 Fork 之后自动执行一次构建。具体行为如下提交者创建一个 Pull Request或将仓库 Fork 后推送自己的分支GitHub Actions 随即开始构建镜像并运行全部测试构建与测试全部成功后镜像被推送到目标 Registry标签格式为pr-x其中x为 PR 编号。这套机制的价值在于任何未经合并的代码改动都能以pr-x标签生成一份可拉取验证的临时镜像维护者与贡献者可以直接docker pull该镜像做集成验证而不必等待代码合入主干。源码视角PR 构建如何运行测试在 docker.yaml 中PR 场景push输出为 false 时会在镜像构建完成后直接docker run该镜像执行测试第 213-225 行docker run --platform${PLATFORM} --rm \ 构建出的镜像ID \ sh -c ./go.sh test ${RACE} -v $(./go.sh list ./... | grep -v .../internal/testext | grep -v .../internal/extgen | tr \n ) cd caddy ../go.sh test ${RACE} -v ./...值得注意的细节测试通过./go.sh test驱动覆盖仓库根目录下除internal/testext、internal/extgen之外的所有 Go 包并额外进入caddy目录测试 Caddy 模块在linux/amd64平台上还会追加-race参数启用 Go 竞态检测器第 110-112 行对 fork 来源的 PR流水线只构建不推送load: true测试通过后即完成使命。场景二合并到 main 分支后的正式发布当 Pull Request 被合并后流水线进入正式发布路径GitHub Actions 再次运行测试并构建全新镜像构建成功后Registry 中的main标签被更新指向最新合并产物。main标签代表主干最新可用版本是日常开发中拉取最新 FrankenPHP 镜像最常用的标签。从 docker-bake.hcl 的tag()函数第 55-63 行可以看到main场景下流水线还会同时生成latest、latest-php{版本}-{OS}等别名标签方便不同需求按需拉取。镜像命名与多架构矩阵合并触发的构建并非单一架构而是完整的多架构矩阵。docker-bake.hcl 第 100-126 行定义了构建矩阵操作系统trixieDebian 最新、bookwormDebian 稳定版、alpine三种基础镜像PHP 版本默认覆盖 8.2/8.3/8.4/8.5PHP_VERSION变量第 9-11 行目标阶段builder编译工具链与runner运行时镜像双阶段平台linux/amd64、linux/386、linux/arm/v7、linux/arm64Alpine 额外支持linux/arm/v6第 114-126 行。构建任务会按平台分发到ubuntu-24.04或ubuntu-24.04-arm运行器docker.yaml 第 100 行最终在pushjob 中通过docker buildx imagetools create将各平台产物合并为多架构 Manifest第 259-265 行实现一个标签、多架构拉取。场景三创建版本标签的发布流程FrankenPHP 的版本发布完全由 Git 标签驱动这是原文档描述的第三条触发路径维护者在仓库中创建一个新标签如v1.2.3GitHub Actions 构建镜像并运行全部测试构建成功后镜像按标签名推送到 Registry——以v1.2.3为例会同时生成v1.2.3完整版本和v1.2主次版本两个标签latest标签同步更新到该版本。标签语义化背后的实现这套一个版本、多个标签的规则由 docker-bake.hcl 中的semver()函数实现第 73-88 行。它用正则解析v1.2.3形式的版本号拆分为 major / minor / patch 三部分进而生成v1.2.3完整版本号v1.2major.minor便于用户锁定次版本latest仅当该版本为默认 PHP 版本且为基础 OS 时生成同时非 tag 场景下还会附加sha-{commit前7位}格式的不可变标签第 130 行保证任意一次提交都能被精确追溯。所有标签都经过clean_tag()清洗第 68-71 行确保符合 Docker 标签的合法字符集并将非法字符替换为-。从标签到正式 Release 的完整链路版本标签触发的不止是镜像构建。.github/workflows/release.yaml 展示了从标签到正式发布的完整编排以workflow_dispatch传入语义化版本号刷新 PGO 性能剖析文件、升级caddy/go.mod依赖、通过 GitHub API 创建v{version}与caddy/v{version}双标签、起草 GitHub Release 草稿并向static.yaml、docker.yaml、windows.yaml三个下游工作流派发构建任务第 362-379 行。其中static.yaml负责产出 Linux/macOS 静态二进制并上传至 Release 资产。镜像构建的底层支撑双 Dockerfile 策略仓库根据运行目标提供两套构建文件Dockerfile基于 Debiantrixie/bookworm的通用镜像FROM php-base AS common后安装运行依赖、复制 caddy/frankenphp/Caddyfile 作为默认配置并以frankenphp run作为入口命令第 25 行alpine.Dockerfile基于 Alpine 的精简镜像额外支持linux/arm/v6等平台。两条路径都由docker-bake.hcl的defaulttarget 统一驱动通过dockerfile os alpine ? alpine.Dockerfile : Dockerfile动态选择第 111 行并注入FRANKENPHP_VERSION构建参数。可复现构建与安全加固从 docker-bake.hcl 可以看到流水线对镜像质量的两项硬性要求可复现性镜像标签记录org.opencontainers.image.created、version、revision等 OCI 标签第 134-146 行并通过BASE_FINGERPRINT记录基础镜像指纹每日定时重建时只重建基础镜像发生变化的变体避免无意义的全量构建供应链安全构建过程使用secret [idgithub-token,envGITHUB_TOKEN]第 150 行以 Secret 方式注入 GitHub Token且 docker.yaml 中pull_request触发被限制在main分支并做路径过滤仅docker-bake.hcl、**Dockerfile、**cgo.go、**.c/**.h/**.sh/**.stub.php等影响构建的文件变更才触发第 10-18 行既节省算力也缩小了攻击面。常见问题与排查要点基于上述源码结构在使用这套流水线时建议关注以下几点PR 不推送镜像从 fork 发起的 PR 只会构建并测试、不会推送避免恶意代码污染官方镜像如需验证可等待维护者合并后拉取main标签或在自建仓库中另行配置Secrets 名称必须与工作流一致官方流水线实际读取DOCKERHUB_USERNAME/DOCKERHUB_TOKEN文档中的REGISTRY_*四项适用于自行编写的通用模板——fork 自建时务必核对工作流实际引用的变量名标签格式约束版本标签必须形如v*.*.*如v1.2.3其他格式不会触发发布路径非语义化分支则生成sha-{7位提交号}标签平台覆盖差异arm/v6仅 Alpine 镜像支持Debian 系列不包含该平台拉取时需按需选择。总结FrankenPHP 的 GitHub Actions 流水线是一个触发事件驱动 Buildx 多架构构建 语义化标签推送的完整范例通过四个 Secrets 完成 Registry 认证通过 PR / 合并 / 标签三类事件分别产出pr-x、main与v1.2.3latest系列标签并在推送前以真实镜像运行全量 Go 测试作为质量门禁。无论是想深入理解镜像 CI 设计还是计划基于 FrankenPHP 搭建自己的发布流水线都可以直接参考 .github/workflows/docker.yaml、.github/workflows/release.yaml 与 docker-bake.hcl 这三份核心文件进行改造复用。【免费下载链接】frankenphp The modern PHP app server项目地址: https://gitcode.com/GitHub_Trending/fr/frankenphp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表