En este momento, nuestros agentes de Jenkins generan un docker-compose.yml para cada uno de nuestros proyectos de Rails y luego ejecutan docker-compose. El docker-compose.yml tiene un contenedor "web" principal que tiene rbenv y todas nuestras otras dependencias de Rails dentro. Está vinculado a un contenedor de base de datos que contiene la base de datos de Postgres de prueba.
El problema surge cuando realmente necesitamos ejecutar las pruebas y generar códigos de salida. Nuestro servidor de CI solo se implementará si el script de prueba devuelve exit 0, pero docker-compose siempre devuelve 0, incluso si uno de los comandos del contenedor falla.
El otro problema es que el contenedor DB se ejecuta indefinidamente, incluso después de que el contenedor web haya terminado de ejecutar las pruebas, por lo que docker-compose upnunca regresa.
¿Hay alguna forma en que podamos usar docker-compose para este proceso? Necesitaríamos poder ejecutar los contenedores, pero salir después de que el contenedor web esté completo y devolver su código de salida. En este momento, estamos atascados manualmente al usar la ventana acoplable para activar el contenedor de base de datos y ejecutar el contenedor web con la opción --link.
fuente

docker-compose1.12.0 y superior. Quizás también sea tu caso. Un ejemplo podría ser:docker-compose up --exit-code-from test-unit. Tenga en cuenta que no funcionó para mí hasta que agregué unset -eal principio de mi script.--exit-code-fromaunque no funciona-d.using --exit-code-from implies --abort-on-container-exit--abort-on-container-exit and -d cannot be combined.docker-compose runes la forma sencilla de obtener los estados de salida que desee. Por ejemplo:Alternativamente, tiene la opción de inspeccionar los contenedores muertos. Puede usar la
-fbandera para obtener solo el estado de salida.En cuanto al contenedor de la base de datos que nunca regresa, si lo usa
docker-compose up, necesitará sigkill ese contenedor; probablemente eso no es lo que quieres. En su lugar, puede usardocker-compose up -dpara ejecutar sus contenedores demonizados y matar manualmente los contenedores cuando se complete la prueba.docker-compose rundebería ejecutar contenedores vinculados para usted, pero he escuchado charlas en SO sobre un error que impide que funcione como se esperaba en este momento.fuente
docker-compose logs-TSobre la base de la respuesta de kojiro:
docker-compose ps -q | xargs docker inspect -f '{{ .State.ExitCode }}' | grep -v '^0' | wc -l | tr -d ' 'Devuelve cuántos códigos de salida distintos de 0 se devolvieron. Sería 0 si todo saliera con el código 0.
fuente
docker-compose ps, por ejemplo:docker-compose ps | grep -c "Exit 1"le dará el recuento donde "Salida 1" se corresponde en la pantalla desdedocker-compose ps(que proporciona una tabla resumen de resultados bastante impresa). Los códigos de salida se enumeran en la columna "Estado".Si está dispuesto a usar
docker-compose runpara iniciar manualmente sus pruebas, agregar la--rmbandera, por extraño que parezca, hace que Compose refleje con precisión el estado de salida de su comando.Este es mi ejemplo:
fuente
(docker-compose run --rm ...) || exit $?para rescisión en caso de error. Útil en scripts bash.Úselo
docker waitpara obtener el código de salida:fooes el "nombre del proyecto". En el ejemplo anterior, lo especifiqué explícitamente, pero si no lo proporciona, es el nombre del directorio.bares el nombre que le da al sistema bajo prueba en su docker-compose.yml.Tenga en cuenta que también
docker logs -fhace lo correcto al salir cuando el contenedor se detiene. Entonces puedes ponerentre el
docker-compose upy eldocker waitpara que pueda ver cómo se ejecutan sus pruebas.fuente
--exit-code-from SERVICEy--abort-on-container-exitno funciona en escenarios en los que necesita ejecutar todos los contenedores hasta su finalización, pero falla si uno de ellos salió antes. Un ejemplo podría ser si se ejecutan 2 trajes de prueba simultáneamente en diferentes contenedores.Con la sugerencia de @ spenthil, puede incluir
docker-composeun script que fallará si lo hace algún contenedor.Luego, en su servidor CI simplemente cambie
docker-compose upa./docker-compose.sh up.fuente
docker-rails le permite especificar qué código de error del contenedor se devuelve al proceso principal, para que su servidor de CI pueda determinar el resultado. Es una gran solución para CI y desarrollo para rieles con Docker.
Por ejemplo
en su
docker-rails.ymlgenerará elwebcódigo de salida de los contenedores como resultado del comandodocker-rails ci test.docker-rails.ymles solo una meta envoltura alrededor del estándardocker-compose.ymlque le brinda la posibilidad de heredar / reutilizar la misma configuración base para diferentes entornos, es decir, desarrollo frente a prueba frente a pruebas paralelas.fuente
En caso de que pueda ejecutar más servicios de composición de Docker con el mismo nombre en un motor de Docker y no sepa el nombre exacto:
echo %?- devuelve el código de salida del servicio test-chromeBeneficios:
fuente
Puede ver el estado de salida con:
echo $(docker-compose ps | grep "servicename" | awk '{print $4}')fuente
docker-compose ps | grep servicename | grep -v 'Exit 0' && echo "Automation or integration tests failed." && exit 1