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 up
nunca 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-compose
1.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 -e
al principio de mi script.--exit-code-from
aunque no funciona-d
.using --exit-code-from implies --abort-on-container-exit
--abort-on-container-exit and -d cannot be combined.
docker-compose run
es 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
-f
bandera 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 -d
para ejecutar sus contenedores demonizados y matar manualmente los contenedores cuando se complete la prueba.docker-compose run
deberí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
-T
Sobre 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 run
para iniciar manualmente sus pruebas, agregar la--rm
bandera, 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 wait
para obtener el código de salida:foo
es el "nombre del proyecto". En el ejemplo anterior, lo especifiqué explícitamente, pero si no lo proporciona, es el nombre del directorio.bar
es el nombre que le da al sistema bajo prueba en su docker-compose.yml.Tenga en cuenta que también
docker logs -f
hace lo correcto al salir cuando el contenedor se detiene. Entonces puedes ponerentre el
docker-compose up
y eldocker wait
para que pueda ver cómo se ejecutan sus pruebas.fuente
--exit-code-from SERVICE
y--abort-on-container-exit
no 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-compose
un script que fallará si lo hace algún contenedor.Luego, en su servidor CI simplemente cambie
docker-compose up
a./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.yml
generará elweb
código de salida de los contenedores como resultado del comandodocker-rails ci test
.docker-rails.yml
es solo una meta envoltura alrededor del estándardocker-compose.yml
que 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