डॉकटर कंटेनर चलाते समय स्वचालित रूप से सेवा कैसे शुरू करें?


157

मेरे पास एक कंटेनर में MySQL सर्वर को स्थापित करने के लिए एक डॉकरीफाइल है, जिसे मैं फिर इस तरह शुरू करता हूं:

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

लेकिन MySQL सेवा स्वचालित रूप से शुरू नहीं होती है, मुझे मैन्युअल रूप से (कंटेनर के भीतर से) चलाना होगा:

service mysql start

जब मैं डॉक कंटेनर चलाता हूं तो मैं स्वचालित रूप से MySQL सेवा कैसे शुरू कर सकता हूं?


1
नहीं, एक साधारण सेवा के लिए, पर्यवेक्षक की जरूरत नहीं है, यह शुरुआत उपयोगकर्ता के लिए जटिल बनाता है
लैरी काई

8
आप फ़ाइल को लिंक करने के बजाय डॉकटराइल को यहां कॉपी करना चाहते हैं जो अब मौजूद नहीं है
neo112

पर्यवेक्षक पर docker लेख अब यहाँ है: docs.docker.com/config/containers/multi-service_container मैंने अपनी सेवा प्राप्त करने के लिए && टेल कमांड का उपयोग किया था - लेकिन docker में "scap-add-SYS_PTRACE" जोड़ने की आवश्यकता थी। चलाने के आदेश।
टेड काहल

जवाबों:


205

सबसे पहले, आपकी समस्या है Dockerfile:

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

डॉकर छवियां चल रही प्रक्रियाओं को नहीं बचाती हैं। इसलिए, आपकी RUNकमांड केवल docker buildचरण के दौरान निष्पादित होती है और निर्माण पूरा होने के बाद बंद हो जाती है। इसके बजाय, आपको कमांड निर्दिष्ट करने की आवश्यकता है जब कंटेनर को नीचे की तरह CMDया ENTRYPOINTकमांड का उपयोग करना शुरू किया जाता है :

CMD mysql start

दूसरे, डॉकटर कंटेनर को चालू रखने के लिए एक प्रक्रिया (अंतिम कमांड) की आवश्यकता होती है, अन्यथा कंटेनर बाहर निकल जाएगा / बंद हो जाएगा। इसलिए, सामान्य service mysql startकमांड को सीधे डॉकरफाइल में उपयोग नहीं किया जा सकता है।

उपाय

प्रक्रिया को चालू रखने के तीन विशिष्ट तरीके हैं:

  • serviceकमांड का उपयोग करना और उसके बाद नॉन-एंड कमांड को जोड़नाtail -F

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

यह अक्सर तब पसंद किया जाता है जब आपके पास एकल सेवा चल रही हो क्योंकि यह आउटपुट लॉग को डॉक करने के लिए सुलभ बनाता है।

  • या ऐसा करने के लिए अग्रभूमि कमांड का उपयोग करें

    CMD /usr/bin/mysqld_safe
    

यह तभी काम करता है जब कोई स्क्रिप्ट हो mysqld_safe

  • या अपनी स्क्रिप्ट को इसमें लपेटें start.shऔर इसे अंत में रखें

    CMD /start.sh
    

यह सबसे अच्छा है अगर कमांड को चरणों की एक श्रृंखला /start.shकरनी चाहिए , फिर से, चलना चाहिए।

ध्यान दें

शुरुआत के लिए उपयोग करने supervisordकी अनुशंसा नहीं की जाती है। ईमानदारी से, यह ओवरकिल है। कंटेनर के लिए एकल सेवा / एकल आदेश का उपयोग करना बेहतर है।

BTW: कृपया संदर्भ के लिए मौजूदा mysql docker की छवियों के लिए https://registry.hub.docker.com देखें


डॉकटर कंटेनर में शुरू होने के बाद आप सेवा को कैसे पुनः आरंभ करेंगे?
के - एसओ में विषाक्तता बढ़ रही है।

3
@ कार्लमॉरिसनdocker exec -it <CONTAINER NAME> mysql /etc/init.d/mysqld restart
कैसर

1
मैं यह निर्धारित करने के लिए कि डेटाबेस चल रहा है या नहीं, MySQL की त्रुटि लॉग पूंछने की सलाह नहीं दूंगा। अधिकांश mysqld सेटअप में, सर्वर soe त्रुटियों से उबर जाएगा और ऐसा करने की प्रक्रिया में त्रुटि लॉग बंद हो जाएगा और फिर से खोल दिया जाएगा। मैं यह भी अनिश्चित हूं कि आपकी पूंछ-एफ आपके लिए सभी या कुछ मामलों में भी काम करेगी।
ब्रायन अकर

मुझे यकीन नहीं है कि क्यों, लेकिन सेवा स्क्रिप्ट के लिए पहला समाधान विकल्प ठीक काम करता है। जब आप पूंछ का उपयोग नहीं करते हैं, तो यह विफल हो जाएगा, भले ही सेवा शुरू हो जाए (कम से कम टोमकाट 7 सेवा के लिए)। पूंछ के साथ यह काम करता है। दोनों ही मामलों के लिए आप करने के लिए उपयोग स्विच cap_add जरूरत है (- रन के लिए कैप-ऐड SYS_PTRACE) कम से कम SYS_PTRACE साथ
zhrist


73

अपने में Dockerfile, अंतिम पंक्ति में जोड़ें

ENTRYPOINT service ssh restart && bash

इससे मेरा काम बनता है

और यह परिणाम है:

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
यह अच्छा है, लेकिन मुझे लगता है कि आपके पास इस तरह से एक अलग कंटेनर नहीं हो सकता है।
mdob

1
यह मेरे लिए बहुत अच्छा काम किया। मुझे नग्नेक्स 1.8 से ऑटो स्टार्ट होने में परेशानी हो रही थी। आपको निम्नलिखित मददगार मिल सकते हैं: RUN इको "डेमन ऑफ;" >> /etc/nginx/nginx.conf RUN ln -sf / dev / stdout /var/log/nginx/access.log RUN ln -sf / dev / stderr /var_log/nginx/error.log
लियोनेल मॉरिसन

1
क्या इस समाधान के लिए कोई कमियां हैं?
srph

2
बैश को शुरू करना एक बुरा विचार है जब आप अपनी सेवाओं को इनायत से रोकना चाहते हैं, क्योंकि इस तरह से docker contaienr को docker stopया docker restartइनायत से नहीं रोका जा सकता है, बस इसे मारा जा सकता है।
मोहम्मद नौरेलिन

मैं doer चित्र बनाने के लिए पैकर पर काम कर रहा था और यह पैकर फ़ाइल में conaitner के साथ मेरे मुद्दे को ठीक करने के लिए लगता है। "परिवर्तन": ["ENTRYPOINT सेवा nginx start && / bin / bash"]
karthik101

8

सरल! Dockerfile के अंत में जोड़ें:

ENTRYPOINT service mysql start && /bin/bash

यह सबसे अच्छा उत्तर है जो मेरे वर्तमान डॉकटर कंटेनर मुद्दे को हल करता है: Docker version 18.09.7, build 2d0083dबिना && /bin/bashसेवा तुरंत बंद हो जाएगी
लॉन्ग

7

ऐसा करने का एक और तरीका है कि मैंने हमेशा अधिक पठनीय पाया है।

कहो कि आप खरगोश और मंगोल को शुरू करना चाहते हैं जब आप इसे चलाते हैं तो आपका CMDकुछ इस तरह दिखाई देगा:

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

आप कोई एक हो सकता के बाद से CMDप्रति Dockerfileचाल के साथ सभी निर्देशों को श्रेणीबद्ध करने के लिए है &&और फिर \प्रत्येक आदेश के लिए एक नई लाइन शुरू करने के लिए।

यदि आप समाप्त करते हैं, तो मैं आपको अपने सभी आदेशों को एक स्क्रिप्ट फ़ाइल में जोड़ने का प्रयास करता हूं और इसे @ लैरी-कैई की तरह शुरू करता हूं:

CMD /start.sh

3

मेरे मामले में, मेरे पास एक PHP वेब अनुप्रयोग है जो Apache2 द्वारा docker कंटेनर के भीतर परोसा जा रहा है जो MYSQL बैकएंड डेटाबेस से जुड़ता है। लैरी कै के समाधान ने मामूली संशोधनों के साथ काम किया। मैंने एक entrypoint.shफ़ाइल बनाई जिसके भीतर मैं अपनी सेवाओं का प्रबंधन कर रहा हूं। मुझे लगता है कि entrypoint.shजब आपके कंटेनर को स्टार्ट करने के लिए आपके पास एक से अधिक कमांड हैं, तो एक बूटस्ट्रैप डॉकटर के लिए एक क्लीनर तरीका है।

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

बस इसे अपने डॉकरफाइल के साथ लगाएं। फिर आपके डॉकरीफाइल में आपके पास एक निर्देश होना चाहिए जो इस फाइल को वांछित स्थान पर कॉपी करता है। तब आप ENTRYPOINT ['your location']निर्देश को स्क्रिप्ट फ़ाइल में इंगित करते हैं । हालांकि अपनी स्क्रिप्ट पर निष्पादित अनुमतियाँ सेट करना याद रखें। COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]। इस उदाहरण में, मैंने डॉकटर कंटेनर में रूट एंट्री में अपना प्रवेश बिंदु कॉपी किया।
श्री डूमस्बस्टर

Dockerfile कहाँ है?
विक्टर जोरास

3

मैं एक ही समस्या है जब मैं स्वचालित रूप से ssh सेवा शुरू करना चाहता हूँ। मुझे वह अपेंड मिला

/etc/init.d/ssh प्रारंभ
सेवा
~ / .Bashrc
इसे हल कर सकते हैं, लेकिन केवल आप इसे बैश के साथ खोलेंगे।


1

मैं केवल एक बार कोड चलाने के लिए /root/.bashrc पर निम्न कोड जोड़ता हूं,

कृपया इस स्क्रिप्ट को चलाने से पहले छवि को कंटेनर दें, अन्यथा छवियों में 'docker_services' फ़ाइल बनाई जाएगी और कोई सेवा नहीं चलाई जाएगी।

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

यहाँ है कि मैं स्वचालित रूप से MySQL सेवा शुरू करता हूँ जब भी डॉक कंटेनर चलता है।

मेरे मामले में, मुझे न केवल MySQL बल्कि PHP, Nginx और Memcached को चलाने की आवश्यकता है

डॉकरीफाइल में मेरी निम्न पंक्तियाँ हैं

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

&& बैश जोड़ने से कंटेनर के भीतर Nginx, MySQL, PHP और Memcached चल रहा होगा।


1

यह काम नहीं करता है CMD service mysql start && /bin/bash

यह काम नहीं करता है CMD service mysql start ; /bin/bash ;

- मुझे लगता है कि इंटरैक्टिव मोड अग्रभूमि का समर्थन नहीं करेगा।

यह काम !! CMD service nginx start ; while true ; do sleep 100; done;

यह काम !! CMD service nginx start && tail -F /var/log/nginx/access.log

docker run -p 80:80 nginx_bashकमांड पैरामीटर के बिना आपको सावधान रहना चाहिए ।


0

डॉकर वेबसाइट से निम्नलिखित प्रलेखन से पता चलता है कि एक डॉक कंटेनर में एसएसएच सेवा को कैसे लागू किया जाए। यह आपकी सेवा के लिए आसानी से अनुकूल होना चाहिए:

इस सवाल पर एक बदलाव यहाँ भी पूछा गया है:


SSH सर्वर इंस्टॉलेशन की आवश्यकता के बिना nsenter टूल कंटेनर में प्रवेश करने का एक और तरीका है: github.com/jpetazzo/nsenter । लेकिन इस दृष्टिकोण के लिए आपके डॉकर होस्ट तक पहुंच की आवश्यकता होती है (आमतौर पर एसएसएच एक्सेस पर्याप्त है)।
फेबिन बालागेस

लिंक docs.docker.com/sorry/#/examples/running_ssh_service काम नहीं करता है। क्या आप कृपया इसे अपडेट कर सकते हैं?
अंकुर

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

Docker prune का उपयोग करके मौजूदा कंटेनर को प्री्यून करने की आवश्यकता हो सकती है ...

आवश्यक संशोधनों के साथ आयात करें:

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

उदाहरण के लिए कंटेनर को हमेशा पुनरारंभ विकल्प के साथ चलाएं यह सुनिश्चित करने के लिए कि यह मेजबान / डेमन रीसायकल के बाद ऑटो फिर से शुरू होगा:

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

साइड नोट: मेरी राय में, केवल क्रोन सेवा को कंटेनर से साफ करना शुरू करना है जितना संभव हो सके तो बस कॉन्टैब या क्रोन.होरली, डीडीली आदि को संशोधित करें ... इसी चेकअप / मॉनिटरिंग स्क्रिप्ट के साथ। कारण यह है कि आप केवल एक डेमॉन पर निर्भर हैं और परिवर्तन के मामले में बूट पर शुरू होने वाली ट्रैक सेवाओं के बजाय क्रोन स्क्रिप्ट को फिर से विभाजित करना आसान या कठपुतली के साथ आसान है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.