지금 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 ' '
- 컨테이너 ID 가져 오기
- 각 컨테이너 ID에 대한 마지막 실행 종료 코드 가져 오기
- ‘0’으로 시작하지 않는 상태 코드 만
- 0이 아닌 상태 코드 수 계산
- 공백 제거
반환 된 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
“프로젝트 이름”입니다. 위의 예에서는 명시 적으로 지정했지만 제공하지 않으면 디렉터리 이름입니다. bar
docker-compose.yml에서 테스트중인 시스템에 제공하는 이름입니다.
참고 docker logs -f
컨테이너가 중지 될 때 종료도 옳은 일을한다. 그래서 당신은 넣을 수 있습니다
$ docker logs -f foo_bar_1
사이 docker-compose up
와 docker 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
입니다.