CI ile docker-compose kullanarak - çıkış kodları ve arka plana bağlanan bağlantılı kaplar nasıl kullanılır?

Şu anda Jenkins temsilcilerimiz, Rails projelerimizin her biri için bir docker-compose.yml oluşturuyor ve ardından docker-compose çalıştırıyor. Docker-compose.yml, rbenv'ye ve içindeki diğer Rails bağımlılıklarına sahip ana bir "web" kabına sahiptir. Postgres DB testini içeren bir DB konteynerine bağlanır.

Sorun, testleri gerçekten çalıştırmamız ve çıkış kodları oluşturmamız gerektiğinde ortaya çıkar. CI sunucumuz yalnızca test komut dosyası exit 0 döndürürse dağıtılır, ancak docker-compose, konteyner komutlarından biri başarısız olsa bile her zaman 0 döndürür.

Diğer bir konu da, DB konteynerinin süresiz olarak çalışmasıdır, hatta web konteyner testleri yapıldıktan sonra bile, docker-compose up asla geri dönmez.

Bu işlem için liman oluşturucuyu kullanabileceğimiz bir yol var mı? Kapları çalıştırabilmemiz gerekir, ancak web kabı tamamlandıktan sonra çıkın ve çıkış kodunu döndürün. Şu anda DB konteynırını döndürmek ve web konteynırını --link seçeneğiyle çalıştırmak için docker'ı manuel olarak kullanıyoruz.

54

8 cevap

1.12.0 sürümünden beri, --exit-code-from seçeneğini kullanabilirsiniz.

belgelerinden :

--exit-code-SERVICE adresinden

     

Seçilen servis kabının çıkış kodunu döndür. Şu anlama gelir: - konteynere çıkışta çıkış.

40
katma
katma yazar subelsky, kaynak
docker-compose 1.12.0 ve daha üstü kullanıyorsanız, bunu yapmanın doğru yolu bu olmalıdır. Belki de senin durumundur. Bir örnek olabilir: docker-best up - exit-code-test biriminden . Senaryomun başına bir set -e ekleyene kadar benim için işe yaramadığını unutmayın.
katma yazar Adrian Antunez, kaynak
--exit-code-from , -d ile çalışmıyor. Bu hataları atar: --exit-code-from komutunu kullanan - code-container-exit-çıkış ve - container-exit -abort-çıkış ve -d birleştirilemez .
katma yazar ericat, kaynak

docker-compose run is the simple way to get the exit statuses you desire. For example:

$ 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

Alternatif olarak ölü kapları inceleme seçeneğiniz vardır. Sadece çıkış durumunu almak için -f bayrağını kullanabilirsiniz.

$ 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

Asla geri dönmeyen db kabına gelince, eğer docker-compose up kullanıyorsanız, bu kabı imzalamanız gerekir; Muhtemelen istediğin bu değildir. Bunun yerine, kaplarınızı daemonize etmek için docker-compose-d komutunu kullanabilir ve testiniz tamamlandığında kapları manuel olarak öldürebilirsiniz. docker-compose run sizin için bağlantılı kaplar çalıştırmalı, ancak şu anda amaçlandığı gibi çalışmasını önleyen bir hata hakkında SO hakkında sohbet ettim.

30
katma
@LoganSerman, docker-compose logs ile çıktıyı inceleyebilirsiniz.
katma yazar kojiro, kaynak
Sanırım neden -T ile çalıştığınızı anlamıyorum.
katma yazar kojiro, kaynak
Docker çalıştırma ile ilgili sorun, -T ile çalıştırıldığında herhangi bir çıktı vermemesidir ve çıktıyı istiyoruz, böylece başarısız yapıları inceleyebiliriz.
katma yazar Logan Serman, kaynak
CI inşaatı devam ederken görebilmemiz için, çalışma sırasında sürekli olarak bu kütükleri STDOUT'a yönlendirmenin bir yolu var mı?
katma yazar Logan Serman, kaynak
Konteynır içinde çalıştırdığımız komutların bir kısmı testleri yapmak için girdi isteme potansiyeline sahip, bunu önlemek için -T ile çalışmak istiyoruz. Örneğin Rbenv, daha önce varsa ruby sürümünü yeniden yüklemek isteyip istemediğinizi sorar.
katma yazar Logan Serman, kaynak

Kojiro'nun cevabı üzerine inşa:

liman işçisi-oluştur ps -q | xargs liman işçisi -f '{{.State.ExitCode}}' | grep -v 0 | wc -l | tr -d ''

  1. konteyner kimliklerini al
  2. her kapsayıcı kimliği için en son çalıştırma çıkış kodunu al
  3. yalnızca 0 olmayan durum kodları
  4. 0 olmayan durum kodlarının sayısını sayın
  5. beyaz alanı kesin

0 olmayan çıkış kodunun döndürdüğünü döndürür. Her şey 0 koduyla çıkarsa 0 olur.

19
katma
Sessiz olmayan çıktısını docker-compose ps 'dan de kullanabilirsiniz, örneğin: docker-compose ps | grep -c "Çıkış 1" , docker-compose ps ("sonuçların oldukça basılmış bir özet tablosunu sağlar) ekranında" Çıkış 1 "in eşleştiği yeri size gösterir. . Çıkış kodları "Durum" sütununda listelenmiştir.
katma yazar eharik, kaynak

Çıkış kodunu almak için docker wait tuşunu kullanın:

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

foo is the "project name". In the example above, I specified it explicitly, but if you don't supply it, it's the directory name. bar is the name you give to the system under test in your docker-compose.yml.

docker'ın -f günlüklerinin, konteyner durduğunda çıkarken doğru olanı yaptığına dikkat edin. Yani koyabilirsin

$ docker logs -f foo_bar_1

docker-compose up ile docker wait arasında, testlerin çalışmasını izleyebilirsiniz.

5
katma

Testlerinizi manuel olarak başlatmak için docker-compose run özelliğini kullanmak istiyorsanız, --rm bayrağını eklemeniz garip bir şekilde ekleyerek Compose’un komutunuzun çıkışını doğru şekilde yansıtmasına durumu.

İşte benim örneğim:

$ 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.
4
katma

--exit-code-from SERVICE and --abort-on-container-exit don't work in scenarios where you need to run all containers to completion, but fail if one of them exited early. An example might be if running 2 test suits in concurrently in different containers.

@ Spenthil'in önerisi ile, docker-compose 'ı herhangi bir kapsayıcı yaparsa başarısız olacak bir betiğe sarabilirsiniz.

#!/bin/bash
set -e

# Wrap docker-compose and return a non-zero exit code if any containers failed.

docker-compose "[email protected]"

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

Daha sonra, CI sunucunuzda docker-compose up./docker-compose.sh up olarak değiştirin.

3
katma
Bu betik, çıkış bölümüne hiçbir zaman sürekli erişmeyen diğer kaplar (veritabanları, web uygulamaları gibi) ulaşmaz. Müstakil modda çalışırken, konteynır hazırlanır kalkmaz çıkar.
katma yazar Baldy, kaynak
Yine de cevabını değiştirdi, çünkü beni orada en çok elde etti! Docker eklemek, her test kabında bağımsız modda beklemede kalmasını sağladı. Paylaşım için teşekkürler:)
katma yazar Baldy, kaynak
Bu doğru, bu işlem yalnızca tüm kapları tamamlanana kadar çalıştırmak istiyorsanız çalışır. Muhtemelen özellikle yaygın değil, ama yazı yazarken benim için faydalıydı ve paylaşacağımı düşündüm.
katma yazar Matt Cole, kaynak

docker-rails allows you to specify which container's error code is returned to the main process, so you CI server can determine the result. It is a great solution for CI and development for rails with docker.

Örneğin

exit_code: web

docker-rails.yml öğenizde docker-rails ci test komutunun sonucu olarak web konteyner çıkış kodunu verir. docker-rails.yml , yalnızca farklı ortamlar için aynı temel yapılandırmayı devralma/yeniden kullanma potansiyeline sahip olan, standart docker-compose.yml standardının etrafındaki meta paketleyicidir vs test vs paralel_testler.

1
katma

Var olan durumu şununla görebilirsiniz:

echo $(docker-compose ps | grep "servicename" | awk '{print $4}')
1
katma
@Stephen Rauch 'u doğru bir şekilde yerleştirdiğiniz için teşekkür ederiz.
katma yazar RT Bathula, kaynak