我目前正在尝试扩展我的一个Django API项目。它使用Postgres作为数据库。我正在使用Docker Cloud作为CI,以便可以构建,绒毛和运行测试。
我从以下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无法连接到任何数据库,而JusS会失败,但由于没有Postgres实例在此Dockerfile中运行
django.db.utils.OperationalError: could not translate host name "db"
to address: Name or service not known
然后,我在Docker Cloud中发现了一些称为" Autotest"的东西,使您可以使用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 Cloud将其构建。构建本身成功,但使用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?
因此,与我的本地计算机相比,DB服务似乎没有启动或太慢,无法在Docker Cloud上启动?
Google-ing稍后之后,我发现此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
to
command: ["./wait-for-postgres.sh", "db", "python", "src/manage.py",
"test"]
然后,我推到Github,Docker Cloud开始构建。构建图像有效,但现在是自动的,只是等待Postgres永远(我等待10分钟,然后手动关闭Docker Cloud中的构建过程(
(
我今天有Google-d有很多,似乎大多数" Dockerize django"教程根本没有提及单位测试。
我在使用Docker运行Django单元测试是完全错误的吗?
对我来说似乎很奇怪,它在本地运行完美,但是当Docker Cloud运行它时,它会失败!
我似乎已经通过将文件中的docker-compose版本从3.2降低到2.1并使用healthcheck来修复。
HealthCheck选项给我一个语法错误,因为您必须将数组传递到其中。不知道为什么版本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