当单元测试请求 docker 内置于 python 的容器时,连接中止

Connection aborted when unit test to request to docker container built in python

我的目标是编写一个构建 docker 容器并尝试对新建容器执行请求的单元测试。

测试首先构建一个docker镜像,然后运行镜像,最后尝试对新创建的容器执行请求。目前 运行 使用 py.test 的测试给了我

requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))

而 运行 ipython 中的相同代码工作得很好。

预期行为: py.test 给出了成功的结果。

测试

import pytest
import docker
import requests

@pytest.fixture(scope='module')
def docker_env():
    return docker.from_env()

@pytest.fixture(scope='module')
def docker_image(docker_env):
    client = docker_env
    image = client.images.build(path = ".", tag = "python-test:latest")
    yield image, client
    client.images.remove("python-test:latest")

def test_port(docker_image):
    image, client = docker_image
    client.containers.run("python-test:latest", 
                          entrypoint="/opt/conda/envs/python-docker-test/bin/gunicorn --config /usr/src/app/gunicorn.conf.py app:api",
                          detach=True,
                          ports={'8000/tcp': ('127.0.0.1', 8000)})

    resp = requests.get("http://127.0.0.1:8000/hello")
    assert resp.status == 200
    # Expect success, currently getting an error

Docker 文件

我的 docker 文件如下所示,

FROM phusion/baseimage:0.9.22
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8

RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
    libglib2.0-0 libxext6 libsm6 libxrender1 \
    git mercurial subversion

RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
    wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.3.30-Linux-x86_64.sh -O ~/miniconda.sh && \
    /bin/bash ~/miniconda.sh -b -p /opt/conda && \
    rm ~/miniconda.sh

ENV PATH /opt/conda/bin:$PATH

WORKDIR /usr/src/app
COPY . .

RUN conda env create -f environment.yml

EXPOSE 8000

SHELL ["/bin/bash", "-c"]

ENTRYPOINT  source activate python-docker-test && /opt/conda/envs/python-docker-test/bin/gunicorn \
  --config /usr/src/app/gunicorn.conf.py  app:api

app.py

import falcon

class TestServer:
    def on_get(self, req, resp):
        resp.content_type = "text/text"

        resp.body = "hello world"
        resp.status = falcon.HTTP_OK

api = falcon.API()
api.add_route("/hello", TestServer())

environment.yml

name: python-docker-test
channels:
 - anaconda
 - conda-forge
dependencies:
 - python==3.6
 - gunicorn==19.7.1
 - pytest==3.2.5
 - gunicorn==19.7.1
 - ipython
 - falcon==1.3.0
 - pip==9.0.1
 - pip:
   - docker==2.7.0

Gunicorn.conf.py

bind = '0.0.0.0:8000'

系统规格

正确的测试看起来像,

def test_port(docker_image):
    image, client = docker_image
    import time
    container = client.containers.run("python-test:latest",
                                      detach=True,
                                      ports={'8000/tcp': ('127.0.0.1', 8000)})

    time.sleep(1)
    resp = requests.get("http://127.0.0.1:8000/hello")

    container.kill()
    assert resp.status_code == 200