Bağlantı istasyonu konteyneri çalıştırılırken otomatik olarak bir hizmet nasıl başlatılır?


158

MySQL sunucusunu bir kapsayıcıda kurmak için bir Dockerfile'ım var .

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

Ancak MySQL hizmeti otomatik olarak başlamıyor, (konteyner içinden) manuel olarak çalıştırmam gerekiyor:

service mysql start

Docker kapsayıcısını çalıştırdığımda MySQL hizmetini otomatik olarak nasıl başlatırım?


1
hayır, basit bir hizmet için amir gerekli değildir, başlangıç ​​kullanıcısı için karmaşık hale getirir
Larry Cai

8
artık mevcut olmayan bir dosyaya bağlanmak yerine docker dosyasını buraya kopyalamak isteyebilirsiniz
neo112

Supervisord'daki docker makalesi şimdi burada: docs.docker.com/config/containers/multi-service_container Hizmetimin çalışması için && tail komutunu kullandım - ancak docker'a "--cap-SYS_PTRACE ekle" eklemeniz gerekiyor komutu çalıştır.
Ted Cahall

Yanıtlar:


205

İlk olarak, bir orada sorun Gözlerinde farklı Dockerfile:

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

Docker görüntüleri çalışan işlemleri kaydetmez. Bu nedenle, RUNkomutunuz yalnızca docker buildaşama sırasında yürütülür ve derleme tamamlandıktan sonra durur. Bunun yerine, konteyner aşağıdaki gibi CMDveya ENTRYPOINTkomutlarını kullanarak başlatıldığında komutu belirtmeniz gerekir :

CMD mysql start

İkincisi, docker konteynerinin çalışmaya devam etmesi için bir işleme (son komut) ihtiyacı vardır, aksi takdirde konteyner çıkar / durur. Bu nedenle, normal service mysql startkomut doğrudan Dockerfile içinde kullanılamaz.

Çözüm

Süreci çalıştırmanın üç tipik yolu vardır:

  • serviceKomutu kullanma ve bundan sonra bitmeyen komut eklemetail -F

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

Bu genellikle, çıkarılan günlüğü liman işçisine erişilebilir kıldığı için çalışan tek bir hizmetiniz olduğunda tercih edilir.

  • Veya bunu yapmak için ön plan komutunu kullanın

    CMD /usr/bin/mysqld_safe
    

Bu yalnızca benzer bir komut dosyası varsa çalışır mysqld_safe.

  • Veya komut dosyalarınızı içine start.shyerleştirin ve sonuna koyun

    CMD /start.sh
    

Komutun bir dizi adım gerçekleştirmesi gerekiyorsa, bu en iyisidir, /start.sh çalışmaya devam .

Not

Yeni başlayanlar için supervisord önerilmez. Dürüst olmak gerekirse, aşırı dolu. Konteyner için tek hizmet / tek komut kullanmak çok daha iyidir.

BTW: referans için mevcut mysql docker görüntüleri için lütfen https://registry.hub.docker.com adresini kontrol edin


Docker kapsayıcısında başlatıldıktan sonra hizmeti nasıl yeniden başlatırsınız?
K - SO'da toksisite artıyor.

3
@KarlMorrisondocker exec -it <CONTAINER NAME> mysql /etc/init.d/mysqld restart
kaiser

1
Ben veritabanının çalışıp çalışmadığını belirlemek için tail'ing MySQL hata günlüğünü tavsiye etmem. Çoğu mysqld kurulumunda sunucu soe hatalarından kurtulacak ve bunu yaparken hata günlüğü kapatılacak ve yeniden açılacaktır. Ayrıca kuyruk -F'nizin sizin için veya hatta bazı durumlarda çalışacağından emin değilim.
Brian Aker

Neden olduğundan emin değilim, ancak ilk çözüm seçeneği hizmet komut dosyası için iyi çalışıyor. Kuyruk kullanmadığınızda, hizmet başlatılmış olsa bile başarısız olur (en azından tomcat7 hizmeti için). Kuyruk ile çalışır. Her iki durumda da en azından SYS_PTRACE ile cap_add anahtarını (- cap-add SYS_PTRACE ekleyin) kullanmanız gerekir
zhrist

1
hayır, daha fazlasını görmek için bkz. stackoverflow.com/questions/46800594/…
Larry Cai

73

Gözlerinde farklı Dockerfile, son satırında eklemek

ENTRYPOINT service ssh restart && bash

Benim için çalışıyor

Ve sonuç bu:

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

2
bu güzel ama bence bu şekilde müstakil bir konteynır olamaz.
mdob

1
Bu benim için harika çalıştı. Nginx 1.8'in otomatik olarak başlatılmasında sorun yaşıyordum. Aşağıdakileri eklemeyi faydalı bulabilirsiniz: 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
Bu çözümün herhangi bir dezavantajı var mı?
srph

2
Bash'i nihayet başlatmak, hizmetlerinizi zarif bir şekilde durdurmak istediğinizde kötü bir fikirdir, çünkü bu şekilde docker contaienr tarafından durdurulamaz docker stopveya docker restartzarifçe öldürülemez.
Mohammed Noureldin

Docker görüntüleri oluşturmak için packer üzerinde çalışıyordum ve bu packer dosyasında conaitner ile sorunumu düzeltmek gibi görünüyor. "değişiklikler": ["ENTRYPOINT hizmeti nginx start && / bin / bash"]
karthik101

8

Basit! Dockerfile dosyasının sonuna ekleyin:

ENTRYPOINT service mysql start && /bin/bash

Bu şu anki Docker Container sorunumu çözen en iyi cevap: servis Docker version 18.09.7, build 2d0083dolmadan && /bin/bashderhal duracak
Uzun

8

Bunu yapmak için her zaman daha okunabilir bulduğum başka bir yol var.

Bunu çalıştırdığınızda rabbitmq ve mongodb'u başlatmak istediğinizi söyleyin, o zaman CMDşöyle bir şey olurdu:

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

Hile CMDbaşına sadece bir tane olabileceğinden, Dockerfiletüm talimatları birleştirmek &&ve sonra kullanmaktır.\ yeni bir satır başlatmak için her komut için .

Bunların çoğuna eklerseniz, tüm komutlarınızı bir komut dosyasına koymanızı ve @ larry-cai recommended gibi başlatmanızı öneririm:

CMD /start.sh

3

Benim durumumda, Apache2 tarafından MYSQL arka uç veritabanına bağlanan docker kapsayıcısı tarafından sunulan bir PHP web uygulaması var. Larry Cai'nin çözümü küçük değişikliklerle çalıştı. entrypoint.shİçinde hizmetlerimi yönettiğim bir dosya oluşturdum . Bir oluşturarak düşünüyorum entrypoint.shEğer konteyner başlatıldığında önyükleme docker için temizleyici bir yolu olduğunda yürütmek için birden fazla komut varsa.

#!/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

Sadece Dockerfile'ınızın yanına koyun. Sonra Dockerfile dosyasında bu dosyayı istenen konuma kopyalayan bir talimat olmalıdır. Daha sonra ENTRYPOINT ['your location']talimatı komut dosyasına yönlendirirsiniz. Yine de komut dosyanızdaki yürütme izinlerini ayarlamayı unutmayın. COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]. Bu örnekte, giriş noktamı docker kapsayıcısındaki kök dizine kopyaladım.
Bay Doomsbuster

Dockerfile nerede?
Viktor Joras

3

SSH hizmetini otomatik olarak başlatmak istediğimde de aynı sorunla karşılaşıyorum. Bu eki buldum

/etc/init.d/ssh başlangıç
için
~ / .Bashrc
çözebilir, ancak sadece bash ile açacaksınız.


1

Aşağıdaki kodu yalnızca bir kez çalıştırmak için /root/.bashrc dosyasına ekliyorum,

Lütfen bu komut dosyasını çalıştırmadan önce kapsayıcıyı resme verin, aksi takdirde resimlerde 'docker_services' dosyası oluşturulur ve hiçbir hizmet çalıştırılmaz.

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

1

Docker kapsayıcısı çalıştığında MySQL hizmetini otomatik olarak nasıl başlatacağım.

Benim durumumda, sadece MySQL değil, aynı zamanda PHP, Nginx ve Memcached çalıştırmam gerekiyor

Dockerfile'da şu satırlar var

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

&& bash eklemek , Nginx, MySQL, PHP ve Memcached'in konteyner içinde çalışmasını sağlar.


1

Bu işe yaramıyor CMD service mysql start && /bin/bash

Bu işe yaramıyor CMD service mysql start ; /bin/bash ;

- Sanırım interaktif mod ön planı desteklemez.

Bu çalışıyor !! CMD service nginx start ; while true ; do sleep 100; done;

Bu çalışıyor !! CMD service nginx start && tail -F /var/log/nginx/access.log

docker run -p 80:80 nginx_bashKomut parametresi olmadan kullanmanız gerekir .


0

Docker web sitesindeki aşağıdaki belgeler, bir docker kapsayıcısına bir SSH hizmetinin nasıl uygulanacağını gösterir. Hizmetinize kolayca uyarlanabilir olmalıdır:

Bu soruda bir varyasyon da burada sorulmuştur:


nsenter aracı, SSH sunucu kurulumu gerektirmeden bir kaba girmek için başka bir yaklaşımdır: github.com/jpetazzo/nsenter . Ancak bu yaklaşım Docker ana makinenize erişim gerektirir (genellikle SSH erişimi yeterlidir).
Fabien Balageas

Docs.docker.com/sorry/#/examples/running_ssh_service bağlantısı çalışmıyor. Lütfen güncelleyebilir misiniz?
Ankur

0
docker export -o <nameOfContainer>.tar <nameOfContainer>

Docker erik kullanarak mevcut kapsayıcı budamak gerekebilir ...

Gerekli değişikliklerle içe aktarın:

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

Ana bilgisayar / arka plan programı geri dönüşümünden sonra otomatik olarak devam edeceğinden emin olmak için kapsayıcıyı her zaman yeniden başlat seçeneğiyle çalıştırın:

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

Yan not: Bence makul sadece konteyner bırakarak cron hizmetini olabildiğince temiz başlatmak, sonra sadece crontab veya cron.hourly, .daily vb ... ilgili kontrol / izleme komut dosyalarıyla değiştirin. Nedeni Sadece bir artalan programına güvenirsiniz ve değişiklik olması durumunda, önyükleme ile başlayan parça hizmetleri yerine cron komut dosyalarını yeniden dağıtmak için ansible veya kukla ile daha kolaydır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.