简体   繁体   English

Docker Cloud自动测试找不到服务

[英]Docker Cloud autotest cant find service

I am currently trying to dockerize one of my Django API projects. 我目前正在尝试对我的Django API项目之一进行docker化。 It uses postgres as the database. 它使用postgres作为数据库。 I am using Docker Cloud as a CI so that I can build, lint and run tests. 我将Docker Cloud用作CI,以便可以构建,运行和运行测试。

I started with the following DockerFile 我从以下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

But this DockerFile always fails as Django cant connect to any database when running the unit tests and justs fails with the following error as no postgres instance is running in this Dockerfile 但是此DockerFile始终失败,因为Django在运行单元测试时无法连接到任何数据库,并且由于以下错误而失败,因为此Dockerfile中未运行postgres实例

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

Then I discovered something called "Autotest" in Docker Cloud that allows you to use a docker-compose.text.yml file to describe a stack and then run some commands with each build. 然后,我在Docker Cloud中发现了一个称为“自动测试”的东西,它使您可以使用docker-compose.text.yml文件来描述堆栈,然后在每次构建时运行一些命令。 This seemed like what I needed to run the tests, as it would allow me to build my Django image, reference an already existing postgres image and run the tests. 这似乎是我运行测试所需要的,因为它将允许我构建Django映像,引用已经存在的postgres映像并运行测试。

I removed the 我删除了

 RUN python3 src/manage.py test

from the DockerFile and created the following docker-compose.test.yml file. 从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

Then when I run 那我跑的时候

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

and

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

locally, the tests all run and all pass. 在本地,所有测试都会运行并全部通过。

Then I push my changes to Github and Docker cloud builds it. 然后,我将更改推送到Github,并由Docker Cloud构建它。 The build itself succeeds but the autotest, using the docker-compose.test.yml file fails with the following error: 构建本身会成功,但使用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?

So it seems like the db service isnt being started or is too slow to start on Docker Cloud compared to my local machine? 如此看来,与我的本地计算机相比,db服务似乎没有启动或在Docker Cloud上启动太慢?

After Google-ing around a bit I found this https://docs.docker.com/compose/startup-order/ where it says that the containers dont really wait for each other to be a 100% ready. 在Google浏览了一下之后,我发现了这个https://docs.docker.com/compose/startup-order/ ,上面说容器并没有真正等待对方100%准备就绪。 Then they recommend writing a wrapper script to wait for postgres if that is really needed. 然后,他们建议编写包装器脚本以等待postgres(如果确实需要)。

I followed their instructions and used the wait-for-postgres.sh script. 我按照他们的指示使用了wait-for-postgres.sh脚本。

Juicy part: 多汁的部分:

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

and replaced the command in my docker-compose.test.yml from 并替换了我的docker-compose.test.yml中的命令

 command: python src/manage.py test

to

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

I then pushed to Github and Docker Cloud starts building. 然后我推到Github,开始构建Docker Cloud。 Building the image works but now the Autotest just waits for postgres forever (I waited for 10 minutes before manually shutting down the build process in Docker Cloud) 构建映像可以正常工作,但是现在自动测试只会永远等待postgres(我等待了10分钟,然后手动关闭了Docker Cloud中的构建过程)

I have Google-d a fair bit around today and it seems like most "Dockerize Django" tutorials dont really mention unit testing at all. 我今天有Google-d,似乎大多数“ Dockerize Django”教程都根本没有提到单元测试。

Am I running Django unit tests completely wrong using Docker? 我使用Docker运行Django单元测试是否完全错误?

Seems strange to me that it runs perfectly fine locally but when Docker Cloud runs it, it fails! 我似乎很奇怪,它在本地运行得很好,但是当Docker Cloud运行它时,它会失败!

I seem to have fixed it by downgrading the docker-compose version in the file from 3.2 to 2.1 and using healthcheck. 我似乎已通过将文件中的docker-compose版本从3.2降级到2.1并使用healthcheck修复了该问题。

The healthcheck option gives me a syntax error in depends_on clause as you have to pass an array into it. healthcheck选项在Depends_on子句中给我带来语法错误,因为您必须将数组传递给它。 No idea why this is not supported in version 3.2 不知道为什么3.2版不支持此功能

But here is my new docker-compose.test.yml that works 但是这是我的新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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM