Docker Cloud自动测试无法找到服务

时间:2017-06-25 12:38:34

标签: django docker docker-compose dockerfile docker-cloud

我目前正在尝试将我的一个Django API项目停靠。它使用postgres作为数据库。我使用Docker Cloud作为CI,以便我可以构建,lint和运行测试。

我开始使用以下DockerFile

# Start with a python 3.6 image
FROM python:3.6

ENV PYTHONUNBUFFERED 1
ENV POSTGRES_USER postgres 
ENV POSTGRES_PASSWORD xxx 
ENV DB_HOST db 

RUN mkdir /code

ADD . /code/

WORKDIR /code

RUN pip install -r requirements.txt

RUN pylint **/*.py

# First tried running tests from here.

RUN python3 src/manage.py test

但是这个DockerFile总是失败,因为Django在运行单元测试时无法连接到任何数据库而justs因为没有postgres实例在此Dockerfile中运行而失败并出现以下错误

django.db.utils.OperationalError: could not translate host name "db" 
to address: Name or service not known

然后我在Docker Cloud中发现了一个名为“自动测试”的东西,它允许你使用docker-compose.text.yml文件来描述一个堆栈,然后在每个构建中运行一些命令。这似乎是我运行测试所需要的,因为它可以让我构建我的Django图像,引用已经存在的postgres图像并运行测试。

我删除了

 RUN python3 src/manage.py test
来自DockerFile的

并创建了以下docker-compose.test.yml文件。

 version: '3.2'

 services:
   db:
     image: postgres:9.6.3
     environment:
       - POSTGRES_USER=$POSTGRES_USER
       - POSTGRES_PASSWORD=$POSTGRES_PASSWORD

   sut:
     build: .
     command: python src/manage.py test
     environment:
       - POSTGRES_USER=$POSTGRES_USER
       - POSTGRES_PASSWORD=$POSTGRES_PASSWORD
       - DB_HOST=db
     depends_on:
       - db

然后当我跑

  docker-compose -f docker-compose.test.yml build

  docker-compose -f docker-compose.test.yml run sut

在本地,测试全部运行并全部通过。

然后我将我的更改推送到Github并且Docker云构建它。构建本身成功,但自动测试使用docker-compose.test.yml文件失败,并出现以下错误:

  django.db.utils.OperationalError: could not connect to server: 
  Connection refused
  Is the server running on host "db" (172.18.0.2) and accepting
  TCP/IP connections on port 5432?

因此,与我的本地计算机相比,似乎数据库服务没有启动或者启动Docker Cloud太慢了?

稍微谷歌后,我发现这个https://docs.docker.com/compose/startup-order/,其中表示容器并不真正等待彼此100%准备就绪。然后,如果确实需要,他们建议编写一个包装器脚本来等待postgres。

我按照他们的指示使用了wait-for-postgres.sh脚本。

多汁部分:

  until psql -h "$host" -U "postgres" -c '\l'; do
    >&2 echo "Postgres is unavailable - sleeping"
    sleep 1
  done

并替换了我的docker-compose.test.yml中的命令

 command: python src/manage.py test

 command: ["./wait-for-postgres.sh", "db", "python", "src/manage.py", 
 "test"]

然后我推送到Github,Docker Cloud开始建设。构建映像有效但现在Autotest只是等待postgres(我等了10分钟才手动关闭Docker Cloud中的构建过程)

今天我有一个Google-d,看起来大多数“Dockerize Django”教程都没有真正提到单元测试。

使用Docker运行Django单元测试是否完全错误?

我觉得它在本地运行得非常好,但是当Docker Cloud运行它时,它会失败!

1 个答案:

答案 0 :(得分:0)

我似乎已经通过将文件中的docker-compose版本从3.2降级到2.1并使用healthcheck来修复它。

healthcheck选项在depends_on子句中给出了语法错误,因为您必须将数组传递给它。不知道为什么在3.2版本中不支持这个。

但这是我的新docker-compose.test.yml工作

version: '2.1'

services:
  db:
    image: postgres:9.6.3
    environment:
      - POSTGRES_USER=$POSTGRES_USER
      - POSTGRES_PASSWORD=$POSTGRES_PASSWORD
    healthcheck:
      test: ["CMD-SHELL", "psql -h 'localhost' -U 'postgres' -c 
            '\\l'"]
      interval: 30s
      timeout: 30s
      retries: 3

 sut:
   build: .
   command: python3 src/manage.py test
   environment:
     - POSTGRES_USER=$POSTGRES_USER
     - POSTGRES_PASSWORD=$POSTGRES_PASSWORD
     - DB_HOST=db
   depends_on:
   // Does not work in 3.2
     db:
       condition: service_healthy