ARG หรือ ENV จะใช้อันไหนในกรณีนี้


122

นี่อาจเป็นคำถามเล็กน้อย แต่การอ่านเอกสารสำหรับARGและENVไม่ได้ทำให้ฉันกระจ่าง

ฉันกำลังสร้างคอนเทนเนอร์ PHP-FPM และฉันต้องการให้ความสามารถในการเปิด / ปิดส่วนขยายบางอย่างตามความต้องการของผู้ใช้

จะดีมากถ้าสามารถทำได้ใน Dockerfile โดยการเพิ่มเงื่อนไขและส่งแฟล็กบนคำสั่ง build แต่อาจไม่รองรับ 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 files) คำจำกัดความที่มีจุดประสงค์เดียวที่จะตั้งค่าสถานะนี้เพื่อให้สคริปต์รู้ว่าจะทำอย่างไร ...

  • วิธีนี้เป็นวิธีที่ถูกต้องหรือไม่?
  • ฉันควรใช้ENVเพื่อจุดประสงค์นี้หรือไม่?

ฉันเปิดรับแนวคิดหากคุณมีแนวทางอื่นเพื่อบรรลุเป้าหมายนี้โปรดแจ้งให้เราทราบ


หากส่วนขยาย / คุณสมบัติเหล่านั้นแตกต่างจากรุ่นหนึ่งไปยังอีกรุ่นหนึ่งคุณควรใช้ARGเพื่อตั้งค่าด้วยค่าที่แตกต่างกันโดยใช้แต่ละ--build-argบิลด์และคุณยังสามารถใช้ค่าเริ่มต้นใน Dockerfile ได้ หากคุณใช้ENVคุณจะต้องแก้ไข Dockerfile เองสำหรับทุกบิลด์เพื่อตั้งค่าที่แตกต่างกัน
AA

คำตอบ:


217

จากการอ้างอิง Dockerfile :

  • ARGคำแนะนำและกำหนดตัวแปรที่ผู้ใช้งานสามารถส่งผ่านที่สร้างเวลาในการสร้างที่มีนักเทียบท่าสร้างคำสั่งใช้เป็น--build-arg <varname>=<value>ธง

  • ENVการเรียนการสอนชุดตัวแปรสภาพแวดล้อมค่า<key> ตัวแปรสภาพแวดล้อมที่ตั้งค่าโดยใช้จะยังคงมีอยู่เมื่อคอนเทนเนอร์ถูกเรียกใช้จากอิมเมจผลลัพธ์<value>
    ENV

ดังนั้นหากคุณต้องการการปรับแต่งบิลด์ไทม์ARGเป็นทางเลือกที่ดีที่สุดของคุณ
หากคุณต้องการการปรับแต่งรันไทม์ (เพื่อเรียกใช้ภาพเดียวกันโดยใช้การตั้งค่าที่แตกต่างกัน) ENVก็เหมาะสมอย่างยิ่ง

ถ้าฉันต้องการเพิ่มสมมติว่าส่วนขยาย 20 (ตัวเลขสุ่ม) หรือคุณสมบัติอื่น ๆ ที่สามารถเปิดใช้งาน | ปิดใช้งาน

ด้วยจำนวนชุดค่าผสมที่เกี่ยวข้องการใช้ENVเพื่อตั้งค่าคุณสมบัติเหล่านั้นในรันไทม์จะดีที่สุดที่นี่

แต่คุณสามารถรวมทั้งสองอย่างได้โดย:

  • การสร้างภาพด้วยไฟล์ ARG
  • โดยใช้ARGเป็นไฟล์ENV

นั่นคือด้วย Dockerfile รวมถึง:

ARG var
ENV var=${var}

จากนั้นคุณสามารถสร้างอิมเมจที่มีvarค่าเฉพาะในเวลาสร้าง ( docker build --build-arg var=xxx) หรือเรียกใช้คอนเทนเนอร์ที่มีค่ารันไทม์เฉพาะ ( docker run -e var=yyy)


1
เยี่ยมมาก แต่ARGสามารถเข้าถึงได้จากสคริปต์ที่ฉันกำลังเรียกใช้ในการเริ่มต้นคอนเทนเนอร์? ถ้าเป็นอย่างไร คุณช่วยปรับปรุงคำตอบของคุณได้ไหมโดยเพิ่มตัวอย่างเล็กน้อยเกี่ยวกับวิธีเข้าถึงคำตอบจากสคริปต์ทุบตี
ReynierPM

@ReynierPM คุณสามารถด้วยการประกาศใน Dockerfile (เวลาในการสร้างของคุณ) ในนอกเหนือจากARGการENV var=${var}ดูstackoverflow.com/a/33936014/6309 ใช้ทั้งสองอย่าง
VonC

ถ้าฉันใช้แนวทางของคุณไม่ว่าฉันจะลงเอยด้วยvarตัวแปร ENV บนคอนเทนเนอร์เมื่อเริ่มต้นฉันพูดถูก? ไม่อย่างนั้นฉันจะไม่ติดตามคุณเลย โปรดจำไว้ว่าสคริปต์จะถูกคัดลอกจากโฟลเดอร์ในเครื่องไปยังคอนเทนเนอร์และใช้ในการเริ่มต้นคอนเทนเนอร์นั่นเป็นเหตุผลที่ฉันใช้ ENV แทน ARG เพราะฉันไม่รู้ว่าเมื่อใดที่คอนเทนเนอร์เริ่มต้น ARG ยังคงมีชีวิตอยู่และสามารถเข้าถึงได้จากภายใน สคริปต์ทุบตี
ReynierPM

ฉันได้เพิ่ม Dockerfile ของฉันเพื่อให้คุณสามารถดูและรู้ว่าฉันกำลังทำอะไรอยู่
ReynierPM

1
@HardeepSingh ทั้งสอง: ENV ( stackoverflow.com/a/33836848/6309 ) และ ARG ( stackoverflow.com/a/41593407/6309 )
VonC

0

ดังนั้นหากต้องการตั้งค่าของตัวแปรสภาพแวดล้อมเป็นสิ่งที่แตกต่างกันสำหรับทุก ๆ บิลด์เราสามารถส่งผ่านค่าเหล่านี้ในช่วงเวลาสร้างและเราไม่จำเป็นต้องเปลี่ยนไฟล์นักเทียบท่าทุกครั้ง

ในขณะที่ENVเมื่อตั้งค่าแล้วจะไม่สามารถเขียนทับผ่านค่าบรรทัดคำสั่งได้ ดังนั้นหากเราต้องการให้ตัวแปรสภาพแวดล้อมของเรามีค่าที่แตกต่างกันสำหรับการสร้างที่แตกต่างกันเราสามารถใช้ARGและตั้งค่าเริ่มต้นในไฟล์นักเทียบท่าของเราได้ และเมื่อเราต้องการเขียนทับค่าเหล่านี้เราสามารถทำได้โดยใช้--build-argsในทุก ๆ บิลด์โดยไม่ต้องเปลี่ยนไฟล์นักเทียบท่าของเรา

สำหรับรายละเอียดเพิ่มเติมที่คุณสามารถดูนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.