我正在尝试使用Docker-Compose和bash脚本构建ci进程来构建,测试和发布我的.NET Core应用程序。
我在一个文件夹中有UnitTests,IntegrationTests和XApi项目
并创建了DockerFile
和docker-compose.yml
,如下所示。
IntegrationTests
依赖于mongointegration
,因此我将links
和depends_on
属性添加到testandpublish
中的docker-compose.yml
服务。
当我尝试docker-compose up
或docker-compose up testandpublish
时,
它无法连接mongo。 (DockerFile - 第10步),mongo服务还没有开始(不明白为什么)
在步骤10中,如果我将RUN
更改为CMD
,则可以连接到mongo,docker-compose工作正常。但这次我无法检测测试失败或在我的sh脚本中成功,因为现在它不会破坏docker-compose up
命令..
我的问题是:为什么docker compose无法启动服务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"
答案 0 :(得分:4)
图像构建阶段和容器运行阶段是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
仅在启动依赖容器之前等待容器启动。它还不够聪明,无法等待容器内的过程准备就绪。 Proper dependencies can be done with a healthcheck
and a 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
使用Docker health check script后,通过Dockerfile将其复制到容器中。
#!/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
答案 1 :(得分:2)
RUN
步骤。而是在运行时执行CMD
步骤,并且已根据mongointegration容器启动Docker Compose。