Anda dapat menyalin crontab Anda ke dalam gambar, agar wadah diluncurkan dari gambar tersebut untuk menjalankan pekerjaan.
Lihat " Jalankan pekerjaan cron dengan Docker " dari Julien Boulay dalam bukunya Ekito/docker-cron
:
Mari kita buat file baru yang disebut " hello-cron
" untuk menggambarkan pekerjaan kita.
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.
Dockerfile berikut menjelaskan semua langkah untuk membangun gambar Anda
FROM ubuntu:latest
MAINTAINER docker@ekito.fr
RUN apt-get update && apt-get -y install cron
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
(lihat Gaafar 's komentar dan Bagaimana cara membuat apt-get
install kurang bising? :
apt-get -y install -qq --force-yes cron
dapat bekerja juga)
Seperti yang dicatat oleh Nathan Lloyd dalam komentar :
Catatan singkat tentang gotcha:
Jika Anda menambahkan file skrip dan menyuruh cron untuk menjalankannya, ingatlah untuk Cron gagal secara diam-diam jika Anda lupa .
RUN chmod 0744 /the_script
OR, pastikan pekerjaan Anda sendiri mengarahkan langsung ke stdout / stderr bukan file log, seperti yang dijelaskan dalam hugoShaka 's jawabannya :
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
Ganti baris Dockerfile terakhir dengan
CMD ["cron", "-f"]
Lihat juga (tentang cron -f
, yang mengatakan cron "foreground") " docker ubuntu cron -f
tidak berfungsi "
Bangun dan jalankan:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
Bersabarlah, tunggu 2 menit dan baris perintah Anda akan ditampilkan:
Hello world
Hello world
Eric menambahkan dalam komentar :
Perhatikan bahwa tail
mungkin tidak menampilkan file yang benar jika dibuat selama pembuatan gambar.
Jika itu masalahnya, Anda harus membuat atau menyentuh file selama runtime kontainer agar ekor untuk mengambil file yang benar.
Lihat " Output tail -f
pada akhir buruh pelabuhan CMD
tidak ditampilkan ".
RUN apt-get update && apt-get install cron
-y
untuk menginstal cron untuk menghindari keluar bangunan buruh pelabuhancrontab -l
, saya tidak menginstal crontab untuk root , juga, layar saya tetap kosong. Namun, ketika saya mencentang '/etc/cron.d/', saya melihat crontab ada di sana (dan bahkan lebih mengejutkan), ketika saya periksa/var/log/cron.log
, saya melihat bahwa skrip sedang berjalan (isi file sedang ditambahkan denganHello World
). Aku menarik gambar ini di Dockerfile saya:FROM phusion/baseimage:0.10.0
. Adakah gagasan tentang perbedaan perilaku?Solusi yang diadopsi mungkin berbahaya di lingkungan produksi .
Ketika Anda menggunakan
CMD cron && tail -f /var/log/cron.log
proses cron pada dasarnya bercabang untuk mengeksekusicron
di latar belakang, proses utama keluar dan membiarkan Anda mengeksekusitailf
di latar depan. Proses latar belakang cron bisa berhenti atau gagal Anda tidak akan melihat, wadah Anda akan tetap berjalan diam-diam dan alat orkestrasi Anda tidak akan memulai kembali.Menggunakan pengalihan shell dasar Anda mungkin ingin melakukan sesuatu seperti ini:
Dan CMD Anda akan:
CMD ["cron", "-f"]
sumber
cron -f
untuk "cron foreground". Saya telah menyertakan jawaban Anda di bagian saya di atas, untuk visibilitas lebih lanjut +1Bagi mereka yang ingin menggunakan gambar yang sederhana dan ringan:
Di mana cronjobs adalah file yang berisi cronjobs Anda, dalam formulir ini:
sumber
> /proc/1/fd/1 2> /proc/1/fd/2
pengalihan untuk mengakses output cronjobs langsung dari log buruh pelabuhan.-d 8
parameter bukan cron standar, itu adalah perintah crond dari busybox. Misalnya dari ubuntu, Anda dapat menjalankan ini sebagaibusybox crond -f -d 8
. Untuk versi yang lebih lama Anda harus menggunakan-L /dev/stdout/
.docker run -v ${PWD}/cronjobs:/etc/crontabs/root alpine:3.6 crond -f -d 8
. @Gostostav Anda dapat menggunakan hal serupa di Docker Compose.CMD ["crond"
atauCMD ["cron"
?Apa yang disarankan @VonC bagus tapi saya lebih suka melakukan semua konfigurasi tugas cron dalam satu baris. Ini akan menghindari masalah lintas platform seperti lokasi cronjob dan Anda tidak memerlukan file cron yang terpisah.
Setelah menjalankan wadah buruh pelabuhan, Anda dapat memastikan apakah layanan cron bekerja dengan:
Jika Anda lebih suka memiliki ENTRYPOINT daripada CMD, maka Anda dapat mengganti CMD di atas dengan
sumber
RUN apt-get update && apt-get -y install cron
atau tidak akan dapat menemukan paketcron
RUN cat $APP_HOME/crons/* | crontab
Seperti pesona :)cron
ke skrip entrypoint sepertinya pilihan terbaik: ENTRYPOINT ["entrypoint.sh"]Ada cara lain untuk melakukannya, yaitu menggunakan Tasker , pelari tugas yang memiliki dukungan cron (penjadwal).
Mengapa Terkadang untuk menjalankan pekerjaan cron, Anda harus mencampur, gambar dasar Anda (python, java, nodejs, ruby) dengan crond. Itu berarti gambar lain untuk dipertahankan. Tasker menghindarinya dengan memisahkan keranjang dan wadah Anda. Anda bisa fokus pada gambar yang ingin Anda jalankan perintah Anda, dan mengkonfigurasi Tasker untuk menggunakannya.
Di sini ada
docker-compose.yml
file, yang akan menjalankan beberapa tugas untuk AndaAda 3 tugas di sana, semuanya akan berjalan setiap menit (
every: minute
), dan masing-masing akan menjalankanscript
kode, di dalam gambar yang ditentukan dalamimage
bagian.Jalankan saja
docker-compose up
, dan lihat itu berfungsi. Inilah repo Tasker dengan dokumentasi lengkap:http://github.com/opsxcq/tasker
sumber
docker exec
pada wadah yang ditentukan.Jawaban VonC cukup menyeluruh. Selain itu saya ingin menambahkan satu hal yang membantu saya. Jika Anda hanya ingin menjalankan pekerjaan cron tanpa mengekor file, Anda akan tergoda untuk hanya menghapus
&& tail -f /var/log/cron.log
dari perintah cron.Namun ini akan menyebabkan wadah Docker keluar segera setelah berjalan karena ketika perintah cron selesai, Docker berpikir perintah terakhir telah keluar dan karenanya membunuh kontainer. Ini bisa dihindari dengan menjalankan cron di foreground via
cron -f
.sumber
Meskipun ini bertujuan untuk menjalankan pekerjaan di samping proses yang berjalan dalam wadah melalui
exec
antarmuka Docker , ini mungkin menarik bagi Anda.Saya telah menulis daemon yang mengamati wadah dan menjadwalkan pekerjaan, didefinisikan dalam metadata mereka, pada mereka. Contoh:
'Klasik', konfigurasi seperti cron juga dimungkinkan.
Ini dokumennya , inilah repositori gambar .
sumber
docker exec <container_name> <some_command>
demi jadwal.Saya membuat gambar Docker berdasarkan jawaban lain, yang bisa digunakan seperti
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
di mana
/path/to/cron
: path absolut ke file crontab, atau Anda dapat menggunakannya sebagai basis di Dockerfile:Untuk referensi, gambar ada di sini .
sumber
Ketika Anda menggunakan wadah Anda di host lain, perlu diketahui bahwa itu tidak akan memulai proses apa pun secara otomatis. Anda perlu memastikan bahwa layanan 'cron' berjalan di dalam wadah Anda. Dalam kasus kami, saya menggunakan Supervisord dengan layanan lain untuk memulai layanan cron.
sumber
Tentukan cronjob dalam wadah khusus yang menjalankan perintah melalui buruh pelabuhan ke layanan Anda.
Ini adalah kohesi yang lebih tinggi dan skrip yang berjalan akan memiliki akses ke variabel lingkungan yang telah Anda tetapkan untuk layanan Anda.
sumber
myservice unknown
kesalahan.Jika Anda menggunakan buruh pelabuhan untuk windows, ingatlah bahwa Anda harus mengubah format akhir baris Anda dari CRLF ke LF (yaitu dari dos ke unix) jika Anda bermaksud mengimpor file crontab Anda dari windows ke wadah ubuntu Anda. Jika tidak, cron-job Anda tidak akan berfungsi. Berikut ini contoh kerjanya:
Ini benar-benar membuat saya berjam-jam untuk mencari tahu, karena men-debug pekerjaan cron dalam wadah buruh pelabuhan adalah tugas yang membosankan. Semoga ini bisa membantu orang lain di luar sana yang tidak bisa membuat kode mereka berfungsi!
sumber
Dari contoh di atas saya membuat kombinasi ini:
Alpine Image & Edit Menggunakan Crontab di Nano (I hate vi)
sumber
Atur cron secara paralel ke pekerjaan satu kali
Buat file skrip, katakan run.sh, dengan pekerjaan yang seharusnya dijalankan secara berkala.
Simpan dan keluar.
Gunakan Entrypoint alih-alih CMD
Jika Anda memiliki banyak pekerjaan untuk ditendang selama kontainerisasi buruh pelabuhan, gunakan file entrypoint untuk menjalankan semuanya.
File Entrypoint adalah file skrip yang mulai beraksi ketika perintah run docker dikeluarkan. Jadi, semua langkah yang ingin kita jalankan dapat dimasukkan ke dalam file skrip ini.
Misalnya, kami memiliki 2 pekerjaan yang harus dijalankan:
Jalankan sekali pekerjaan : echo "Docker container telah dimulai"
Jalankan pekerjaan berkala : run.sh
Buat entrypoint.sh
Mari kita memahami crontab yang telah diatur dalam file
* * * * *
: Jadwal Cron; pekerjaan harus dijalankan setiap menit. Anda dapat memperbarui jadwal berdasarkan kebutuhan Anda./run.sh
: Jalur ke file skrip yang akan dijalankan secara berkala/var/log/cron.log
: Nama file untuk menyimpan output dari pekerjaan cron yang dijadwalkan.2>&1
: Log kesalahan (jika ada) juga akan diarahkan ke file output yang sama yang digunakan di atas.Catatan : Jangan lupa untuk menambahkan baris baru, karena menjadikannya cron yang valid.
Scheduler.txt
: pengaturan cron lengkap akan dialihkan ke file.Menggunakan variabel lingkungan Sistem / Pengguna khusus dalam cron
Pekerjaan cron saya yang sebenarnya mengharapkan sebagian besar argumen sebagai variabel lingkungan dilewatkan ke perintah run docker. Tetapi, dengan bash, saya tidak dapat menggunakan variabel lingkungan apa pun yang termasuk dalam sistem atau wadah buruh pelabuhan.
Kemudian, ini muncul sebagai solusi untuk masalah ini:
Akhirnya, Anda
entrypoint.sh
akan terlihat sepertiTerakhir tetapi tidak sedikit: Buat Dockerfile
Itu dia. Bangun dan Jalankan gambar Docker!
sumber
Pekerjaan Cron disimpan di / var / spool / cron / crontab (Tempat umum di semua distro yang saya tahu). BTW, Anda bisa membuat tab cron di bash menggunakan sesuatu seperti itu:
Ini akan membuat file sementara dengan tugas cron, kemudian memprogramnya menggunakan crontab. Baris terakhir hapus file sementara.
sumber
cron
daemon biasanya tidak berjalan dalam sebuah wadah.crond
selain layanan yang Anda jalankan dalam wadah, biasanya dengan manajer layanan seperti s6. Mungkin tanyakan itu sebagai pertanyaan untuk mendapatkan jawaban yang tepatKetika menjalankan beberapa gambar terpangkas yang membatasi akses root, saya harus menambahkan pengguna saya ke sudoers dan menjalankannya sebagai
sudo cron
Mungkin itu membantu seseorang
sumber
Jadi, masalah saya sama. Cara mengatasinya adalah mengubah bagian perintah di
docker-compose.yml
.Dari
perintah: crontab / etc / crontab && tail -f / etc / crontab
Untuk
perintah: crontab / etc / crontab
perintah: tail -f / etc / crontab
The masalah adalah '&&' antara perintah. Setelah menghapus ini, semuanya baik-baik saja.
sumber
Cara paling kuat yang saya temukan sejauh ini adalah menjalankan wadah cron independen - instal klien buruh pelabuhan dan ikat gunung buruh pelabuhan sehingga Anda dapat berbicara dengan server buruh pelabuhan di host.
Kemudian gunakan saja env vars untuk setiap pekerjaan cron dan skrip entrypoint untuk menghasilkan / etc / crontab
Berikut adalah gambar yang saya buat menggunakan prinsip ini dan menggunakannya dalam produksi selama 3-4 tahun terakhir.
https://www.vip-consult.solutions/post/better-docker-cron#content
sumber
Coba gunakan permata jarum jam untuk menjadwalkan tugas. Ikuti langkah-langkah yang disediakan dalam tautan ini.
http://fuzzyblog.io/blog/rails/2017/05/11/adding-cron-to-a-dockerized-rails-application-using-clockwork.html
Anda dapat memanggil tugas rake di dalam file lib / clock.rb seperti di bawah ini.
Buat wadah terpisah di file komposisi buruh pelabuhan & jalankan perintah di bawah ini di dalam wadah.
sumber