热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Dockercompose退出代码应该为非零时似乎为零

我有两个Docker容器:b-db-包含我的数据库b组合

我有两个Docker容器:


  1. b-db -包含我的数据库

  2. b组合-包含我的Web应用程序和在容器启动并运行后运行的测试。

我正在使用docker-compose.yml文件启动两个容器。

version: '3'
services:
db:
build:
context: .
dockerfile: ./docker/db/Dockerfile
container_name: b-db
restart: unless-stopped
volumes:
- dbdata:/data/db
ports:
- "27017:27017"
networks:
- app-network
combined:
build:
context: .
dockerfile: ./docker/combined/Dockerfile
container_name: b-combined
restart: unless-stopped
env_file: .env
ports:
- "5000:5000"
- "8080:8080"
networks:
- app-network
depends_on:
- db
networks:
app-network:
driver: bridge
volumes:
dbdata:
node_modules:

我正在使用Jenkins启动容器并使用以下命令开始运行测试。我正在使用here,here和here的SO帖子概述的--exit-code-from

docker-compose up --build --exit-code-from combined

下面是我的Jenkinsfile的样子。

pipeline {
agent any
environment {
CI = 'true'
}
stages {
stage('Test') {
steps {
sh 'docker-compose up --build --exit-code-from combined'
}
}
}
}

运行我的测试时,b组合似乎按预期退出,并带有非零错误代码,该错误代码显示在控制台上,如下所示。这会触发两个容器都关闭,这也是预期的行为。


  

b组合退出,代码2

  
  

停止b组合...

  
  

停止b-db ...

  
  

停止b-db ...完成在容器出口中终止...

为什么Jenkins仍然显示测试已通过(请参见下面的屏幕截图)?在docker-compose up --build --exit-code-from combined命令非零退出后,詹金斯不应该失败吗?

Docker-compose退出代码应该为非零时似乎为零

此外,当我在本地命令行中(而不是在Jenkins中)运行上述docker-compose命令后立即运行以下命令时,我得到的错误代码为0,这表明问题不在于Jenkins但是使用docker-compose却无法识别出我正在使用非零退出代码退出init.sh

$ echo $?
0

根据@LinPy的以下建议,我在计算机上和Jenkins中本地运行了以下命令。

docker-compose up -d --build db && docker-compose up --build combined || exit 2; echo $?

我收到的输出如下。最后一行是echo $?的输出,它显示脚本仍然以错误代码0退出。

b-combined | Mongoose disconnected
b-combined | TEST ENDED WITH EXIT CODE OF: 2
b-combined | EXITING SCRIPT WITH EXIT CODE OF: 2
b-combined exited with code 2
0

下面是运行上述命令后的詹金斯截图:

Docker-compose退出代码应该为非零时似乎为零

为帮助调试,以下是combineddocker-compose.yml服务的Dockerfile。

RUN npm install
COPY . .
EXPOSE 5000
RUN npm install -g history-server nodemon
RUN npm run build-test
EXPOSE 8080
COPY ./docker/combined/init.sh /scripts/init.sh
RUN ["chmod","+x","/scripts/init.sh"]
ENTRYPOINT [ "/scripts/init.sh" ]

下面是我的init.sh文件中的内容。

#!/bin/bash
# Start front end server
history-server dist -p 8080 &
front_pid=$!
# Start back end server that interacts with DB
nodemon -L server &
back_pid=$!
# Run tests
NODE_ENV=test $(npm bin)/cypress run --config video=false --browser chrome
# Error code of the test
test_exit_code=$?
echo "TEST ENDED WITH EXIT CODE OF: $test_exit_code"
# End front and backend server
kill -9 $front_pid
kill -9 $back_pid
# Exit with the error code of the test
echo "EXITING SCRIPT WITH EXIT CODE OF: $test_exit_code"
exit "$test_exit_code"

以下是我的db服务的Dockerfile。它所做的就是将一些本地数据复制到Docker容器中,然后使用此数据初始化数据库。

FROM mongo:3.6.14-xenial
COPY ./dump/ /tmp/dump/
COPY mongo_restore.sh /docker-entrypoint-initdb.d/
RUN chmod 777 /docker-entrypoint-initdb.d/mongo_restore.sh

下面是mongo_restore.sh中的内容。

#!/bin/bash
# Creates db using copied data
mongorestore /tmp/dump

从@LinPy更新解决方案之后,我尝试了以下步骤。

下面是我的 combined Dockerfile的外观:

RUN npm install
COPY . .
EXPOSE 5000
RUN npm install -g history-server nodemon
RUN npm run build-test
EXPOSE 8080
COPY ./docker/combined/init.sh /scripts/init.sh
RUN ["chmod","/scripts/init.sh"]
ENTRYPOINT [ "/scripts/init.sh" ]
# NEW LINE ADDED HERE
CMD ["sh","-c","exit $(cat /scripts/exit_code)"]

下面是我的 init.sh文件的外观。

#!/bin/bash
# Start front end server
history-server dist -p 8080 &
front_pid=$!
# Start back end server that interacts with DB
nodemon -L server &
back_pid=$!
# Run tests
NODE_ENV=test $(npm bin)/cypress run --config video=false --browser chrome
# Error code of the test
test_exit_code=$?
echo "TEST ENDED WITH EXIT CODE OF: $test_exit_code"
# End front and backend server
kill -9 $front_pid
kill -9 $back_pid
# NEW LInes ADDED HERE
echo "$test_exit_code" > /scripts/exit_code
exec "$@"
# Exit with the error code of the test
echo "EXITING SCRIPT WITH EXIT CODE OF: $test_exit_code"
exit "$test_exit_code"

最后,我运行了以下命令:

docker-compose up -d --build db && docker-compose up --build combined || exit 2; echo $?

输出如下-最后一行(来自echo $?的输出)的退出代码为0。

b-combined | TEST ENDED WITH EXIT CODE OF: 2 ===========================
b-combined exited with code 2
0

解决方案:

我使用的是较早版本的docker-compose(低于v1.23.0)。正如您在docker-compose的release notes中所看到的那样,自v1.23.0起,--exit-code-from周围有一些错误修复。


我认为您的命令应该是:

docker-compose up --build --exit-code-from combined combined

通过这种方式,您将从combined获得退出代码

因为combined服务依赖于db,而该服务也将启动db服务。

我认为退出代码始终为0,因为--exit-code-from暗示着--abort-on-container-exit,而db将在退出时返回0

--abort-on-container-exit Stops all containers if any container was
stopped. Incompatible with -d. ...
--exit-code-from SERVICE Return the exit code of the selected service
container. Implies --abort-on-container-exit.

更新

尝试将其添加到脚本中,以代替最后一行:

#!/bin/bash
# Start front end server
history-server dist -p 8080 &
front_pid=$!
# Start back end server that interacts with DB
nodemon -L server &
back_pid=$!
# Run tests
NODE_ENV=test $(npm bin)/cypress run --config video=false --browser chrome
# Error code of the test
test_exit_code=$?
echo "TEST ENDED WITH EXIT CODE OF: $test_exit_code"
# End front and backend server
kill -9 $front_pid
kill -9 $back_pid
# Exit with the error code of the test
echo "EXITING SCRIPT WITH EXIT CODE OF: $test_exit_code"
echo "$test_exit_code" > /scripts/exit_code
exec "$@"

然后在您的Dockerfile中添加一个CMD

CMD ["sh","-c","exit $(cat /scripts/exit_code)"]

运行

docker-compose up --build --exit-code-from combined combined

,

如评论中所述,我无法通过简单的撰写文件来重现您的问题。如果下面的示例仍然为您提供退出代码0,则安装docker-compose可能会出现问题。并且,如果工作正常,那么问题将出在您的容器实际上没有以正确的退出代码退出。您还应该运行docker container ls -a来查看退出的容器及其退出代码,并在已停止的容器上运行docker logs来验证输出。这是我的工作示例:

$ cat docker-compose.exit-code.yml
version: '3'
services:
good:
image: busybox
command: /bin/sh -c "exit 0"
bad:
image: busybox
command: /bin/sh -c "exit 42"
$ docker-compose -f docker-compose.exit-code.yml up --exit-code-from bad
Starting test_good_1_69c61ee0bdc6 ... done
Starting test_bad_1_fbe3194c1994 ... done
Attaching to test_bad_1_fbe3194c1994,test_good_1_69c61ee0bdc6
test_bad_1_fbe3194c1994 exited with code 42
Aborting on container exit...
$ echo $?
42
$ docker-compose -f docker-compose.exit-code.yml up --exit-code-from good
Starting test_good_1_69c61ee0bdc6 ... done
Starting test_bad_1_fbe3194c1994 ... done
Attaching to test_good_1_69c61ee0bdc6,test_bad_1_fbe3194c1994
test_good_1_69c61ee0bdc6 exited with code 0
Aborting on container exit...
$ echo $?
0

推荐阅读
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了多因子选股模型在实际中的构建步骤,包括风险源分析、因子筛选和体系构建,并进行了模拟实证回测。在风险源分析中,从宏观、行业、公司和特殊因素四个角度分析了影响资产价格的因素。具体包括宏观经济运行和宏经济政策对证券市场的影响,以及行业类型、行业生命周期和行业政策对股票价格的影响。 ... [详细]
  • 本文介绍了如何使用iptables添加非对称的NAT规则段,以实现内网穿透和端口转发的功能。通过查阅相关文章,得出了解决方案,即当匹配的端口在映射端口的区间内时,可以成功进行端口转发。详细的操作步骤和命令示例也在文章中给出。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
author-avatar
老娘叫凌凌_523
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有