No momento, nossos agentes Jenkins geram um docker-compose.yml para cada um de nossos projetos Rails e, em seguida, executam docker-compose up. O docker-compose.yml tem um contêiner "web" principal que contém o rbenv e todas as outras dependências do Rails. Ele está vinculado a um contêiner de banco de dados que contém o banco de dados Postgres de teste.
O problema surge quando precisamos realmente executar os testes e gerar códigos de saída. Nosso servidor de CI só será implantado se o script de teste retornar a saída 0, mas docker-compose sempre retorna 0, mesmo se um dos comandos do contêiner falhar.
O outro problema é que o contêiner de banco de dados é executado indefinidamente, mesmo depois que o contêiner da web termina de executar os testes, portanto, docker-compose up
nunca retorna.
Existe uma maneira de usar docker-compose para esse processo? Precisaríamos ser capazes de executar os contêineres, mas sair depois que o contêiner da web for concluído e retornar seu código de saída. No momento, estamos travados manualmente usando o docker para ativar o contêiner DB e executar o contêiner da web com a opção --link.
fonte
docker-compose
1.12.0 e superior. Talvez seja o seu caso também. Um exemplo poderia ser:docker-compose up --exit-code-from test-unit
. Observe que não funcionou para mim até que eu adicionei umset -e
no início do meu script.--exit-code-from
não funciona-d
embora. Ele gerará estes erros:using --exit-code-from implies --abort-on-container-exit
e--abort-on-container-exit and -d cannot be combined.
docker-compose run
é a maneira simples de obter os status de saída desejados. Por exemplo:Como alternativa, você tem a opção de inspecionar os contêineres inativos. Você pode usar o
-f
sinalizador para obter apenas o status de saída.Quanto ao contêiner de banco de dados que nunca retorna, se você usar
docker-compose up
, será necessário assinar o contêiner; provavelmente não é isso que você quer. Em vez disso, você pode usardocker-compose up -d
para executar seus contêineres daemonizados e eliminar manualmente os contêineres quando o teste for concluído.docker-compose run
deve executar contêineres vinculados para você, mas ouvi conversas no SO sobre um bug que impede que funcione como pretendido agora.fonte
docker-compose logs
-T
Com base na resposta de Kojiro:
docker-compose ps -q | xargs docker inspect -f '{{ .State.ExitCode }}' | grep -v '^0' | wc -l | tr -d ' '
Retorna quantos códigos de saída diferentes de 0 foram retornados. Seria 0 se tudo saísse com o código 0.
fonte
docker-compose ps
, por exemplo:docker-compose ps | grep -c "Exit 1"
fornecerá a contagem de onde "Saída 1" é correspondida na exibiçãodocker-compose ps
(que fornece uma tabela de resumo de resultados bem impressa). Os códigos de saída estão listados na coluna "Estado".Se você deseja usar
docker-compose run
para iniciar manualmente seus testes, adicionar o--rm
sinalizador, por incrível que pareça, faz com que o Compose reflita com precisão o status de saída do comando.Aqui está meu exemplo:
fonte
(docker-compose run --rm ...) || exit $?
para rescisão em caso de erro. Útil em scripts bash.Use
docker wait
para obter o código de saída:foo
é o "nome do projeto". No exemplo acima, eu especifiquei explicitamente, mas se você não fornecer, é o nome do diretório.bar
é o nome que você dá ao sistema em teste em docker-compose.yml.Observe que também
docker logs -f
faz a coisa certa sair quando o contêiner parar. Então você pode colocarentre o
docker-compose up
e odocker wait
para que você possa assistir a execução de seus testes.fonte
--exit-code-from SERVICE
e--abort-on-container-exit
não funciona em cenários em que você precisa executar todos os contêineres até a conclusão, mas falha se um deles saiu antes do tempo. Um exemplo pode ser a execução de 2 conjuntos de teste simultaneamente em recipientes diferentes.Com a sugestão de @ gastouhil, você pode envolver
docker-compose
em um script que falhará se algum contêiner falhar.Em seguida, em seu servidor CI, simplesmente mude
docker-compose up
para./docker-compose.sh up
.fonte
docker-rails permite que você especifique qual código de erro do contêiner é retornado ao processo principal, para que seu servidor de CI possa determinar o resultado. É uma ótima solução para CI e desenvolvimento para trilhos com docker.
Por exemplo
em seu
docker-rails.yml
irá produzir oweb
código de saída dos contêineres como resultado do comandodocker-rails ci test
.docker-rails.yml
é apenas um meta wrapper em torno do padrãodocker-compose.yml
que oferece o potencial de herdar / reutilizar a mesma configuração de base para diferentes ambientes, ou seja, desenvolvimento vs teste vs parallel_tests.fonte
Caso você possa executar mais serviços docker-compose com o mesmo nome em um mecanismo docker e não saiba o nome exato:
echo %?
- retorna o código de saída do serviço test-chromeBenefícios:
fonte
Você pode ver o status de saída com:
echo $(docker-compose ps | grep "servicename" | awk '{print $4}')
fonte
docker-compose ps | grep servicename | grep -v 'Exit 0' && echo "Automation or integration tests failed." && exit 1