Docker Compose不启动mongo服务,即使主服务依赖它

时间:2017-03-07 08:56:15

标签: docker continuous-integration docker-compose .net-core dockerfile

我正在尝试使用Docker-Compose和bash脚本构建ci进程来构建,测试和发布我的.NET Core应用程序。

我在一个文件夹中有UnitTests,IntegrationTests和XApi项目 并创建了DockerFiledocker-compose.yml,如下所示。

IntegrationTests依赖于mongointegration,因此我将linksdepends_on属性添加到testandpublish中的docker-compose.yml服务。

当我尝试docker-compose updocker-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"

2 个答案:

答案 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)

当Docker构建映像并且还没有可用的容器时,执行

RUN步骤。而是在运行时执行CMD步骤,并且已根据mongointegration容器启动Docker Compose。