Cara menjalankan build di kontainer Docker dari Jenkins

18

Saya mencoba menggunakan Jenkins untuk membangun proyek C ++ di wadah Docker. Saya tidak punya masalah membangun di Jenkins, atau membangun di wadah di luar Jenkins.

Di bawah ini yang saya coba. Saya menghilangkan pemetaan volume untuk kejelasan.

Kasus 1

Perintah berikut berhasil menjalankan build di shell.

docker run --rm --interactive=true --tty=true $IMAGE make

Namun ketika dijalankan di Jenkins sebagai "eksekusi shell" langkah Docker mengembalikan kesalahan berikut.

cannot enable tty mode on non tty input

Kasus 2

Perintah berikut ini mirip dengan yang sebelumnya tetapi menonaktifkan interaktivitas.

docker run --rm $IMAGE make

Jenkins dapat menjalankan build dengan sukses. Namun ada masalah serius saat membatalkan pembangunan. Bangunan segera ditandai sebagai dibatalkan tetapi wadah terus berjalan sampai selesai. Juga wadah tidak dilepas setelah keluar.

Ketika dijalankan di shell, perintah berhasil dibuat tetapi tidak mungkin untuk menghentikannya. Wadah juga dilepas setelah keluar.

Pertanyaan

Adakah yang tahu cara menjalankan build dengan rapi dalam wadah Docker dari Jenkins dan mempertahankan kemampuan untuk membatalkan build?

Menggunakan salah satu plugin Jenkins bukanlah suatu pilihan karena panggilan Docker ada di dalam skrip dan tidak dapat diekstraksi dengan mudah.

marcv81
sumber
1
Mungkin dengan pekerjaan post-build yang tugasnya untuk menghapus wadah? Dan untuk kasus di mana Anda membatalkan pembangunan, mungkin Anda bisa memiliki bangunan khusus yang berhenti dan menghapus semua wadah palsu? Ini suboptimal tetapi setidaknya, ini merupakan solusi yang mudah untuk diatur. :-)
lgeorget
1
Ini tidak cukup cocok dengan definisi saya tentang bersih :) Tapi saya menghargai saran itu, dan itu tentu saja merupakan solusi yang valid.
marcv81

Jawaban:

3

Cara termudah untuk menjalankan bangunan buruh pelabuhan di Jenkins adalah dengan menggunakan pekerjaan saluran pipa. Sudah ada banyak plugin bawaan yang dapat mengontrol lingkungan dan wadah Docker Anda.

beberapa contohnya

    docker.image("image-name").run() -Runs the container from the image 
    docker.image("image-name").inside(){//your commands} -Runs your commands inside the docker container and also removes your container as soon as your commands are executed.

Untuk info lebih lanjut: https://www.cloudbees.com/blog/orchestrating-workflows-jenkins-and-docker

velsim
sumber
2

Anda dapat menerapkan alur kerja berikut:

  1. buat wadah buruh pelabuhan dan tentukan nama sedemikian rupa sehingga Anda dapat dengan mudah merujuknya (misalnya dalam skrip)
  2. mulai dan gunakan sesuatu sebagai titik masuk yang menjaga wadah berjalan
  3. Gunakan docker exec container cmd ...untuk mengeluarkan perintah build dan test Anda
  4. Hentikan wadahnya
  5. Hapus gambar

Ini docker exec ...seperti akses shell jarak jauh ke mesin jaringan. Secara default itu tidak interaktif dan juga tidak mengalokasikan tty. Ini harus baik untuk mengkompilasi dan menjalankan test suite. Perintah dengan benar meneruskan status keluar dari perintah yang dieksekusi di dalam wadah.

Pekerjaan build kemudian dapat dibatalkan melalui:

  • docker stop container (mengirim TERM dan KILL dan menunggu di antaranya), atau
  • docker kill container, atau bahkan
  • docker exec container pkill someexecutable

Alur kerja dengan perintah konkret:

$ docker create --name cxx-devel \
    -v $HOME/src:/srv/src:ro -v $HOME/build:/srv/build \
    gsauthof/fedora-cxx-devel:23
$ docker start cxx-devel     # <- entrypoint is /usr/bin/sleep infinity
$ docker exec cxx-devel /srv/src/projecta/build.sh
$ docker exec cxx-devel /srv/src/projecta/check.sh
$ docker stop cxx-devel
$ docker rm cxx-devel

Untuk contoh nyata yang menggunakan alur kerja ini, Anda dapat melihat file .travis.yml ini , skrip CI aktual , skrip yang berjalan di dalam wadah dan file buruh pelabuhan dari gambar yang digunakan.

maxschlepzig
sumber