Dokku 基于 Docker 镜像的应用部署指南:git:from-image 与 git:load-image 实战详解
发布时间:2026/9/10 10:47:32 锦皓数字建站

Dokku 基于 Docker 镜像的应用部署指南git:from-image 与 git:load-image 实战详解【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku导读在 Dokku一个基于 Docker 的 PaaS 平台中应用仓库通常由git push推送的源码构成但在镜像已经由 CI/CD 流水线构建完成、只想直接部署的场景下源码反而不是最优载体。本文讲解 Dokku 提供的两条专为镜像部署设计的能力git:from-image从镜像仓库中的镜像初始化/更新应用0.24.0 引入与git:load-image从标准输入流加载镜像 tar 归档0.30.0 引入。读完本文你将掌握如何把任意 Docker 镜像作为应用部署源、如何解决镜像拉取与幂等重建问题、如何配置私有镜像登录与自定义构建上下文以及这两条命令在源码层的完整执行链路。一、为什么需要从镜像初始化应用仓库Dokku 的应用模型以 git 仓库为核心部署时 Dokku 接收代码、识别构建方式buildpack / Dockerfile / CNB 等并产出可运行镜像。但有一种常见场景无法套用这套模型——代码根本不在这台 Dokku 主机上应用镜像在远程 CI/CD 流水线中构建完成只希望 Dokku 负责运行团队不维护 Dokku 主机上的源码副本镜像就是唯一交付物需要持续跟踪某个第三方基础镜像的变更。Dokku 的解法是让一个只含一行 FROM 的 Dockerfile成为应用仓库的全部内容。git:from-image与git:load-image负责把这条FROM写入应用仓库其余构建、部署流程与普通 Dockerfile 部署完全一致。关联文档docs/deployment/methods/image.md二、git:from-image从镜像仓库初始化应用2.1 基本用法git:from-image会初始化一个应用仓库或将其更新为包含指定镜像的FROM指令dokku git:from-image node-js-app my-registry/node-js-getting-started:latest执行后Dokku 会像仓库中只包含下面这个 Dockerfile 一样构建应用FROM my-registry/node-js-getting-started:latest这是跟踪只部署某个镜像变更的极佳方式尤其是镜像由远端 CI/CD 流水线推送的场景——仓库里没有代码只有对镜像的引用。2.2 本地已存在镜像时的拉取行为与 --force如果指定镜像已经存在于 Dokku 主机Dokku 不会再次拉取这是源码中明确的分支判断先通过docker image ls -q $DOCKER_IMAGE检查本地是否已有该镜像有则跳过docker image pull参见 plugins/git/git-from-image。当远端镜像已更新、但 tag 保持不变时需要强制重新拉取dokku git:from-image --force node-js-app my-registry/node-js-getting-started:latest--force在实现上通过设置DOKKU_APPS_FORCE_DELETE1环境变量来启用强制拉取分支见 plugins/git/internal-functions。2.3 幂等性与镜像摘要digest避免无变更提前退出对相同参数重复触发构建时Dokku 检测不到任何变更会提前以 0 退出不会产生新的部署。源码对应分支在 plugins/git/git-from-directory当git diff-index --quiet HEAD --判定无差异时会输出No changes detected, skipping git commit警告并跳过提交。因此如果 tag 被复用但底层镜像内容已变化强烈建议改用镜像 digest 而不是 tag。可通过以下命令获取 digest# 适用于已推送到远端 registry 的镜像 docker inspect --format{{index .RepoDigests 0}} $IMAGE_NAME # 适用于本地构建、未推送的镜像 # 当上面命令输出为空时使用 docker images --no-trunc --quiet $IMAGE_NAME将 digest 用于git:from-image# 其中镜像 sha 为sha256:9d187c3025d03c033dcc71e3a284fee53be88cc4c0356a19242758bc80cab673 dokku git:from-image node-js-app my-registry/node-js-getting-startedsha256:9d187c3025d03c033dcc71e3a284fee53be88cc4c0356a19242758bc80cab6732.4 自定义提交作者git:from-image可选地接受 gituser.name与user.email按此顺序来定制提交作者留空时分别回退为Dokku与automateddokku.shdokku git:from-image node-js-app my-registry/node-js-getting-started:latest Camila camilaexample.com2.5 私有镜像先登录 registry如果镜像是需要 docker login 才能访问的私有镜像应先用registry:login登录 registry完整流程参见 registry 管理文档。源码层面trigger-git-git-from-image会读取应用对应的DOCKER_CONFIG目录并导出fn-registry-docker-config-dir $APP从而让后续docker image pull使用已登录的凭证见 plugins/git/git-from-image。2.6 --build-dir自定义构建上下文部分镜像依赖ONBUILD ADD/ONBUILD COPY指令此时需要一个自定义构建上下文。通过--build-dir指定dokku git:from-image --build-dir path/to/build node-js-app domy-registrykku/node-js-getting-started:latest Camila camilaexample.com--build-dir下所有文件会被复制进仓库供docker build过程使用。两个关键限制构建上下文必须每次部署时都指定不会在构建之间持久化源码中会先校验目录存在性[[ ! -d $BUILD_DIR ]]时直接dokku_log_fail Invalid BUILD_DIR specified for docker build context随后用rsync -a将目录内容同步进临时工作目录见 plugins/git/git-from-image。关于 Dockerfile 部署的更多配置方式参见 Dockerfile 构建文档。三、git:load-image无 Registry 场景的镜像部署3.1 适用场景与基本用法当环境里没有 Docker Registry 充当镜像存储中介时例如在 CI 中构建镜像后直接部署镜像不出 CI 机器git:load-image可以从镜像归档 tar 文件初始化/更新应用仓库。镜像通过标准输入流传输典型的远端调用方式docker image save my-registry/node-js-getting-started:latest | ssh dokkudokku.me git:load-image node-js-app my-registry/node-js-getting-started:latest上述示例中docker image save把镜像打成 tar 流 → 经 ssh 管道传送到 Dokku 主机 →git:load-image在输入流上执行。与git:from-image一致Dokku 会像仓库只包含下面 Dockerfile 一样构建应用FROM my-registry/node-js-getting-started:latest3.2 唯一镜像 tag 建议通过git:load-image部署时强烈建议在构建镜像时使用唯一 tag。否则与git:from-image相同的无变更提前退出问题会出现复用 tag 会触发变更检测若检测不到变化Dokku 会以 0 提前退出。如果 tag 复用但底层镜像已变化同样建议改用 digest获取命令与上节完全相同# 适用于已推送到远端 registry 的镜像 docker inspect --format{{index .RepoDigests 0}} $IMAGE_NAME # 适用于本地构建、未推送的镜像 # 当上面命令输出为空时使用 docker images --no-trunc --quiet $IMAGE_NAME使用 digest 的调用示例# 其中镜像 sha 为sha256:9d187c3025d03c033dcc71e3a284fee53be88cc4c0356a19242758bc80cab673 docker image save my-registry/node-js-getting-started:latest | ssh dokkudokku.me git:load-image node-js-app my-registry/node-js-getting-startedsha256:9d187c3025d03c033dcc71e3a284fee53be88cc4c0356a19242758bc80cab6733.3 自定义提交作者与git:from-image相同可选传入 gituser.name与user.email按此顺序留空时回退为Dokku与automateddokku.shdocker image save my-registry/node-js-getting-started:latest | ssh dokkudokku.me git:load-image node-js-app my-registry/node-js-getting-started:latest Camila camilaexample.com3.4 --build-dir 自定义构建上下文同样支持--build-dir以兼容依赖ONBUILD ADD/ONBUILD COPY的镜像docker image save my-registry/node-js-getting-started:latest | ssh dokkudokku.me git:load-image --build-dir path/to/build node-js-app my-registry/node-js-getting-started:latest Camila camilaexample.com构建上下文同样每次部署都必须指定不跨构建持久化。Dockerfile 部署的其他配置方式参见 Dockerfile 构建文档。四、源码级执行链路解析了解底层调用链有助于排查问题与理解行为差异。两条命令的核心实现位于 git 插件的 internal-functionscmd-git-load-image见第 148 行、cmd-git-from-image见第 194 行外层入口分别为 plugins/git/subcommands/from-image 与 plugins/git/subcommands/load-image帮助信息定义在 plugins/git/help-functions。4.1 参数解析与前置校验两条命令共享相似的模式遍历参数识别--build-dir以及git:from-image独有的--force旗标剩余位置参数依次对应APP、DOCKER_IMAGE、USER_NAME、USER_EMAIL通过verify_app_name校验应用名合法性git:from-image在镜像参数为空时输出Please specify a docker image并失败退出git:load-image额外校验标准输入必须是管道流而非终端[[ ! -t 0 ]]否则报Expecting tar archive containing docker image on STDIN随后执行cat | docker load加载镜像再用fn-verify-app-image确认 tar 中确实包含指定镜像否则报Loaded image tarball but the specified docker image was not found。4.2 git-from-image 触发器生成构建上下文核心触发器 plugins/git/git-from-image 完成以下工作创建临时工作目录mktemp若指定了--build-dir用rsync -a同步构建上下文生成仅含两行的 DockerfileFROM $DOCKER_IMAGE与一条LABEL com.dokku.docker-image-labeler/alternate-tags[\$DOCKER_IMAGE\]后者用于镜像标签标注按需导出应用级DOCKER_CONFIG私有 registry 登录凭证镜像不存在时docker image pull存在但开启--force即DOKKU_APPS_FORCE_DELETE1时强制重新拉取否则跳过拉取通过fn-plugin-property-write git $APP source-image $DOCKER_IMAGE持久化镜像来源触发git-from-directory进入仓库写入阶段。4.3 git-from-directory 触发器初始化或更新仓库plugins/git/git-from-directory 负责真正的 git 操作首次初始化git init、切到计算出的部署分支fn-git-computed-deploy-branch、配置user.name/user.email、add --all后提交Initial commit更新已有仓库克隆现有应用仓库、复制新的构建上下文、add --all后通过diff-index --quiet HEAD --做变更检测——无变更时输出No changes detected, skipping git commit并提示可用ps:rebuild从既有源码重建有变更则以Automated commit timestamp提交并 fetch最后调用git_receive_app进入常规部署流程构建、发布、调度。这也解释了文档中相同参数重复触发会提前退出的根因镜像引用未变 → Dockerfile 未变 → git 无差异 → 跳过提交自然也就不会触发新的构建。4.4 部署源记录两条命令最终都会触发deploy-source-set $APP docker-image $DOCKER_IMAGE见 plugins/git/internal-functions 与第 191 行把应用的部署源标记为docker-image类型并记录镜像标识供报告展示与后续重建使用。这是与git:from-archive归档文件部署见 plugins/git/subcommands/from-archive并列的第三种非 push 式部署源。五、实践建议与适用边界场景推荐命令说明镜像在远端 registry主机可联网拉取git:from-image最直接主机自行管理拉取--force应对 tag 复用CI 构建产物直接部署无 registrygit:load-image镜像 tar 走 ssh 管道不落中间存储镜像 tag 复用且内容变化改用镜像 digest规避无变更提前退出私有镜像先registry:login应用级DOCKER_CONFIG自动生效依赖ONBUILD ADD/COPY的镜像配合--build-dir构建上下文每次部署都要指定不持久化几点边界提醒两条命令面向的是镜像即部署物的交付模式与常规源码 push 部署是互补关系不互相排斥部署源docker-image与提交作者均可通过命令参数定制未指定作者时统一回退为Dokku automateddokku.sh若需要从 git 仓库而非镜像初始化/更新应用仓库可参考同目录下的 git 部署文档 与 归档部署文档构建阶段的行为细节可进一步阅读 Dockerfile 构建文档。【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。