Dokku git push 报 [remote rejected] (pre-receive hook declined) 怎么排查?
【免费下载链接】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部署应用时,可能会看到这样的报错:
! [remote rejected] master -> master (pre-receive hook declined)这行报错本身不告诉你具体哪一步失败了。官方排查文档明确说明:remote rejected错误提供的信息不足,"Anything could have failed"——构建流水线中的任何一步都可能是失败点。Dokku 在应用通过git push创建时会生成pre-receivehook 来执行整条构建流水线(见 Git 部署文档),hook 中途被拒绝,客户端就只收到这一行remote rejected。所以排查路径是固定的:先打开 trace 模式拿到完整日志,再对照文档列举的已知原因逐项核对。报错中的master -> master表示推送分支到部署分支的映射,Dokku 默认部署分支为master。
第一步:开启 trace 模式复现推送
trace 模式自 Dokku 0.17.0 引入,在 Dokku 主机上执行:
dokku trace:on文档示例输出:
-----> Enabling trace modetrace 模式的作用是看到插件"在哪个位置"执行了原本不会预期的命令。它对 bash 插件会打开set -x标志;其他插件则可以自行尊重DOKKU_TRACE环境变量并采用不同的日志方式。默认的 Dokku 输出会约束每个命令打印的内容量,trace 模式把这个限制放开。
开启后,在本地重新执行同一条git push,完整记录从头到尾的输出。这就是后续定位失败阶段的依据。
第二步:查看失败部署的日志
用logs:failed取回上一次失败部署的日志:
dokku logs:failed node-js-app # 或者一次查看所有应用的失败日志 dokku logs:failed --all两个注意点:
- 默认 docker-local scheduler 会把这些日志保留到下一次部署或旧容器被垃圾回收为止(以先发生的为准)。如果需要在这之后还能查到,应把日志发到集中式日志服务器。
- 自 0.30.0 起,
logs:failed必须带应用名或--all标志,不带参数的旧调用方式已被移除。
第三步:按日志中的失败位置核对已知原因
trace 日志和失败日志会显示失败发生在哪个阶段。文档针对同一个remote rejected报错列举了下面几类原因,按现象逐条对照。
构建阶段失败、重试有时能通过:检查容器网络与 buildpack
文档指出,构建阶段(开启 tracing 后仍看到该报错)的大多数错误源于瞬时网络问题(本地或远端)或 buildpack bug。排查动作分两步:
- 找到失败阶段的容器镜像:
docker ps -a | grep build文档示例输出(示例结果):
94d9515e6d93 077581956a92 "/build" 29 minutes ago Exited (0) 25 minutes ago cocky_bell- 用该镜像启动一个新容器,进去检查(例如确认容器内能访问互联网,或重放已知失败的命令):
docker run -ti <image-id> /bin/bash curl -s -S icanhazip.com其中<image-id>替换为上一步输出中的失败阶段镜像 ID(文档示例中为077581956a92)。curl的文档示例输出是一个 IP 地址(如192.168.0.1),说明网络可达;若不通,问题就落在容器侧网络上。
文档还给出两条补充经验:
- 重新部署一次有时就能越过这类看似瞬时的故障(文档特别提到在 DigitalOcean 上常见)。
- 如果刚切换过 DNS 解析器不同的网络,可以执行
resolvconf -u更新resolv.conf。
没有明显报错但容器立即关闭:启动命令提前退出
文档列出的另一个原因是容器内运行的命令"正常退出"了。典型例子:在 Procfile 中定义一个运行 Delayed Job 的 worker,使用bin/delayed_job start命令——该命令会把进程守护化然后退出,容器认为任务已完成于是关闭自身,git push侧拿到的就是上面的remote rejected。
对应的修复方式是把 worker 改为使用不会守护化的命令,文档示例是改用rake jobs:work。核对方法:看 trace 日志里构建产物是否已经正常生成、但部署阶段的容器瞬间退出;是的话回到 Procfile 检查每个进程定义的命令是否会自行退出。
服务器内存不足:构建报Killed,或机器内存小于 1 GB
如果日志显示构建失败且带有Killed消息,文档把这归因于服务器内存耗尽,处理方式是给服务器加内存或配置交换空间。以下脚本(文档原文)创建 2 GB 交换空间。执行前注意它的副作用:需要 root 权限;会创建 2 GB 的/swapfile文件,并分别向/etc/fstab追加交换项、向/etc/sysctl.conf追加vm.swappiness = 10配置:
sudo install -o root -g root -m 0644 /dev/null /swapfile dd if=/dev/zero of=/swapfile bs=1k count=2048k mkswap /swapfile swapon /swapfile echo "/swapfile swap swap auto 0 0" | sudo tee -a /etc/fstab sudo sysctl -w vm.swappiness=10 echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf另一个直接命中本报错的场景记录在 进阶安装文档:当可供 Dokku 及其容器使用的系统内存不足 1 GB 时,可能出现! [remote rejected] master -> master (pre-receive hook declined)这类错误,文档以安装 NPM 依赖阶段为例(关联 npm 的 issue #3867)。文档建议把交换文件大小增大到至多两倍物理内存,并以 512 MB 机器为例给出了把交换空间调整到 1 GB 的操作步骤,需要时按该文档执行。
网络慢:buildpack 下载中断报gzip: stdin: unexpected end of file
如果部署输出中出现类似下面的内容:
Command: 'set -o pipefail; curl --fail --retry 3 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/ruby-2.0.0-p451-default-cache.tgz -s -o - | tar zxf -' failed unexpectedly: ! ! gzip: stdin: unexpected end of file ! tar: Unexpected EOF in archive ! tar: Unexpected EOF in archive ! tar: Error is not recoverable: exiting now可能是下载 buildpack 的 curl 命令在较慢的网络上耗时过长。要覆盖默认值(连接超时 90 秒、操作总时长上限 600 秒),文档给出以下全局配置(示例值):
dokku config:set --global CURL_TIMEOUT=1200 dokku config:set --global CURL_CONNECT_TIMEOUT=180文档还提到另一种原因:如果设置过名为SSL_CERT_FILE的配置项,会干扰 buildpack 下载依赖的能力(即使响应很快、排除了超时问题)。把该配置项改名为其他名字,例如MY_APP_SSL_CERT_FILE,即可。
收尾:验证与仍无法定位时
修复后重新执行同一条git push,判断标准是输出中不再出现! [remote rejected] master -> master (pre-receive hook declined),部署日志不再停在失败的那一步。
如果开启 trace 模式后仍无法定位,文档给出的建议是:把完整日志保存下来,创建一个 gist 并在上游项目提交 issue,把完整日志附上。排查结束后记得执行dokku trace:off关闭 trace 模式(输出-----> Disabling trace mode),恢复到默认的输出约束。
参考文档
- 排查文档(trace 模式与常见部署错误)
- 进阶安装文档(低内存虚拟机场景)
- 日志管理文档(logs:failed 与日志保留)
- Git 部署文档(pre-receive hook 与部署分支)
【免费下载链接】dokkuA docker-powered PaaS that helps you build and manage the lifecycle of applications项目地址: https://gitcode.com/GitHub_Trending/do/dokku
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考