我正在尝试使用Docker-Compose和Bash脚本来构建,测试和发布我的.NET Core应用程序。
我有一个文件夹中的Unitests,IntegrationTests和XAPI项目并创建了DockerFile
和docker-compose.yml
。
IntegrationTests
取决于mongointegration
,因此我在docker-compose.yml
中的testandpublish
添加了links
和depends_on
属性。
当我尝试使用docker-compose up
或docker-compose up testandpublish
时它无法连接Mongo。(Dockerfile-步骤10),Mongo服务尚未启动(不明白为什么)
在步骤10中,如果我将RUN
更改为CMD
,它可以连接到Mongo,Docker-Compose可以正常工作。但是这一次我无法检测到测试失败或在我的SH脚本中取得成功,因为现在它不会打破docker-compose up
命令。
我的问题是:为什么Docker组成不启动服务mongointegration
?如果不可能,我该如何理解服务testandpublish
失败了?谢谢。
结构:
XProject
-src
-Tests
-UnitTests
-IntegrationTests
-Dockerfile
-docker-compose.yml
-XApi
我的dockerfile内容是(我在此处添加了行号来解释问题):
1.FROM microsoft/dotnet:1.1.0-sdk-projectjson
2.COPY . /app
3.WORKDIR /app/src/Tests/UnitTests
4.RUN ["dotnet", "restore"]
5.RUN ["dotnet", "build"]
6.RUN ["dotnet", "test"]
7.WORKDIR /app/src/Tests/IntegrationTests
8.RUN ["dotnet", "restore"]
9.RUN ["dotnet", "build"]
10.RUN ["dotnet", "test"]
11.WORKDIR /app/src/XApi
12.RUN ["dotnet", "restore"]
13.RUN ["dotnet", "build"]
14.CMD ["dotnet", "publish", "-c", "Release", "-o", "publish"]
和我的docker-compose.yml
version: "3"
services:
testandpublish:
build: .
links:
- mongointegration
depends_on:
- mongointegration
mongointegration:
image: mongo
ports:
- "27017:27017"
图像构建阶段和容器运行阶段是Docker-Compose中两个非常独立的步骤。
构建和运行差异
构建阶段从Dockerfile中的步骤中创建每个图像层。每个发生在独立容器中。除了特定于服务构建的build:
节外,您的服务配置都没有。
构建图像后,它可以作为容器运行,并带有其余的Docker-Compose服务配置。
,您可以创建一个脚本作为CMD
,而不是在dockerfile中运行测试,该脚本可以在容器中运行所有测试步骤。
#!/bin/sh
set -uex
cd /app/src/Tests/UnitTests
dotnet restore
dotnet build
dotnet test
cd /app/src/Tests/IntegrationTests
dotnet restore
dotnet build
dotnet test"
cd /app/src/XApi
dotnet restore
dotnet build
dotnet publish -c Release -o publish
如果microsoft/dotnet:1.1.0-sdk-projectjson
图像是Windows的,则可能需要将其转换为等效的CMD或PS命令。
容器依赖项
depends_on
的工作不如大多数人认为的那样。在简单的形式中,depends_on
仅等待容器启动,然后再进入启动依赖容器。它不够聪明,无法等待容器内部的过程。可以使用healthcheck
和condition
进行适当的依赖项。
services:
testandpublish:
build: .
links:
- mongointegration
depends_on:
mongointegration:
condition: service_healthy
mongointegration:
image: mongo
ports:
- "27017:27017"
healthcheck:
test: ["CMD", "docker-healthcheck"]
interval: 30s
timeout: s
retries: 3
通过Dockerfile复制到容器中后,使用Docker Health Check脚本。
#!/bin/bash
set -eo pipefail
host="$(hostname --ip-address || echo '127.0.0.1')"
if mongo --quiet "$host/test" --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 1)'; then
exit 0
fi
exit 1
RUN
docker构建图像并且尚无容器可用时执行步骤。而是在运行时间执行CMD
步骤,而Docker Compose已经开始根据MongeTementration容器开始。