Saya menggunakan rabbitmq dan contoh python sederhana dari sini bersama dengan docker-compose. Masalah saya adalah saya harus menunggu rabbitmq untuk sepenuhnya dimulai. Dari apa yang saya cari sejauh ini, saya tidak tahu bagaimana menunggu dengan kontainer x (dalam pekerja kasus saya) sampai y (rabbitmq) dimulai.
Saya menemukan posting blog ini di mana dia memeriksa apakah host lain sedang online. Saya juga menemukan perintah buruh pelabuhan ini :
Tunggu
Penggunaan: buruh pelabuhan tunggu CONTAINER [CONTAINER ...]
Blokir hingga wadah berhenti, lalu cetak kode keluarnya.
Menunggu wadah untuk berhenti mungkin bukan yang saya cari, tetapi jika ya, apakah mungkin menggunakan perintah itu di dalam docker-compose.yml? Solusi saya sejauh ini adalah menunggu beberapa detik dan memeriksa port, tetapi apakah ini cara untuk mencapai ini? Jika saya tidak menunggu saya mendapatkan kesalahan.
docker-compose.yml
worker:
build: myapp/.
volumes:
- myapp/.:/usr/src/app:ro
links:
- rabbitmq
rabbitmq:
image: rabbitmq:3-management
contoh python hello (rabbit.py):
import pika
import time
import socket
pingcounter = 0
isreachable = False
while isreachable is False and pingcounter < 5:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('rabbitmq', 5672))
isreachable = True
except socket.error as e:
time.sleep(2)
pingcounter += 1
s.close()
if isreachable:
connection = pika.BlockingConnection(pika.ConnectionParameters(
host="rabbitmq"))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print (" [x] Sent 'Hello World!'")
connection.close()
Dockerfile untuk pekerja:
FROM python:2-onbuild
RUN ["pip", "install", "pika"]
CMD ["python","rabbit.py"]
Pembaruan November 2015 :
Script shell atau menunggu di dalam program Anda mungkin merupakan solusi yang mungkin. Tetapi setelah melihat Masalah ini saya mencari perintah atau fitur docker / docker-compose sendiri.
Mereka menyebutkan solusi untuk melaksanakan pemeriksaan kesehatan, yang mungkin merupakan pilihan terbaik. Koneksi tcp terbuka tidak berarti layanan Anda siap atau mungkin tetap siap. Selain itu saya perlu mengubah entri saya di dockerfile saya.
Jadi saya berharap untuk jawaban dengan komposisi buruh pelabuhan pada perintah papan, yang diharapkan akan terjadi jika mereka menyelesaikan masalah ini.
Pembaruan Maret 2016
Ada proposal untuk menyediakan cara bawaan untuk menentukan apakah sebuah wadah "hidup". Jadi komposisi buruh pelabuhan mungkin dapat menggunakannya dalam waktu dekat.
Perbarui Juni 2016
Tampaknya pemeriksaan kesehatan akan diintegrasikan ke dalam buruh pelabuhan di Versi 1.12.0
Perbarui Januari 2017
Saya menemukan solusi menyusun buruh pelabuhan lihat: Menulis Docker menunggu wadah X sebelum memulai Y
sumber
Jawaban:
Akhirnya menemukan solusi dengan metode menulis buruh pelabuhan. Karena format file komposisi pembuat galat 2.1 Anda dapat menentukan pemeriksaan kesehatan .
Saya melakukannya dalam proyek contoh Anda harus menginstal setidaknya buruh pelabuhan 1.12.0+. Saya juga perlu memperpanjang Dockerfile rabbitmq-manajemen , karena curl tidak diinstal pada gambar resmi.
Sekarang saya menguji apakah halaman manajemen rabbitmq-container tersedia. Jika ikal selesai dengan exitcode 0 aplikasi wadah (python pika) akan dimulai dan mempublikasikan pesan ke halo antrian. Sekarang berfungsi (output).
docker-compose (versi 2.1):
keluaran:
Dockerfile (rabbitmq + curl):
Versi 3 tidak lagi mendukung bentuk kondisi depend_on . Jadi saya pindah dari depend_on ke restart on-failure. Sekarang wadah aplikasi saya akan memulai ulang 2-3 kali sampai berfungsi, tetapi masih merupakan fitur menulis buruh pelabuhan tanpa menimpa titik masuk.
docker-compose (versi 3):
sumber
ping
menggunakan ICMP sehingga tidak mendukung port TCP. Mungkinnc
untuk menguji port TCP. Mungkin lebih baik menggunakanpsql -h localhost -p 5432
dan menanyakan sesuatu.condition
bentukdepends_on
dihapus, tetapidepends_on
itu sendiri masih ada di v3depends_on
dengancondition
telah dihapus?Secara native itu belum memungkinkan. Lihat juga permintaan fitur ini .
Sejauh ini Anda perlu melakukan itu dalam wadah Anda
CMD
untuk menunggu sampai semua layanan yang diperlukan ada di sana.Dalam
Dockerfile
sCMD
Anda bisa merujuk ke naskah awal Anda sendiri yang membungkus memulai layanan kontainer Anda. Sebelum Anda memulainya, Anda menunggu yang tergantung seperti:Dockerfile
start.sh
Mungkin Anda perlu menginstal netcat
Dockerfile
juga. Saya tidak tahu apa yang sudah diinstal pada gambar python.Ada beberapa alat di luar sana yang menyediakan logika menunggu yang mudah digunakan, untuk pemeriksaan port tcp sederhana:
Untuk menunggu lebih kompleks:
sumber
Menggunakan
restart: unless-stopped
ataurestart: always
dapat memecahkan masalah ini.Jika pekerja
container
berhenti ketika rabbitMQ tidak siap, itu akan dimulai kembali sampai siap.sumber
Baru-baru ini mereka telah menambahkan
depends_on
fitur .Edit:
Mulai dari menulis versi 2.1+ yang dapat Anda gunakan
depends_on
bersama denganhealthcheck
untuk mencapai ini:Dari dokumen :
Sebelum versi 2.1
Anda masih dapat menggunakan
depends_on
, tetapi itu hanya mempengaruhi urutan layanan dimulai - tidak jika mereka siap sebelum layanan dependen dimulai.Tampaknya memerlukan setidaknya versi 1.6.0.
Penggunaan akan terlihat seperti ini:
Dari dokumen:
Catatan: Seperti yang saya mengerti, meskipun ini tidak mengatur urutan di mana kontainer dimuat. Itu tidak menjamin bahwa layanan di dalam wadah benar-benar dimuat.
Misalnya, Anda wadah postgres mungkin naik. Tetapi layanan postgres itu sendiri mungkin masih menginisialisasi dalam wadah.
sumber
depends_on
." docs.docker.com/compose/compose-file/#dependsondepends_on
tidak menunggu sampai wadahnya dalamready
keadaan (apa pun artinya dalam kasus Anda). Itu hanya menunggu sampai wadah dalam keadaan 'berjalan'.Anda juga bisa menambahkannya ke opsi perintah misalnya.
https://github.com/docker/compose/issues/374#issuecomment-156546513
untuk menunggu di port Anda juga dapat menggunakan sesuatu seperti ini
untuk menambah waktu tunggu Anda dapat meretas lebih banyak:
sumber
restart: on-failure
melakukan trik untuk saya .. lihat di bawahsumber
Untuk wadah, mulailah memesan
Untuk menunggu wadah sebelumnya, mulai gunakan skrip
Artikel ini akan membantu Anda https://docs.docker.com/compose/startup-order/
sumber
Anda juga dapat menyelesaikan ini dengan menetapkan titik akhir yang menunggu layanan untuk dinyalakan dengan menggunakan netcat (menggunakan skrip docker-wait ). Saya suka pendekatan ini karena Anda masih memiliki
command
bagian bersih di Andadocker-compose.yml
dan Anda tidak perlu menambahkan kode khusus buruh pelabuhan ke aplikasi Anda:Maka Anda
docker-entrypoint.sh
:Ini saat ini didokumentasikan dalam dokumentasi buruh pelabuhan resmi .
PS: Anda harus menginstal
netcat
dalam contoh buruh pelabuhan Anda jika ini tidak tersedia. Untuk melakukannya, tambahkan ini keDocker
file Anda :sumber
Ada utilitas siap pakai yang disebut " docker-wait " yang dapat digunakan untuk menunggu.
sumber
Sudah mencoba berbagai cara, tetapi menyukai kesederhanaan ini: https://github.com/ufoscout/docker-compose-wait
Gagasan bahwa Anda dapat menggunakan ENV vars dalam file buruh pelabuhan compose untuk menyerahkan daftar layanan host (dengan port) yang harus "ditunggu" seperti ini:
WAIT_HOSTS: postgres:5432, mysql:3306, mongo:27017
.Jadi misalkan Anda memiliki file docker-compose.yml berikut (salin / lampau dari repo README ):
Selanjutnya, agar layanan menunggu, Anda perlu menambahkan dua baris berikut ke Dockerfiles Anda (ke Dockerfile dari layanan yang harus menunggu layanan lain untuk memulai):
Contoh lengkap contoh Dockerfile tersebut (lagi dari README repo proyek ):
Untuk detail lainnya tentang kemungkinan penggunaan, lihat README
sumber
https://github.com/ufoscout/docker-compose-wait
perpustakaan berfungsi :) Cara Anda menggunakan perpustakaan itu tidak mengubah jawaban yang dapat Anda manfaatkan dengan lib. Keamanan adalah topik yang kompleks dan jika kita melangkah jauh, kita harus memeriksa apa yang dilakukan perpustakaan di dalamnya, bahkan jika kita SALINAN itu :) Jadi lebih baik untuk lebih spesifik dalam komentar Anda seperti: "Saya sangat merekomendasikan terhadap penggunaan perpustakaan itu dari hyperlink ". Semoga Anda setuju, terima kasih atas petunjuknya!mendasarkan pada posting blog ini https://8thlight.com/blog/dariusz-pasciak/2016/10/17/docker-compose-wait-for-dependencies.html
Saya mengkonfigurasi saya
docker-compose.yml
seperti yang ditunjukkan di bawah ini:Maka saya lakukan untuk menjalankan =>:
docker-compose up start_dependencies
rabbitmq
layanan akan mulai dalam mode daemon,start_dependencies
akan menyelesaikan pekerjaan.sumber
"curl", "-f", "http://localhost:15672"
mana Anda perlu menginstalmanagement
plugin dan menggunakan pemeriksaan kesehatan yang sudah usang - jawaban terbaiknya. Contoh kerja sederhana dengan cek melaluinc
- downvote. ha, ok ...docker-compose run --name app-test --rm "app" bash -l -c 'echo Waiting for mysql service start... && while ! nc -z db-server 3306; do sleep 1; done && echo Connected! && /bin/bash /script/ci_tests.sh'
Dalam versi 3 file Menulis Docker, Anda dapat menggunakan RESTART .
Sebagai contoh:
docker-compose.yml
Perhatikan bahwa saya menggunakan depend_on alih-alih tautan karena yang terakhir tidak digunakan dalam versi 3.
Meskipun berfungsi, itu mungkin bukan solusi ideal karena Anda me-restart wadah buruh pelabuhan di setiap kegagalan.
Lihat juga RESTART_POLICY . itu memungkinkan Anda menyempurnakan kebijakan mulai ulang.
Saat Anda menggunakan Tulis dalam produksi , sebenarnya adalah praktik terbaik untuk menggunakan kebijakan mulai ulang:
sumber
Salah satu solusi alternatif adalah menggunakan solusi orkestrasi wadah seperti Kubernetes. Kubernetes memiliki dukungan untuk wadah init yang dijalankan hingga selesai sebelum wadah lain dapat mulai. Anda dapat menemukan contoh di sini dengan wadah SQL Server 2017 Linux di mana wadah API menggunakan wadah init untuk menginisialisasi database
https://www.handsonarchitect.com/2018/08/understand-kubernetes-object-init.html
sumber
Berikut adalah contoh di mana
main
wadah menungguworker
ketika mulai merespons ping:Namun, cara yang tepat adalah menggunakan
healthcheck
(> = 2.1).sumber
Tidak disarankan untuk penerapan serius, tetapi di sini pada dasarnya adalah perintah "tunggu x detik".
Dengan
docker-compose
versi3.4
sebuahstart_period
instruksi telah ditambahkan kehealthcheck
. Ini berarti kita dapat melakukan hal berikut:docker-compose.yml
:status.sh
:Apa yang terjadi di sini adalah bahwa
healthcheck
dipanggil setelah 5 detik. Ini memanggilstatus.sh
skrip, yang selalu mengembalikan "Tidak masalah". Kami baru saja membuatzmq_client
wadah menunggu 5 detik sebelum memulai!Catatan: Penting bagi Anda untuk memilikinya
version: "3.4"
. Jika.4
tidak ada, komposisi buruh pelabuhan mengeluh.sumber
start_period
tidak. Konfigurasi itu berarti ada masa tenggang di mana pemeriksaan kesehatan yang gagal tidak dihitung sebagai percobaan ulang. Jika berhasil lebih awal, itu dianggap sehat. Setelah periode mulai, kegagalan akan dihitung sebagai coba lagi. Lihat docs.docker.com/engine/reference/builder/#healthcheckSaya hanya punya 2 file menulis dan mulai yang pertama dan yang kedua nanti. Script saya terlihat seperti itu:
sumber