没有OOM异常时Docker-compose退出代码为137

标签 docker docker-compose cypress

当我运行以下命令时,我期望退出代码为0,因为combined容器运行的测试成功退出,退出代码为0。

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

不幸的是,即使我的combined容器中的测试成功运行并且我以0的退出代码退出该容器,我也始终收到137的退出代码(有关如何执行此操作的更多详细信息,在下面指定)。

以下是我的docker-compose版本:
docker-compose version 1.25.0, build 0a186604

根据此post,137的退出代码可能归因于两个主要问题。
  • 容器收到了docker stop,并且应用程序无法正常处理SIGTERM
  • 容器已用完内存(OOM)。

  • 我知道137退出代码不是因为我的容器内存不足。运行docker inspect <container-id>时,我可以看到“OOMKilled”为假,如下面的代码片段所示。我还为Docker Engine分配了6GB的内存,这对我的应用程序来说足够了。
    [
        {
            "Id": "db4a48c8e4bab69edff479b59d7697362762a8083db2b2088c58945fcb005625",
            "Created": "2019-12-12T01:43:16.9813461Z",
            "Path": "/scripts/init.sh",
            "Args": [],
            "State": {
                "Status": "exited",
                "Running": false,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false, <---- shows container did not run out of memory
                "Dead": false,
                "Pid": 0,
                "ExitCode": 137,
                "Error": "",
                "StartedAt": "2019-12-12T01:44:01.346592Z",
                "FinishedAt": "2019-12-12T01:44:11.5407553Z"
            },
    

    我的容器没有从docker stop退出,因此我也不认为第一个原因与我的情况有关。

    如何设置我的Docker容器

    我有两个Docker容器:
  • b-db -包含我的数据库
  • 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:
    

    以下是combineddocker-compose.yml服务的Dockerfile。
    FROM cypress/included:3.4.1
    
    WORKDIR /usr/src/app
    
    COPY package*.json ./
    
    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
    

    下面是我运行docker-compose up --build --exit-code-from combined; echo $?时输出的最后几行。
    ...
    b-combined | user disconnected
    b-combined | Mongoose disconnected
    b-combined | Mongoose disconnected through Heroku app shutdown
    b-combined | TEST ENDED WITH EXIT CODE OF: 0 ===========================
    b-combined | EXITING SCRIPT WITH EXIT CODE OF: 0 =====================================
    Aborting on container exit...
    Stopping b-combined   ... done
    137
    

    正如上面所看到的,令人困惑的是,由于我的所有测试均成功通过,因此测试和脚本以退出代码0结束,但是容器仍以137的退出代码退出。

    更令人困惑的是,当我从init.sh文件中注释掉以下行(运行我的Cypress集成测试)时,容器退出,退出代码为0,如下所示。
    NODE_ENV=test $(npm bin)/cypress run --config video=false --browser chrome
    

    下面是当我注释掉/从init.sh中删除以上行时收到的输出,这是运行Cypress集成测试的命令。
    ...
    b-combined | TEST ENDED WITH EXIT CODE OF: 0 ===========================
    b-combined | EXITING SCRIPT WITH EXIT CODE OF: 0 =====================================
    Aborting on container exit...
    Stopping b-combined   ... done
    0
    

    如何在测试成功运行时让docker-compose返回零退出代码,而在测试失败时返回非零退出代码?

    编辑:

    在 Debug模式下运行以下docker-compose命令后,我注意到b-db似乎在关闭时遇到了一些问题,因此可能正在从Docker接收到SIGKILL信号。
    docker-compose --log-level DEBUG up --build --exit-code-from combined; echo $?
    

    根据以下输出,确实是这种情况吗?
    ...
    b-combined exited with code 0
    Aborting on container exit...
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/json?limit=-1&all=1&size=0&trunc_cmd=0&filters=%7B%22label%22%3A+%5B%22com.docker.compose.project%3Db-property%22%2C+%22com.docker.compose.oneoff%3DFalse%22%5D%7D HTTP/1.1" 200 3819
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/json?limit=-1&all=0&size=0&trunc_cmd=0&filters=%7B%22label%22%3A+%5B%22com.docker.compose.project%3Db-property%22%2C+%22com.docker.compose.oneoff%3DFalse%22%5D%7D HTTP/1.1" 200 4039
    http://localhost:None "POST /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/attach?logs=0&stdout=1&stderr=1&stream=1 HTTP/1.1" 101 0
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/json HTTP/1.1" 200 None
    Stopping b-combined   ...
    Stopping b-db         ...
    Pending: {<Container: b-db (0626d6)>, <Container: b-combined (196f3e)>}
    Starting producer thread for <Container: b-combined (196f3e)>
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    Pending: {<Container: b-db (0626d6)>}
    http://localhost:None "POST /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/wait HTTP/1.1" 200 32
    http://localhost:None "POST /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/stop?t=10 HTTP/1.1" 204 0
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "POST /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561bStopping b-combined   ... done
    Finished processing: <Container: b-combined (196f3e)>
    Pending: {<Container: b-db (0626d6)>}
    Starting producer thread for <Container: b-db (0626d6)>
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/json HTTP/1.1" 200 None
    Pending: set()
    Pending: set()
    Pending: set()
    Pending: set()
    Pending: set()
    Pending: set()
    http://localhost:None "GET /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/json HTTP/1.1" 200 None
    http://localhost:None "POST /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/stop?t=10 HTTP/1.1" 204 0
    http://localhost:None "POST /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/wait HTTP/1.1" 200 30
    Stopping b-db         ... done
    Pending: set()
    http://localhost:None "GET /v1.25/containers/0626d6bf49e5236440c82de4e969f31f4f86280d6f8f555f05b157fa53bae9b8/json HTTP/1.1" 200 None
    http://localhost:None "GET /v1.25/containers/196f3e622847b4c4c82d8d761f9f19155561be961eecfe874bbb04def5b7c9e5/json HTTP/1.1" 200 None
    137
    

    最佳答案

    错误消息使我震惊:Aborting on container exit...docker-compose docs:

    --abort-on-container-exit Stops all containers if any container was stopped.


    您是否正在使用此标志运行docker-compose?如果是这种情况,请考虑这意味着什么。b-combined完成后,就直接退出。这意味着,容器b-db也将被强制停止。即使b-combined返回的退出代码为0,mongodb也可能无法正常处理b-db强制关闭。
    编辑:我刚刚意识到您在命令行中有--exit-code-from。这意味着--abort-on-container-exit
    解决方案:b-db需要更多时间才能正常退出。使用docker-compose up --timeout 600可以避免该错误。

    关于没有OOM异常时Docker-compose退出代码为137,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59296801/

    相关文章:

    mysql - 尝试使用 docker 连接 MySQL 和 Gogs 容器时出错

    cypress - 如果 Cypress 中不存在元素,如何跳过测试

    javascript - 检查 Cypress 中的单选按钮

    docker - 如何在docker-compose up -d期间大声失败?

    docker - 如何借助docker compose正确设置golang应用的第三方库?

    nginx - 无法启动openresty docker

    java - Docker 容器中 PostgreSQL 数据库的正确 JDBC 连接 URL

    cypress - 如何忽略 cypress cy.visit 中的某些获取请求

    Python 基础镜像 vs Ubuntu 基础镜像在 docker 中单独安装 python

    logging - 通过配置日志驱动程序将 Docker 容器日志发送到 ELK Stack - 简单方法