एआरजी या ईएनवी, इस मामले में किसका उपयोग करना है?


122

यह शायद एक तुच्छ प्रश्न हो सकता है, लेकिन ARG और ENV के लिए डॉक्स पढ़ना मेरे लिए स्पष्ट चीजें नहीं रखता है।

मैं एक PHP-FPM कंटेनर बना रहा हूं और मैं उपयोगकर्ता की जरूरतों पर कुछ एक्सटेंशन को सक्षम / अक्षम करने की क्षमता देना चाहता हूं।

यह बहुत अच्छा होगा अगर इसे डॉकफेरफाइल में सशर्त जोड़कर और फ्लैग को कमांड कमांड पर पारित करके किया जा सकता है लेकिन AFAIK समर्थित नहीं है।

मेरे मामले में और मेरा व्यक्तिगत दृष्टिकोण कंटेनर शुरू होने पर एक छोटी सी स्क्रिप्ट को चलाने का है, निम्नलिखित कुछ:

#!/bin/sh   
set -e

RESTART="false"

# This script will be placed in /config/init/ and run when container starts.
if  [ "$INSTALL_XDEBUG" == "true" ]; then
    printf "\nInstalling Xdebug ...\n"
    yum install -y  php71-php-pecl-xdebug
    RESTART="true"
fi
...   
if  [ "$RESTART" == "true" ]; then
    printf "\nRestarting php-fpm ...\n"
    supervisorctl restart php-fpm
fi

exec "$@"

यह मेरी Dockerfileतरह दिखता है:

FROM reynierpm/centos7-supervisor
ENV TERM=xterm \
    PATH="/root/.composer/vendor/bin:${PATH}" \
    INSTALL_COMPOSER="false" \
    COMPOSER_ALLOW_SUPERUSER=1 \
    COMPOSER_ALLOW_XDEBUG=1 \
    COMPOSER_DISABLE_XDEBUG_WARN=1 \
    COMPOSER_HOME="/root/.composer" \
    COMPOSER_CACHE_DIR="/root/.composer/cache" \
    SYMFONY_INSTALLER="false" \
    SYMFONY_PROJECT="false" \
    INSTALL_XDEBUG="false" \
    INSTALL_MONGO="false" \
    INSTALL_REDIS="false" \
    INSTALL_HTTP_REQUEST="false" \
    INSTALL_UPLOAD_PROGRESS="false" \
    INSTALL_XATTR="false"

RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
                   https://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum install -y  \
        yum-utils \
        git \
        zip \
        unzip \
        nano \
        wget \
        php71-php-fpm \
        php71-php-cli \
        php71-php-common \
        php71-php-gd \
        php71-php-intl \
        php71-php-json \
        php71-php-mbstring \
        php71-php-mcrypt \
        php71-php-mysqlnd \
        php71-php-pdo \
        php71-php-pear \
        php71-php-xml \
        php71-pecl-apcu \
        php71-php-pecl-apfd \
        php71-php-pecl-memcache \
        php71-php-pecl-memcached \
        php71-php-pecl-zip && \
        yum clean all && rm -rf /tmp/yum*

RUN ln -sfF /opt/remi/php71/enable /etc/profile.d/php71-paths.sh && \
    ln -sfF /opt/remi/php71/root/usr/bin/{pear,pecl,phar,php,php-cgi,phpize} /usr/local/bin/. && \
    mv -f /etc/opt/remi/php71/php.ini /etc/php.ini && \
    ln -s /etc/php.ini /etc/opt/remi/php71/php.ini && \
    rm -rf /etc/php.d && \
    mv /etc/opt/remi/php71/php.d /etc/. && \
    ln -s /etc/php.d /etc/opt/remi/php71/php.d

COPY container-files /
RUN chmod +x /config/bootstrap.sh
WORKDIR /data/www
EXPOSE 9001

यहाँ पूरी रिपॉजिटरी है अगर आपको यह समझने के लिए कि मुझे क्या करना है, यह समझने के लिए एक गहरी नज़र रखने की आवश्यकता है

वर्तमान में यह काम कर रहा है, लेकिन ... यदि मैं जोड़ना चाहता हूं कि एक्सटेंशन या किसी अन्य सुविधा को 20 (एक यादृच्छिक संख्या) कह सकते हैं जो सक्षम हो सकता है। अक्षम हो जाता है तो मैं 20 गैर-आवश्यक के साथ समाप्त ENVहो जाऊंगा (क्योंकि Dockerfile समर्थन नहीं करता है ।env फाइलें) की परिभाषा जिसका एकमात्र उद्देश्य यह झंडा लगाना होगा कि स्क्रिप्ट को पता है कि तब क्या करना है ...

  • क्या इसे करने का सही तरीका है?
  • क्या मुझे ENVइस उद्देश्य के लिए उपयोग करना चाहिए ?

यदि आपके पास इसे प्राप्त करने के लिए एक अलग दृष्टिकोण है, तो कृपया मुझे इसके बारे में बताएं


यदि वे एक्सटेंशन / सुविधाएँ एक बिल्ड से दूसरे बिल्ड में भिन्न होंगी, तो आपको ARGउन्हें प्रत्येक बिल्ड के साथ विभिन्न मानों के साथ सेट करने के लिए उपयोग करना चाहिए --build-arg, और आप अभी भी Dockerfile में डिफ़ॉल्ट मानों का उपयोग कर सकते हैं। यदि आप उपयोग करते हैं ENV, तो आपको अलग-अलग मूल्यों को सेट करने के लिए हर निर्माण के लिए खुद डॉकरफाइल को संपादित करना होगा
AA

जवाबों:


216

से Dockerfile संदर्भ :

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

  • ENVअनुदेश वातावरण चर सेट <key>मूल्य के लिए <value>। जब एक कंटेनर परिणामी छवि से चलाया जाता है, तो
    उपयोग किए जाने वाले वातावरण चर ENVबने रहेंगे।

इसलिए अगर आपको बिल्ड-टाइम कस्टमाइजेशन की जरूरत है , तो ARGयह आपकी सबसे अच्छी पसंद है।
यदि आपको रन-टाइम कस्टमाइज़ेशन (विभिन्न सेटिंग्स के साथ एक ही छवि को चलाने के लिए) की आवश्यकता है, तो ENVयह अच्छी तरह से अनुकूल है।

अगर मैं जोड़ना चाहता हूं कि एक्सटेंशन के 20 (एक यादृच्छिक संख्या) या किसी भी अन्य सुविधा को सक्षम करें जिसे अक्षम किया जा सकता है |

इसमें शामिल संयोजनों की संख्या को देखते हुए, ENVउन सुविधाओं को रनटाइम पर सेट करने के लिए उपयोग करना सबसे अच्छा है।

लेकिन आप दोनों को जोड़ सकते हैं :

  • एक विशिष्ट के साथ एक छवि का निर्माण ARG
  • कि ARGएक के रूप में उपयोग करENV

यह एक डॉकफाइल सहित है:

ARG var
ENV var=${var}

तब आप varबिल्ड-टाइम पर एक विशिष्ट मान के साथ एक छवि बना सकते हैं ( docker build --build-arg var=xxxया विशिष्ट रनटाइम मान के साथ एक कंटेनर चला सकते हैं docker run -e var=yyy)


1
महान लेकिन उन ARGस्क्रिप्ट से पहुँचा जा सकता है जो मैं कंटेनर स्टार्टअप पर चला रहा हूं? यदि हां, तो कैसे? क्या आप अपने उत्तर को थोड़ा उदाहरण जोड़कर सुधार सकते हैं कि कैसे उन्हें एक बैश स्क्रिप्ट से एक्सेस किया जा सकता है?
रेनियरपीएम

@ReynierPM आप अपने Dockerfile (निर्माण समय) में घोषणा करते हुए में से कर सकते हैं इसके अलावा की ARG, एक ENV var=${var}: देखने stackoverflow.com/a/33936014/6309 । दोनों का उपयोग करें।
वॉनसी

अगर मैं आपके दृष्टिकोण का उपयोग करता हूं तो कोई फर्क नहीं पड़ता कि मैं varकंटेनर पर एक ईएनवी चर के साथ समाप्त हो जाएगा जब यह शुरू होता है, तो मैं सही हूं? नहीं तो मैं तुम्हारा पीछा नहीं कर रहा हूँ। इसे याद रखें: स्क्रिप्ट को स्थानीय फ़ोल्डर से कंटेनर में कॉपी किया जाता है और इसका उपयोग कंटेनर इनिशियलाइज़ेशन पर किया जाता है, इसीलिए मैं ARG के बजाय ENV का उपयोग कर रहा हूँ क्योंकि मुझे नहीं पता कि कंटेनर कब ARG को ज़िंदा करना शुरू करता है और उसे अंदर से एक्सेस किया जा सकता है एक बैश स्क्रिप्ट।
रेनियरपीएम

मैंने अपना डॉकरीफ़ाइल जोड़ा है ताकि आप इसे देख सकें और जान सकें कि मैं इस समय क्या कर रहा हूँ
रेनियरपीएम

1
@ हर्षदीपसिंह दोनों: ENV ( stackoverflow.com/a/33836848/6309 ) और ARG ( stackoverflow.com/a/41593407/6309 )
VonC

0

इसलिए अगर हर बिल्ड के लिए कुछ अलग करने के लिए एक पर्यावरण चर का मान सेट करना चाहते हैं तो हम बिल्ड टाइम के दौरान इन मानों को पारित कर सकते हैं और हमें हर बार अपने डॉक फ़ाइल को बदलने की आवश्यकता नहीं है।

जबकि ENV, एक बार सेट को कमांड लाइन मानों के माध्यम से अधिलेखित नहीं किया जा सकता है। इसलिए, यदि हम अपने पर्यावरण चर को अलग-अलग बिल्ड के लिए अलग-अलग मान रखना चाहते हैं तो हम ARGअपनी डॉक फ़ाइल में डिफ़ॉल्ट मानों का उपयोग और सेट कर सकते हैं । और जब हम इन मूल्यों को अधिलेखित करना चाहते हैं तो हम --build-argsअपने डॉक फ़ाइल को बदले बिना हर बिल्ड पर ऐसा कर सकते हैं ।

अधिक जानकारी के लिए आप उल्लेख कर सकते हैं इस

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