[docker] CI와 함께 docker-compose 사용-종료 코드 및 데몬 화 된 연결된 컨테이너를 처리하는 방법은 무엇입니까?

지금 Jenkins 에이전트는 각 Rails 프로젝트에 대해 docker-compose.yml을 생성 한 다음 docker-compose up을 실행합니다. docker-compose.yml에는 rbenv 및 기타 모든 Rails 종속성이 내부에있는 기본 “웹”컨테이너가 있습니다. 테스트 Postgres DB를 포함하는 DB 컨테이너에 연결됩니다.

문제는 실제로 테스트를 실행하고 종료 코드를 생성해야 할 때 발생합니다. CI 서버는 테스트 스크립트가 exit 0을 반환하는 경우에만 배포되지만 docker-compose는 컨테이너 명령 중 하나가 실패하더라도 항상 0을 반환합니다.

다른 문제는 웹 컨테이너가 테스트를 실행 한 후에도 DB 컨테이너가 무기한 실행되므로 docker-compose up반환되지 않는다는 것입니다.

이 프로세스에 docker-compose를 사용할 수있는 방법이 있습니까? 컨테이너를 실행할 수 있어야하지만 웹 컨테이너가 완료되면 종료하고 종료 코드를 반환해야합니다. 지금 당장은 Docker를 사용하여 DB 컨테이너를 회전하고 –link 옵션으로 웹 컨테이너를 실행하는 데 수동으로 멈춰 있습니다.



답변

버전부터 옵션을 1.12.0사용할 수 있습니다 --exit-code-from.

에서 문서 :

-서비스에서 코드 종료

선택한 서비스 컨테이너의 종료 코드를 반환합니다. –abort-on-container-exit를 의미합니다.


답변

docker-compose run원하는 종료 상태를 얻는 간단한 방법입니다. 예를 들면 :

$ cat docker-compose.yml
roit:
    image: busybox
    command: 'true'
naw:
    image: busybox
    command: 'false'
$ docker-compose run --rm roit; echo $?
Removing test_roit_run_1...
0
$ docker-compose run --rm naw; echo $?
Removing test_naw_run_1...
1

또는 죽은 컨테이너 를 검사 할 수있는 옵션이 있습니다. -f플래그를 사용 하여 종료 상태 만 가져올 수 있습니다 .

$ docker-compose up
Creating test_naw_1...
Creating test_roit_1...
Attaching to test_roit_1
test_roit_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
$ docker-compose ps -q | xargs docker inspect -f '{{ .Name }} exited with status {{ .State.ExitCode }}'
/test_naw_1 exited with status 1
/test_roit_1 exited with status 0

반환하지 않는 db 컨테이너의 경우 사용 docker-compose up하면 해당 컨테이너를 sigkill해야합니다. 그것은 아마도 당신이 원하는 것이 아닐 것입니다. 대신 docker-compose up -d데몬 화 된 컨테이너를 실행 하는 데 사용할 수 있으며 테스트가 완료되면 컨테이너를 수동으로 종료 할 수 있습니다. 링크 된 컨테이너를 실행 docker-compose run 해야 하지만 지금 의도 한대로 작동하지 못하게하는 버그에 대한 이야기를 들었습니다.


답변

코지로의 대답을 바탕으로 :

docker-compose ps -q | xargs docker inspect -f '{{ .State.ExitCode }}' | grep -v '^0' | wc -l | tr -d ' '

  1. 컨테이너 ID 가져 오기
  2. 각 컨테이너 ID에 대한 마지막 실행 종료 코드 가져 오기
  3. ‘0’으로 시작하지 않는 상태 코드 만
  4. 0이 아닌 상태 코드 수 계산
  5. 공백 제거

반환 된 0이 아닌 종료 코드 수를 반환합니다. 모든 것이 코드 0으로 종료되면 0이됩니다.


답변

docker-compose run테스트를 수동으로 시작하는 데 사용하려는 경우 --rm이상하게도 플래그를 추가 하면 Compose가 명령의 종료 상태를 정확하게 반영합니다.

내 예는 다음과 같습니다.

$ docker-compose -v
docker-compose version 1.7.0, build 0d7bf73

$ (docker-compose run bash false) || echo 'Test failed!'  # False negative.

$ (docker-compose run --rm bash false) || echo 'Test failed!'  # True positive.
Test failed!

$ (docker-compose run --rm bash true) || echo 'Test failed!'  # True negative.


답변

docker wait종료 코드를 가져 오는 데 사용 합니다.

$ docker-compose -p foo up -d
$ ret=$(docker wait foo_bar_1)

foo“프로젝트 이름”입니다. 위의 예에서는 명시 적으로 지정했지만 제공하지 않으면 디렉터리 이름입니다. bardocker-compose.yml에서 테스트중인 시스템에 제공하는 이름입니다.

참고 docker logs -f컨테이너가 중지 될 때 종료도 옳은 일을한다. 그래서 당신은 넣을 수 있습니다

$ docker logs -f foo_bar_1

사이 docker-compose updocker wait당신이 볼 수 있도록 테스트를 실행합니다.


답변

--exit-code-from SERVICE그리고 --abort-on-container-exit당신이 완료 모든 컨테이너를 실행할 수 있지만 그 중 하나가 조기 종료 경우 실패 할 필요가 시나리오에서 작업을하지 않습니다. 예를 들어 서로 다른 컨테이너에서 동시에 2 개의 테스트 슈트를 실행하는 경우가 있습니다.

@spenthil의 제안으로 docker-compose컨테이너가 실패하면 실패하는 스크립트를 래핑 할 수 있습니다 .

#!/bin/bash
set -e

# Wrap docker-compose and return a non-zero exit code if any containers failed.

docker-compose "$@"

exit $(docker-compose -f docker-compose.ci.build.yml ps -q | tr -d '[:space:]' |
  xargs docker inspect -f '{{ .State.ExitCode }}' | grep -v 0 | wc -l | tr -d '[:space:]')

그런 다음 CI 서버에 간단하게 변경 docker-compose up./docker-compose.sh up.


답변

docker-rails를 사용하면 기본 프로세스에 반환되는 컨테이너의 오류 코드를 지정할 수 있으므로 CI 서버가 결과를 확인할 수 있습니다. Docker를 사용한 레일 개발 및 CI를위한 훌륭한 솔루션입니다.

예를 들면

exit_code: web

당신의 docker-rails.yml수율 것이다 web명령의 결과로 컨테이너 종료 코드를 docker-rails ci test. 다른 환경 (예 : 개발 대 테스트 대 parallel_tests)에 대해 동일한 기본 구성을 상속 / 재사용 할 수있는 잠재력을 제공 docker-rails.yml하는 표준에 대한 메타 래퍼 docker-compose.yml입니다.