Cara yang tepat untuk menjaga wadah docker dimulai ketika digunakan untuk tugas-tugas berkala

Saya memiliki wadah docker dengan perangkat lunak yang diinstal dan dikonfigurasi.

Tidak ada programm yang seharusnya dimulai / dijalankan sepanjang waktu.

Apa yang saya inginkan - kemampuannya untuk memulai beberapa perintah tergantung pada peristiwa eksternal. seperti:

docker exec mysupercont /path/to/mycommand -bla -for

dan

docker exec mysupercont /path/to/myothercommand 

Tetapi" exec "tidak mungkin ketika wadah dihentikan, dan juga wadah ini memiliki beberapa data" berfungsi " di dalamnya, yang digunakan untuk perintah itu, jadi saya tidak dapat menggunakannya

docker run ...

setiap kali, karena itu membuat ulang wadah dari gambar dan menghancurkan data saya.

Apa cara yang "benar "dan" terbaik " untuk menjaga wadah seperti itu tetap berjalan? Perintah mana yang bisa saya mulai di dalam?

Anda tidak perlu melakukan setiap kali docker run.

docker run sebenarnya adalah urutan dua perintah:" buat "dan"mulai".

Ketika Anda menjalankan wadah, Anda harus menentukan "-it":

- i, --interactive = false tetap buka STDIN meskipun tidak terpasang
- t, --TTY=false alokasikan pseudo-TTY

Contoh:

docker run -it debian:stable bash

Setelah pekerjaan selesai perintah yang ditentukan saat startup (dalam contoh bash saya). Misalnya, anda melakukan "keluar". Kontainer berhenti:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Sekarang anda bisa memulainya lagi

docker start 1329c99a831b

Wadah dimulai dan lagi mengeksekusi perintah "bash".
Hubungkan ke sesi ini "bash" dengan perintah

docker attach 1329c99a831b

Untuk meringkas: Anda harus memahami perbedaan antara run dan start wadah.
Selain itu, melihat dokumentasi untuk peran parameter "-i t"dan"-d"untuk"lari"

Karena Anda menyebutkan tugas berkala dan Anda mungkin menggunakan sesuatu seperti cron karena cara yang ingin Anda gunakan docker exec, Saya baru saja obat untuk anda. Setidaknya saya akhirnya melakukan sesuatu seperti ini.

  1. Dockerfile

    FROM <some base>CMD tail -f /dev/null
  2. Jalankan dengan yang biasa docker run -d .... (Saya menggunakan docker-compose)

  3. Pengaturan mesin host crontab, misalnya:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1* * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1

Saya menemukan solusi ini bagus karena kami dapat mengandalkan crontab kuno dan terbukti di lingkungan linux default yang cantik, sementara Docker menangani deps dan variabel lingkungan logika bisnis anda yang lebih eksotis. Anda juga dapat menetapkan beberapa batas jika tugas periodik Anda terjebak & memiliki kebocoran memori atau apa pun.

Tail masih akan menyebabkan beberapa operasi file dari waktu ke waktu.

Tidur selamanya, tanpa efek samping

# Ah, ha, ha, ha, stayin' alive...while :; do :; done & kill -STOP $! && wait $!

Cara kerjanya

while :;           # Run an endless loop,do :;              # of do nothing,done &             # as background task.kill -STOP $!      # Stop the background task.wait $!            # Wait forever, because background task process has been stopped.

Saya telah menggunakan semua solusi yang diusulkan di sini sendiri, tetapi semuanya tidak menangani sinyal SIGTERM yang berasal dari DAEMON Docker ketika ingin mematikan wadah (misalnya. docker stop $containername).

Jadi saya mengusulkan yang berikut:

FROM base:image# ...CMD sh -c 'trap "exit" TERM; while true; do sleep 1; done'

Ini pada dasarnya adalah skrip shell pendek yang pertama-tama memotong ("perangkap") sinyal SIGTERM dan kemudian tidur sebentar dalam loop tak terbatas.

Saya terutama menggunakannya bersama dengan docker-compose dan ophelia untuk memasok kontainer sisi-mobil untuk cadangan beberapa layanan lain dalam wadah lain (misalnya database MariaDB).

'docker run - D – name = Nama kontainer ekor-f /dev/null`

Ini adalah pertanyaan yang dijelaskan dengan sangat baik. Lihat posting serupa lainnyahere.