Docker-Compose का उपयोग करके, कई कमांड को कैसे निष्पादित करें


499

मैं कुछ ऐसा करना चाहता हूं जहां मैं कई कमांड चला सकता हूं।

db:
  image: postgres
web:
  build: .
  command: python manage.py migrate
  command: python manage.py runserver 0.0.0.0:8000
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db

जवाबों:


859

यह पता लगा, उपयोग करें bash -c

उदाहरण:

command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"

बहुविवाह में समान उदाहरण:

command: >
    bash -c "python manage.py migrate
    && python manage.py runserver 0.0.0.0:8000"

या:

command: bash -c "
    python manage.py migrate
    && python manage.py runserver 0.0.0.0:8000
  "

6
@Pedram सुनिश्चित करें कि आप एक ऐसी छवि का उपयोग कर रहे हैं जो वास्तव में बैश स्थापित है। कुछ छवियों को भी bash के लिए एक सीधे रास्ते की आवश्यकता हो सकती है जैसे/bin/bash
कोडेमेन 20

5
यदि कोई बैश स्थापित नहीं है, तो आप sh -c "your कमांड" की कोशिश कर सकते हैं
Chaoste

सुनिश्चित करें कि आप अपने आदेशों को उद्धरण में लपेटते हैं जब बैश के पास जाते हैं और मुझे db को सुनिश्चित करने के लिए "स्लीप 5" को पर्ची करना पड़ता था, लेकिन यह मेरे लिए काम करता था।
ट्रेक

74
अल्पाइन-आधारित छवियों को वास्तव में कोई बैश नहीं लगता है - जैसे @ कचौड़ी की सिफारिश करते हैं और shइसके बजाय उपयोग करते हैं:[sh, -c, "cd /usr/src/app && npm start"]
फ्लोरियन लोच

1
सिर्फ ashअल्पाइन पर भी इस्तेमाल कर सकते हैं :)
जोनाथन

160

मैं एक अलग ephemeral कंटेनर में माइग्रेशन की तरह पूर्व-स्टार्टअप सामान चलाता हूं, जैसे कि (ध्यान दें, रचना फ़ाइल संस्करण 2 'प्रकार की है):

db:
  image: postgres
web:
  image: app
  command: python manage.py runserver 0.0.0.0:8000
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db
  depends_on:
    - migration
migration:
  build: .
  image: app
  command: python manage.py migrate
  volumes:
    - .:/code
  links:
    - db
  depends_on:
    - db

इससे चीजों को साफ और अलग रखने में मदद मिलती है। दो बातों पर विचार करें:

  1. आपको सही स्टार्टअप अनुक्रम सुनिश्चित करना होगा (depend_on का उपयोग करके)

  2. आप कई बिल्ड से बचना चाहते हैं, जो बिल्ड और इमेज का उपयोग करके इसे पहली बार टैग करके हासिल किया गया है; आप तब अन्य कंटेनरों में छवि देख सकते हैं


2
यह मेरे लिए सबसे अच्छा विकल्प लगता है, और मैं इसका उपयोग करना चाहूंगा। क्या आप कई बिल्ड से बचने के लिए अपने टैगिंग सेटअप पर विस्तार से बता सकते हैं? मैं अतिरिक्त कदमों से बचना पसंद करूंगा, इसलिए अगर इसे कुछ की जरूरत है, तो मैं bash -cऊपर जा सकता हूं ।
स्टावरोस कोरोकिथिस

3
ऊपर दिए गए yaml में, माइग्रेशन अनुभाग में बिल्ड और टैगिंग होती है। यह पहली नजर में वास्तव में स्पष्ट नहीं है, लेकिन जब आप निर्माण और छवि गुणों को निर्दिष्ट करते हैं, तो डॉकटर-रचना इसे टैग करती है - जिससे छवि संपत्ति उस निर्माण के लिए टैग निर्दिष्ट करती है। फिर एक नए बिल्ड को ट्रिगर किए बिना बाद में उपयोग किया जा सकता है (यदि आप वेब पर देखते हैं, तो आप देखते हैं कि इसका कोई निर्माण नहीं है, लेकिन केवल एक छवि है)। यहाँ कुछ और विवरण हैं docs.docker.com/compose/compose-file )
Bjoern Stiel

25
जबकि मुझे इसका विचार पसंद है, समस्या यह है कि depend_on केवल उस क्रम में शुरू करना सुनिश्चित करता है, न कि वे उस क्रम में तैयार होते हैं। प्रतीक्षा- for-it.sh कुछ लोगों की जरूरत का समाधान हो सकता है।
ट्रेक

2
यह बिल्कुल सही है और एक शर्म की बात है कि डॉकटर-कंपोज किसी भी ठीक दानेदार नियंत्रण का समर्थन नहीं करता है जैसे कि एक कंटेनर से बाहर निकलने या पोर्ट पर सुनना शुरू करने के लिए इंतजार करना। लेकिन हाँ, एक कस्टम स्क्रिप्ट इसका समाधान करती है, अच्छी बात!
Bjoern Stiel

1
यह उत्तर इस बात की गलत और संभावित विनाशकारी जानकारी देता है कि कैसे depend_on काम करता है।
एन्टनगैस्टम

96

मैं shविरोध के रूप में उपयोग करने की सलाह देता हूं bashक्योंकि यह अधिकांश यूनिक्स आधारित छवियों (अल्पाइन, आदि) पर आसानी से उपलब्ध है।

यहाँ एक उदाहरण है docker-compose.yml:

version: '3'

services:
  app:
    build:
      context: .
    command: >
      sh -c "python manage.py wait_for_db &&
             python manage.py migrate &&
             python manage.py runserver 0.0.0.0:8000"

यह क्रम में निम्नलिखित आदेशों को कॉल करेगा:

  • python manage.py wait_for_db - db के तैयार होने की प्रतीक्षा करें
  • python manage.py migrate - कोई भी माइग्रेशन चलाएं
  • python manage.py runserver 0.0.0.0:8000 - मेरा विकास सर्वर शुरू

2
व्यक्तिगत रूप से यह मेरा पसंदीदा, और सबसे साफ, समाधान है।
बगहुंटरुक

1
मेरा भि। @LondonAppDev अंक-आउट के रूप में, बश सभी कंटेनरों में डिफ़ॉल्ट रूप से स्थान पर अनुकूलन करने के लिए उपलब्ध नहीं है (उदाहरण के लिए, अल्पाइन लिनक्स के शीर्ष पर निर्मित अधिकांश कंटेनर)
ईविलन

2
मैं बहु && एक \ साथ भागने के लिए किया था
आंद्रे वान Zuydam

@AndreVanZuydam हम्म अजीब बात है, मुझे ऐसा करने की आवश्यकता नहीं थी। क्या आप उद्धरणों से घिरे थे? आप क्या कर रहे हैं?
लंदनऐपडेव

2
@oligofren >का उपयोग मल्टी-लाइन इनपुट शुरू करने के लिए किया जाता है (देखें stackoverflow.com/a/3790497/2220370 )
LondonAppDev

39

यह मेरे लिए काम करता है:

version: '3.1'
services:
  db:
    image: postgres
  web:
    build: .
    command:
      - /bin/bash
      - -c
      - |
        python manage.py migrate
        python manage.py runserver 0.0.0.0:8000

    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

docker-compose कमांड चलाने से पहले वेरिएबल्स को डीरेल करने की कोशिश करता है , इसलिए यदि आप वैरिएबल को हैंडल करना चाहते हैं तो आपको डॉलर-संकेतों को दोगुना करने से बचना होगा ...

    command:
      - /bin/bash
      - -c
      - |
        var=$$(echo 'foo')
        echo $$var # prints foo

... अन्यथा आपको एक त्रुटि मिलेगी:

सेवा "वेब" में "कमांड" विकल्प के लिए अमान्य प्रक्षेप प्रारूप:


हाय दोस्त। मुझे एक समस्या मिली: `` `गैर-मान्यता प्राप्त तर्क: / बिन / बैश -c python3 /usr/local/airflow/__init__.py -C Local -T Windows` `कमांड मेरे कमांडर- compose.yml में है: कमांड: - - बिन / बाश - -c - | python3 /usr/local/airflow/__init__.py -C $ {ग्राहक} -T $ {प्रकार} क्या आप जानते हैं कि इसे कैसे ठीक किया जाए? मैं अपने .env फ़ाइल में क्लाइंट और प्रकार जोड़ता हूं।
न्यूट

यहाँ आपके लिए एक doc है: docs.docker.com/compose/compose-file/#variable-substitution मुझे लगता है कि क्या हो रहा है कि आपकी .env फ़ाइल उन वेरिएबल्स को कंटेनर वातावरण में रखती है, लेकिन docker-compose आपके शेल वातावरण में दिख रही है। । इसके बजाय $${Types}और प्रयास करें $${Client}। मुझे लगता है कि यह डॉकटर को उन चरों की व्याख्या करने से रोकता है और आप जो भी शेल बनाते हैं उसमें उनके मूल्यों की तलाश कर रहे हैं, जिससे आप यह कहेंगे कि वे अभी भी उन्हें डीएर्फ़र करने के लिए कोसने के लिए हैं ( डॉकटर ने आपकी फ़ाइल को संसाधित करने के बाद.env )।
MatrixManAtYrService

आपके कमेंट के लिए धन्यवाद। मैंने वही किया जो आपने वास्तव में कहा था। इसलिए मुझे त्रुटि जानकारी में $ (ग्राहक) मिला। मैंने अजगर में os.getenv का उपयोग करने के लिए पर्यावरण चर को पढ़ने का तरीका बदल दिया, जो आसान है। फिर भी धन्यवाद।
न्यूट

23

आप यहां एंट्रीपॉइंट का उपयोग कर सकते हैं। docker में entrypoint कमांड से पहले निष्पादित किया जाता है जबकि कमांड डिफॉल्ट कमांड है जिसे कंटेनर शुरू होने पर चलाया जाना चाहिए। इसलिए अधिकांश एप्लिकेशन आमतौर पर एंट्रीपॉइंट फ़ाइल में सेटअप प्रक्रिया को आगे बढ़ाते हैं और आखिरी में वे कमांड को चलाने की अनुमति देते हैं।

docker-entrypoint.shनिम्नलिखित सामग्री के साथ एक शेल स्क्रिप्ट फ़ाइल हो सकती है (नाम कोई फर्क नहीं पड़ता)।

#!/bin/bash
python manage.py migrate
exec "$@"

docker-compose.yml फ़ाइल के साथ इसका उपयोग करें entrypoint: /docker-entrypoint.shऔर command: python manage.py runserver 0.0.0.0:8000 PS के रूप में कमांड रजिस्टर करें : docker-entrypoint.shअपने कोड के साथ कॉपी करना न भूलें ।


ध्यान दें कि यह तब भी निष्पादित होगा जब आप करते हैंdocker-compose run service-name ....
यह

18

एक अन्य विचार:

यदि, इस स्थिति में, आप कंटेनर का निर्माण करते हैं तो उसमें एक स्टार्टअप स्क्रिप्ट रखें और इसे कमांड के साथ चलाएं। या स्टार्टअप स्क्रिप्ट को वॉल्यूम के रूप में माउंट करें।


: हाँ, अंत में मैं एक run.sh स्क्रिप्ट बनाने के #!/bin/bash \n python manage.py migrate \n python manage.py runserver 0.0.0.0:8000(बदसूरत oneline)
fero

9

* अपडेट करें *

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

डोकर-compose.yaml:

version: '3'

# Can be used as an alternative to VBox/Vagrant
services:

  mongo:
    container_name: mongo
    image: mongo
    build:
      context: .
      dockerfile: deploy/local/Dockerfile.mongo
    ports:
      - "27017:27017"
    volumes:
      - ../.data/mongodb:/data/db

Dockerfile.mongo:

FROM mongo:3.2.12

RUN mkdir -p /fixtures

COPY ./fixtures /fixtures

RUN (mongod --fork --syslog && \
     mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
     mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
     mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
     mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
     mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
     mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
     mongoimport --db wcm-local --collection videos --file /fixtures/videos.json)

यह शायद इसे करने का सबसे साफ तरीका है।

* पुराना तरीका *

मैंने अपने आदेशों के साथ एक शेल स्क्रिप्ट बनाई। इस मामले में मैं शुरू करना चाहता था mongod, और भाग रहा था , mongoimportलेकिन कॉलिंग mongodआपको बाकी को चलाने से रोकता है।

docker-compose.yaml :

version: '3'

services:
  mongo:
    container_name: mongo
    image: mongo:3.2.12
    ports:
      - "27017:27017"
    volumes:
      - ./fixtures:/fixtures
      - ./deploy:/deploy
      - ../.data/mongodb:/data/db
    command: sh /deploy/local/start_mongod.sh

start_mongod.sh :

mongod --fork --syslog && \
mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
mongoimport --db wcm-local --collection videos --file /fixtures/videos.json && \
pkill -f mongod && \
sleep 2 && \
mongod

तो यह कांटा मोंगो बनाता है, मोनोगिमपोर्ट करता है और फिर कांटे हुए मोंगो को मारता है जिसे अलग कर दिया जाता है, और फिर से बिना कोचिंग के इसे शुरू कर देता है। सुनिश्चित नहीं है कि कांटे की प्रक्रिया में संलग्न होने का कोई तरीका है लेकिन यह काम करता है।

नोट: यदि आप कड़ाई से कुछ प्रारंभिक db डेटा लोड करना चाहते हैं तो यह करने का तरीका है:

mongo_import.sh

#!/bin/bash
# Import from fixtures

# Used in build and docker-compose mongo (different dirs)
DIRECTORY=../deploy/local/mongo_fixtures
if [[ -d "/fixtures" ]]; then
    DIRECTORY=/fixtures
fi
echo ${DIRECTORY}

mongoimport --db wcm-local --collection clients --file ${DIRECTORY}/clients.json && \
mongoimport --db wcm-local --collection configs --file ${DIRECTORY}/configs.json && \
mongoimport --db wcm-local --collection content --file ${DIRECTORY}/content.json && \
mongoimport --db wcm-local --collection licenses --file ${DIRECTORY}/licenses.json && \
mongoimport --db wcm-local --collection lists --file ${DIRECTORY}/lists.json && \
mongoimport --db wcm-local --collection properties --file ${DIRECTORY}/properties.json && \
mongoimport --db wcm-local --collection videos --file ${DIRECTORY}/videos.json

mongo_fixtures / *। json फ़ाइलें mongoexport कमांड के माध्यम से बनाई गई थीं।

डोकर-compose.yaml

version: '3'

services:
  mongo:
    container_name: mongo
    image: mongo:3.2.12
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db:cached
      - ./deploy/local/mongo_fixtures:/fixtures
      - ./deploy/local/mongo_import.sh:/docker-entrypoint-initdb.d/mongo_import.sh


volumes:
  mongo-data:
    driver: local

5

यदि आपको एक से अधिक डेमॉन प्रक्रिया चलाने की आवश्यकता है, तो पर्यवेक्षक का उपयोग करने के लिए डॉकर प्रलेखन में एक सुझाव है एक अलग-अलग मोड में करें ताकि सभी उप-डेमॉन स्टडआउट में आउटपुट हो जाएं।

एक और SO प्रश्न से, मुझे पता चला है कि आप आउटपुट में बच्चे की प्रक्रियाओं को स्टडआउट पर पुनर्निर्देशित कर सकते हैं। इस तरह आप सभी आउटपुट देख सकते हैं!


इसे फिर से देखते हुए, यह उत्तर धारावाहिक के बजाय समानांतर में कई कमांड चलाने के लिए अधिक अनुकूल लगता है।
टिम टिसडल


1

वेट -फॉर- इट या डॉक्यूलाइज़ जैसे टूल का उपयोग करें । ये छोटी आवरण लिपियाँ हैं जिन्हें आप अपने अनुप्रयोग की छवि में शामिल कर सकते हैं। या एक अधिक एप्लिकेशन-विशिष्ट कमांड निष्पादित करने के लिए अपनी स्वयं की रैपर स्क्रिप्ट लिखें। इसके अनुसार: https://docs.docker.com/compose/startup-order/


0

मैं अपने जेनकींस कंटेनर को जेनकिंस उपयोगकर्ता के रूप में डॉक कंटेनर बनाने के लिए स्थापित करने की कोशिश करते हुए इसमें भाग गया।

मुझे Dockerfile में docker.sock फ़ाइल को छूने की आवश्यकता है क्योंकि मैं इसे बाद में docker-compose फ़ाइल में लिंक करता हूँ। जब तक मैं इसे पहले नहीं छूता, तब तक यह मौजूद नहीं था। इसने मेरे लिए काम किया।

Dockerfile:

USER root
RUN apt-get update && \
apt-get -y install apt-transport-https \
ca-certificates \
curl \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; 
echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce
RUN groupmod -g 492 docker && \
usermod -aG docker jenkins  && \
touch /var/run/docker.sock && \
chmod 777 /var/run/docker.sock

USER Jenkins

डोकर-compose.yml:

version: '3.3'
services:
jenkins_pipeline:
    build: .
    ports:
      - "8083:8083"
      - "50083:50080"
    volumes:
        - /root/pipeline/jenkins/mount_point_home:/var/jenkins_home
        - /var/run/docker.sock:/var/run/docker.sock

यह विभिन्न प्रश्न के उत्तर की तरह लगता है।
केनोरब

-7

"का उपयोग करके देखें?" आदेशों को अलग करने के लिए यदि आप दो उदाहरणों में हैं

command: "sleep 20; echo 'a'"

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