我在 Ubuntu 中有服务器。在服务器上我安装了
docker compose
(v2.29.7)。我创建了脚本 ssl-renew.sh
通过 crontab 定期更新 certbot 证书。 Certbot 通过 docker 运行的方式与我的 nginx 相同,它们位于相同的docker-compose.yml
我没有“docker-compose”,因为它给了我这个错误:
DockerException: Error while fetching server API version: HTTPConnection.request()
,并且修复已明确说明here - 只需移至最新的“docker compose”而不带破折号
问题是当我尝试捕获输出时,“docker compose”版本不起作用。
脚本失败的部分:
#!/bin/bash
set -x
DOCKER_COMPOSE_FILE="/services/nginx/docker-compose.yml"
echo "starting renewal"
output=$(/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal 2>&1)
echo "docker script has run"
输出始终相同:
+ DOCKER_COMPOSE_FILE=/services/nginx/docker-compose.yml
+ echo 'starting renewal'
starting renewal
++ /usr/bin/docker compose -f /services/nginx/docker-compose.yml run --rm certbot renew --force-renewal
它永远不会达到
echo "docker script has run"
。当我删除脚本中的这一行时,该命令不是交互式的:
#output=$(/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal 2>&1)
/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal
正在工作:
+ DOCKER_COMPOSE_FILE=/services/nginx/docker-compose.yml
+ echo 'starting renewal'
starting renewal
+ /usr/bin/docker compose -f /services/nginx/docker-compose.yml run --rm certbot renew --force-renewal
WARN[0000] /services/nginx/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewing an existing certificate for example.com
Failed to renew certificate example.com with error: urn:ietf:params:acme:error:rateLimited
现在它运行命令并且终端没有冻结,但我想捕获输出并通过 API 将其发送到日志记录提供程序。我目前尝试了 Google 和 GPT 中的所有方法,但没有任何帮助。如果您有任何建议,我将不胜感激。
有几点需要注意。
您正在使用命令替换,如下所示
output=$(/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal 2>&1)
在您的情况下,您将
$()
中命令的输出分配给变量名称 output
。如果您要打印 output
变量的值(例如 echo "$output"
),您将看到内部 $()
命令的输出,例如docker compose
。
当我将脚本中的行删除到这一行时......它正在工作
从您共享的输出来看,它似乎没有“工作”,因为它仍然无法打印
+ echo "docker script has run"
这意味着
docker compose
不会终止,并且脚本永远不会到达 echo "docker script has run"
行。