Bagaimana cara memulai layanan secara otomatis saat menjalankan wadah buruh pelabuhan?

157

Saya memiliki Dockerfile untuk menginstal server MySQL dalam sebuah wadah, yang kemudian saya mulai seperti ini:

sudo docker run -t -i 09d18b9a12be /bin/bash

Tetapi layanan MySQL tidak memulai secara otomatis, saya harus menjalankannya secara manual (dari dalam wadah):

service mysql start

Bagaimana cara saya memulai layanan MySQL secara otomatis saat menjalankan wadah buruh pelabuhan?

mtmacdonald
sumber
1
tidak, untuk satu layanan sederhana, pengawas tidak diperlukan, itu membuat rumit untuk pengguna pemula
Larry Cai
8
Anda mungkin ingin menyalin dockerfile di sini alih-alih menautkan ke file yang tidak ada lagi
neo112
Artikel buruh pelabuhan di supervisor sekarang ada di sini: docs.docker.com/config/containers/multi-service_container Saya menggunakan perintah && tail untuk membuat layanan saya berfungsi - tetapi perlu menambahkan "--cap-tambahkan SYS_PTRACE" ke buruh pelabuhan jalankan perintah.
Ted Cahall

Jawaban:

205

Pertama, ada masalah di Anda Dockerfile:

RUN service mysql restart && /tmp/setup.sh

Gambar Docker tidak menyimpan proses yang sedang berjalan. Oleh karena itu, RUNperintah Anda dieksekusi hanya selama docker buildfase dan berhenti setelah build selesai. Sebagai gantinya, Anda perlu menentukan perintah ketika wadah mulai menggunakan CMDatau ENTRYPOINTperintah seperti di bawah ini:

CMD mysql start

Kedua, wadah buruh pelabuhan membutuhkan proses (perintah terakhir) untuk tetap berjalan, jika tidak wadah akan keluar / berhenti. Oleh karena itu, service mysql startperintah normal tidak dapat digunakan secara langsung di Dockerfile.

Larutan

Ada tiga cara khas agar proses tetap berjalan:

  • Menggunakan serviceperintah dan menambahkan perintah tanpa akhir setelah itu sukatail -F

    CMD service mysql start && tail -F /var/log/mysql/error.log
    

Ini sering lebih disukai ketika Anda memiliki satu layanan berjalan karena membuat log yang dihasilkan dapat diakses oleh buruh pelabuhan.

  • Atau gunakan perintah foreground untuk melakukan ini

    CMD /usr/bin/mysqld_safe
    

Ini hanya berfungsi jika ada skrip seperti mysqld_safe.

  • Atau bungkus skrip Anda start.shdan selesaikan ini

    CMD /start.sh
    

Ini yang terbaik jika perintah harus melakukan serangkaian langkah, sekali lagi, /start.shharus tetap berjalan.

Catatan

Untuk pemula supervisordtidak disarankan menggunakan . Jujur saja, itu berlebihan. Jauh lebih baik menggunakan layanan tunggal / perintah tunggal untuk wadah.

BTW: silakan periksa https://registry.hub.docker.com untuk gambar mysql docker yang ada untuk referensi

Larry Cai
sumber
Bagaimana Anda memulai kembali layanan setelah dimulai dalam wadah buruh pelabuhan?
K - Keracunan dalam SO tumbuh.
3
@KarlMorrisondocker exec -it <CONTAINER NAME> mysql /etc/init.d/mysqld restart
kaiser
1
Saya tidak akan merekomendasikan untuk menambahkan log kesalahan MySQL untuk menentukan apakah database berjalan atau tidak. Pada sebagian besar pengaturan mysqld, server akan pulih dari kesalahan soe dan dalam proses melakukan ini log kesalahan akan ditutup dan kemudian dibuka kembali. Saya juga tidak yakin bahwa ekor Anda -F akan bekerja untuk Anda dalam semua atau bahkan beberapa kasus.
Brian Aker
Saya tidak yakin mengapa, tetapi opsi solusi pertama berfungsi dengan baik untuk skrip layanan. Ketika Anda tidak menggunakan tail, itu akan gagal, meskipun layanan dimulai (setidaknya untuk layanan tomcat7). Dengan ekor itu berhasil. Untuk kedua kasus, Anda perlu menggunakan switch cap_add (- cap-add SYS_PTRACE untuk dijalankan) dengan setidaknya SYS_PTRACE
zhrist
1
tidak, lihat lebih banyak di stackoverflow.com/questions/46800594/…
Larry Cai
73

Di Anda Dockerfile, tambahkan di baris terakhir

ENTRYPOINT service ssh restart && bash

Ini bekerja untuk saya

Dan inilah hasilnya:

root@ubuntu:/home/vagrant/docker/add# docker run -i -t ubuntu
 * Restarting OpenBSD Secure Shell server sshd   [ OK ]                                                                      
root@dccc354e422e:~# service ssh status
 * sshd is running
Jia
sumber
2
ini bagus tapi saya pikir Anda tidak bisa memiliki wadah terpisah dengan cara ini.
mdob
1
Ini bekerja baik untuk saya. Saya kesulitan mendapatkan Nginx 1.8 untuk memulai secara otomatis. Anda mungkin menemukan menambahkan yang berikut ini membantu: RUN echo "daemon off;" >> /etc/nginx/nginx.conf RUN ln -sf / dev / stdout /var/log/nginx/access.log RUN ln -sf / dev / stderr /var/log/nginx/error.log
Lionel Morrison
1
Apakah ada kekurangan untuk solusi ini?
srph
2
Memulai Bash akhirnya adalah ide yang buruk ketika Anda ingin menghentikan layanan Anda dengan anggun, karena dengan cara ini buruh pelabuhan tidak dapat dihentikan oleh docker stopatau docker restartanggun, hanya saja bisa dibunuh.
Mohammed Noureldin
Saya sedang mengerjakan packer untuk membuat gambar buruh pelabuhan dan ini tampaknya memperbaiki masalah saya dengan conaitner dalam file packer. "perubahan": ["ENTRYPOINT layanan nginx start && / bin / bash"]
karthik101
8

Sederhana! Tambahkan di akhir dockerfile:

ENTRYPOINT service mysql start && /bin/bash
Thiago
sumber
Ini adalah jawaban terbaik yang memecahkan masalah Docker Container saya saat ini:, Docker version 18.09.7, build 2d0083dtanpa && /bin/bashlayanan akan segera berhenti
Panjang
7

Ada cara lain untuk melakukannya yang menurut saya lebih mudah dibaca.

Katakan bahwa Anda ingin memulai rabbitmq dan mongodb ketika Anda menjalankannya maka Anda CMDakan terlihat seperti ini:

CMD /etc/init.d/rabbitmq-server start && \
    /etc/init.d/mongod start

Karena Anda hanya dapat memiliki satu CMDper Dockerfiletriknya adalah menggabungkan semua instruksi dengan &&dan kemudian menggunakannya\ untuk setiap perintah untuk memulai baris baru.

Jika Anda akhirnya menambahkan ke banyak dari mereka saya sarankan Anda meletakkan semua perintah Anda dalam file skrip dan mulai seperti @ larry-cai yang disarankan:

CMD /start.sh
Francesco Casula
sumber
3

Dalam kasus saya, saya memiliki aplikasi web PHP yang dilayani oleh Apache2 dalam wadah buruh pelabuhan yang terhubung ke database backend MYSQL. Solusi Larry Cai bekerja dengan modifikasi kecil. Saya membuat entrypoint.shfile di mana saya mengelola layanan saya. Saya pikir membuat entrypoint.shketika Anda memiliki lebih dari satu perintah untuk dijalankan ketika wadah Anda mulai adalah cara yang lebih bersih untuk bootstrap buruh pelabuhan.

#!/bin/sh

set -e

echo "Starting the mysql daemon"
service mysql start

echo "navigating to volume /var/www"
cd /var/www
echo "Creating soft link"
ln -s /opt/mysite mysite

a2enmod headers
service apache2 restart

a2ensite mysite.conf
a2dissite 000-default.conf
service apache2 reload

if [ -z "$1" ]
then
    exec "/usr/sbin/apache2 -D -foreground"
else
    exec "$1"
fi
Mr. Doomsbuster
sumber
Letakkan di samping Dockerfile Anda. Kemudian di Dockerfile Anda, Anda harus memiliki instruksi yang menyalin file ini ke lokasi yang diinginkan. Kemudian Anda mengarahkan ENTRYPOINT ['your location']instruksi ke file skrip. Jangan lupa untuk mengatur izin eksekusi pada skrip Anda. COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]. Dalam contoh ini, saya menyalin titik masuk saya ke direktori root di wadah buruh pelabuhan.
Tn. Doomsbuster
dimana Dockerfile
Viktor Joras
3

Saya memiliki masalah yang sama ketika saya ingin memulai layanan ssh secara otomatis. Saya menemukan append itu

/etc/init.d/ssh mulai
untuk
~ / .bashrc
dapat menyelesaikannya, tetapi hanya Anda yang membukanya dengan bash yang akan melakukannya.

Menangis. Lalu
sumber
1

Saya menambahkan kode berikut ke /root/.bashrc untuk menjalankan kode hanya sekali,

Harap komit wadah ke gambar sebelum menjalankan skrip ini, jika tidak file 'docker_services' akan dibuat dalam gambar dan tidak ada layanan yang akan dijalankan.

if [ ! -e /var/run/docker_services ]; then
    echo "Starting services"
    service mysql start
    service ssh start
    service nginx start
    touch /var/run/docker_services
fi
pengguna136685
sumber
1

Inilah cara saya memulai layanan MySQL secara otomatis setiap kali wadah buruh pelabuhan berjalan.

Dalam kasus saya, saya perlu menjalankan tidak hanya MySQL tetapi juga PHP, Nginx dan Memcached

Saya memiliki baris berikut di Dockerfile

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
EXPOSE 3306
CMD service mysql start && service php-fpm start && nginx -g 'daemon off;' && service memcached start && bash

Menambahkan && bash akan membuat Nginx, MySQL, PHP dan Memcached berjalan di dalam wadah.

Chris
sumber
1

Ini tidak berfungsi CMD service mysql start && /bin/bash

Ini tidak berfungsi CMD service mysql start ; /bin/bash ;

- Saya kira mode interaktif tidak akan mendukung latar depan.

Ini bekerja !! CMD service nginx start ; while true ; do sleep 100; done;

Ini bekerja !! CMD service nginx start && tail -F /var/log/nginx/access.log

Waspadalah Anda harus menggunakan docker run -p 80:80 nginx_bashtanpa parameter perintah.

pengguna3073309
sumber
0

Dokumentasi berikut dari situs web Docker menunjukkan bagaimana menerapkan layanan SSH dalam wadah buruh pelabuhan. Itu harus mudah beradaptasi untuk layanan Anda:

Variasi untuk pertanyaan ini juga telah diajukan di sini:

Zammalad
sumber
alat nsenter adalah pendekatan lain untuk masuk ke dalam wadah, tanpa memerlukan instalasi server SSH: github.com/jpetazzo/nsenter . Tetapi pendekatan ini membutuhkan akses ke host Docker Anda (biasanya akses SSH sudah cukup).
Fabien Balageas
Tautan docs.docker.com/sorry/#/examples/running_ssh_service tidak berfungsi. Bisakah Anda memperbaruinya?
Ankur
0
docker export -o <nameOfContainer>.tar <nameOfContainer>

Mungkin perlu memangkas wadah yang ada menggunakan buruh pelabuhan ...

Impor dengan modifikasi yang diperlukan:

cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>

Jalankan wadah misalnya dengan opsi selalu restart untuk memastikannya akan dilanjutkan secara otomatis setelah host / daemon recycle:

docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash

Catatan tambahan: Menurut pendapat saya masuk akal untuk memulai hanya layanan cron yang meninggalkan wadah sebersih mungkin kemudian hanya memodifikasi crontab atau cron. Alasannya adalah Anda hanya bergantung pada satu daemon dan jika terjadi perubahan, lebih mudah menggunakan anonim atau boneka untuk mendistribusikan kembali skrip cron alih-alih layanan trek yang dimulai saat boot.

Daniel
sumber