run imagenes hub docker docker-compose

imagenes - download docker image



Usando docker-compose con CI: ¿cómo lidiar con los códigos de salida y los contenedores enlazados demonizados? (9)

Desde la versión 1.12.0 , puede usar la opción --exit-code-from .

De la documentation :

--exit-code-from SERVICE

Devuelve el código de salida del contenedor de servicio seleccionado. Implica --abort-on-container-exit.

En este momento, nuestros agentes Jenkins generan un docker-compose.yml para cada uno de nuestros proyectos de Rails y luego ejecutan docker-compose. 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 prueba de Postgres.

El problema surge cuando necesitamos ejecutar las pruebas y generar códigos de salida. Nuestro servidor CI solo se desplegará si el script de prueba devuelve la salida 0, pero docker-compose siempre devuelve 0, incluso si falla uno de los comandos del contenedor.

El otro problema es que el contenedor de base de datos 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 manera de usar docker-compose para este proceso? Necesitaríamos poder ejecutar los contenedores, pero salga después de que el contenedor web esté completo y devuelva su código de salida. En este momento estamos atascados manualmente usando Docker para girar el contenedor de DB y ejecutar el contenedor web con la opción --link.


En caso de que pueda ejecutar más servicios de compilación de docker con el mismo nombre en un motor de docker, y no sabe el nombre exacto:

docker-compose up -d (exit "${$(docker-compose logs -f test-chrome)##* }")

echo %? - devuelve el código de salida del servicio test-chrome

Beneficios:

  • esperar a que salga el servicio exacto
  • usa el nombre del servicio, no el nombre del contenedor

Puede ver el estado existente con:

echo $(docker-compose ps | grep "servicename" | awk ''{print $4}'')


Si está dispuesto a utilizar la docker-compose run para iniciar manualmente sus pruebas, agregar el indicador --rm , por extraño que parezca, hace que Compose refleje con precisión el estado de salida de su comando.

Aquí está mi ejemplo:

$ docker-compose -v docker-compose version 1.7.0, build 0d7bf73 $ (docker-compose run kpi false) || echo ''Test failed!'' # False negative. $ (docker-compose run --rm kpi false) || echo ''Test failed!'' # True positive. Test failed! $ (docker-compose run --rm kpi true) || echo ''Test failed!'' # True negative.


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 '' ''

  1. obtener ID de contenedor
  2. obtener el código de salida de las últimas ejecuciones para cada ID de contenedor
  3. solo códigos de estado que no comienzan con ''0''
  4. cuenta el número de códigos de estado que no son 0
  5. recortar el espacio en blanco

Devuelve cuántos códigos de salida distintos de 0 se devolvieron. Sería 0 si todo saliera con el código 0.


Use docker wait para obtener el código de salida:

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

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 docker logs -f hace lo correcto, saliendo cuando el contenedor se detiene. Entonces puedes poner

$ docker logs -f foo_bar_1

entre el docker-compose up y el docker wait para que pueda ver cómo se ejecutan sus pruebas.


docker-rails permite especificar qué código de error del contenedor se devuelve al proceso principal, para que su servidor CI pueda determinar el resultado. Es una gran solución para CI y desarrollo para rieles con docker.

Por ejemplo

exit_code: web

en su docker-rails.yml generará el código de salida de los contenedores web como resultado del comando docker-rails ci test . docker-rails.yml es solo un meta envoltorio alrededor del estándar docker-compose.yml que le brinda el potencial de heredar / reutilizar la misma configuración base para diferentes entornos, es decir, desarrollo vs prueba vs prueba paralela.


--exit-code-from SERVICE y --abort-on-container-exit no funcionan 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 al mismo tiempo en diferentes contenedores.

Con la sugerencia de @ employeehil, puede envolver docker-compose en un script que fallará si algún contenedor lo hace.

#!/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:]'')

Luego, en su servidor CI, simplemente cambie docker-compose up ./docker-compose.sh up .


docker-compose run es la manera simple de obtener los estados de salida que desea. Por ejemplo:

$ 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

Alternativamente, tiene la opción de inspect los contenedores muertos. Puede usar la bandera -f para obtener solo el estado de salida.

$ 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

En cuanto al contenedor db que nunca regresa, si usa docker-compose up entonces deberá sigkill ese contenedor; eso probablemente no sea lo que quieres. En su lugar, puede usar docker-compose up -d para ejecutar sus contenedores daemonizados y eliminar manualmente los contenedores cuando se complete la prueba. docker-compose run debería ejecutar contenedores vinculados para usted, pero he escuchado comentarios sobre SO sobre un error que impide que funcione en este momento.