Dockerfile में पर्यावरण चर मूल्य प्राप्त करें


254

मैं एक रूबी ऐप के लिए एक कंटेनर बना रहा हूं। मेरे ऐप का कॉन्फ़िगरेशन पर्यावरण चर ( ऐपेनव के साथ ऐप के अंदर लोड ) के भीतर निहित है ।

उन कॉन्फ़िगरेशन चर में से एक ऐप का सार्वजनिक आईपी है, जिसका उपयोग आंतरिक रूप से लिंक बनाने के लिए किया जाता है। मुझे कंटेनर के अंदर इस आईपी को 127.0.0.1 पर इंगित करते हुए एक dnsmasq प्रविष्टि जोड़ने की आवश्यकता है, इसलिए यह ऐप के लिंक को प्राप्त कर सकता है जैसे कि यह कंटेनरीकृत नहीं था।

इसलिए मैं ENVअपने डॉकरफाइल में एक सेट करने की कोशिश कर रहा हूं जो कंटेनर के लिए एक पर्यावरण चर होगा।

मैंने कुछ चीजों की कोशिश की।

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

यद्यपि सब कुछ "REQUEST_DOMAIN" स्ट्रिंग के बजाय पर्यावरण चर के मान से गुजरता है। क्या मेजबान मशीन से कंटेनर तक पर्यावरण चर मानों को पारित करने का एक तरीका है?

जवाबों:


392

आपको अपने डॉकेरफाइल में ARGनिर्देश का उपयोग करना चाहिए जो इस उद्देश्य के लिए है।

ARGअनुदेश एक चर है कि उपयोगकर्ताओं को डोकर निर्माण आदेश का उपयोग कर के साथ बिल्डर को निर्माण समय में पारित कर सकते हैं परिभाषित करता है --build-arg <varname>=<value>झंडा।

तो आपके डॉकरीफाइल में यह रेखा होगी:

ARG request_domain

या यदि आप एक डिफ़ॉल्ट मान पसंद करेंगे:

ARG request_domain=127.0.0.1

अब आप अपने चरवाहे के अंदर इस चर का संदर्भ दे सकते हैं:

ENV request_domain=$request_domain

तो आप अपने कंटेनर का निर्माण करेंगे जैसे:

$ docker build --build-arg request_domain=mydomain Dockerfile


नोट 1: यदि आपने ARGअपने डॉकरीफाइल में संदर्भित किया है , लेकिन इसे बाहर रखा है तो आपकी छवि नहीं बनेगी --build-arg

नोट 2: यदि कोई उपयोगकर्ता एक बिल्ड तर्क निर्दिष्ट करता है जिसे डॉकफाइल में परिभाषित नहीं किया गया था, तो बिल्ड एक चेतावनी को आउटपुट करता है:

[चेतावनी] एक या अधिक बिल्ड-आर्ग्स [फू] का सेवन नहीं किया गया।


12
एआरजी docker v1.9 के बाद से उपलब्ध है।
सायेंसो

क्या यह डॉकटर रेपो पर दूर से निर्मित होने के लिए समर्थित है?
जेम्स लिन

4
Your image will not build if you have referenced an ARG in your Dockerfile but excluded it in --build-argतुम गलत हो। आप बिना --build-arg के भी संदर्भ के साथ छवि बना सकते हैं। इसके अलावा आप बिल्ड arg के लिए डिफ़ॉल्ट मान सेट कर सकते हैं।
ALex_hha

1
ईएनवी लाइन का उद्देश्य क्या है? मेरे लिए --build-arg + ARG काफी था।
फिल

3
एआरजी बाद के आदेशों में डॉकफाइल के अंदर उपयोग किए जाने वाले एक चर को परिभाषित करता है। ईएनवी एक पर्यावरण चर को परिभाषित करता है जिसे कंटेनर में पारित किया जाता है।
10

56

तो आप कर सकते हैं: cat Dockerfile | envsubst | docker build -t my-target -

तो कुछ के साथ एक Dockerfile है:

ENV MY_ENV_VAR $MY_ENV_VAR

मुझे लगता है कि कुछ विशेष पात्रों के साथ कोई समस्या हो सकती है, लेकिन यह अधिकांश मामलों के लिए कम से कम काम करता है।


13
यदि आपको निर्देशिका से DDerfile युक्त ADD फ़ाइलों की आवश्यकता है तो यह काम नहीं करता है।
टॉम हेनेन

2
बहुत अच्छा समाधान! एक मैक पर आप के envsubstहिस्से के रूप में प्राप्त कर सकते हैं brew install gettext। लेकिन बीएसडी बिल्ड सिस्टम के साथ संभावित संघर्षों के कारण यह "केग-ओनली" है और कोई सहानुभूति नहीं बनती है। हालाँकि, ln -s /usr/local/Cellar/gettext/*/bin/envsubst /usr/local/bin/उस एक आदेश को अपने PATH में जोड़ना सुरक्षित है । (यह वास्तव में लिबास है जो चिंता का विषय है।) या आप इसे इसके /usr/local/Cellar/gettext/*/bin/envsubstस्थान पर उपयोग कर सकते हैं
ब्रूनो ब्रोंस्की

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

4
Re @ TomHennen की टिप्पणी, यदि आप अपने Dockerfile में COPY जैसे संदर्भ-निर्भर आदेशों का उपयोग करना चाहते हैं , तो आप हमेशा एन्वसबस्ट के आउटपुट को एक अस्थायी फ़ाइल पर पुनर्निर्देशित कर सकते हैं और फिर docker buildइसके बजाय उसे फीड कर सकते हैं। उदाहरण: cat Dockerfile | envsubst > DockerfileWithEnvVarsहै, तो docker build -t my-target -f DockerfileWithEnvVars ., तोrm DockerfileWithEnvVars
Snark

या आप अधिक पैकेज से स्पंज का उपयोग कर सकते हैंenvsubst < Dockerfile | sponge Dockerfile
ALex_hha

19

envsubstआदेशों की तरह COPYया ADDबिना मध्यवर्ती फ़ाइलों का उपयोग करने की क्षमता को खोए बिना उपयोग करने का एक विकल्प बैश के प्रक्रिया प्रतिस्थापन का उपयोग करना होगा :

docker build -f <(envsubst < Dockerfile) -t my-target .

3
दुर्भाग्य से यह काम करने के लिए नहीं लगता है (डॉकर 17.09), मुझे त्रुटि मिलती है unable to prepare context: the Dockerfile (/dev/fd/63) must be within the build context
अलेक्जेंडर क्लिमेत्स्क

11

रनवे पर आपके द्वारा बनाई गई फ़ाइल से पर्यावरण चर लोड करें।

export MYVAR="my_var_outside"
cat > build/env.sh <<EOF
MYVAR=${MYVAR}
EOF

... तो डॉकरीफाइल में

ADD build /build
RUN /build/test.sh

जहां test.sh ने env.sh से MYVAR को लोड किया

#!/bin/bash
. /build/env.sh
echo $MYVAR > /tmp/testfile

4

यदि आप एक डॉकफ़राइल में सभी पर्यावरण चर ($ ExampleEnvVar) को ढूंढना और बदलना चाहते हैं, तो इसे बनाएं यह काम करेगा:

envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -


यहां सबसे अच्छा जवाब, और उस पर आधारित, करने में सक्षम था: envsubst < ./Dockerfile | docker build -squash -t ${DOCKIMG}:${VERSION} . -f -जहां FROMलाइन पर्यावरण चर का उपयोग कर रही है।
mikequentel

-6

-eकंटेनर में पर्यावरण चर पास करने के लिए कुंजी जोड़ें । उदाहरण:

$ MYSQLHOSTIP=$(sudo docker inspect -format="{{ .NetworkSettings.IPAddress }}" $MYSQL_CONRAINER_ID)
$ sudo docker run -e DBIP=$MYSQLHOSTIP -i -t myimage /bin/bash

root@87f235949a13:/# echo $DBIP
172.17.0.2

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