বাহ্যিক আর্গুমেন্টের সাথে শর্ত থাকলে ডকফায়ফাইল


129

আমার ডকফেরাইল আছে

FROM centos:7
ENV foo=42

তারপর আমি এটি নির্মাণ

docker build -t my_docker .

এবং এটি চালান।

docker run -it -d  my_docker

কমান্ড লাইন থেকে তর্কগুলি পাস করা এবং ডকফাইফিলের সাথে অন্যটি দিয়ে ব্যবহার করা কি সম্ভব? আমি এরকম কিছু বোঝাতে চাইছি

FROM centos:7
if (my_arg==42)
     {ENV=TRUE}
else:
     {ENV=FALSE}

এবং এই যুক্তি দিয়ে তৈরি করুন।

 docker build -t my_docker . --my_arg=42

1
এটি সম্ভবত একটি বিল্ড স্ক্রিপ্ট থেকে পরিচালনা করা উচিত।
স্ন্যাপ দেয়

@ .Ый এটি ভুল। নীচের উত্তরটি দেখুন, এটি
বিল্ড

স্বীকৃত উত্তর প্রশ্নের অংশটি "অন্যথায় শর্ত" কভার করে না। শর্ত চেকের প্রয়োজন হওয়ার প্রয়োজন না হলে এটির নাম "বাহ্যিক যুক্তিযুক্ত ডকরাফিল" নামকরণ করা ভাল।
রুসলান কাবালিন

@ রাস্লানকাবলিন - গৃহীত উত্তরের "তারপরে" এবং "অন্য" উভয় ধারা রয়েছে। শুধু পার্থক্য হল কি "যদি শর্ত" এ পরীক্ষা করা হয়। কোড প্রশ্নে দেখানো: RUN if [ "$arg" == "42" ]; then ENV=TRUE; else ENV=FALSE; fi। অথবা যদি আরগটি অনুপস্থিত থাকে: RUN if [ "x$arg" == "x42" ]; then ...
টুলমেকারস্টেভ

উত্তর:


191

এটি পরিষ্কার দেখতে নাও লাগতে পারে তবে নীচে আপনার ডকফাইফাইল (শর্তসাপেক্ষ) থাকতে পারে:

FROM centos:7
ARG arg
RUN if [ "x$arg" = "x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi

এবং তারপরে চিত্রটি তৈরি করুন:

docker build -t my_docker . --build-arg arg=45

অথবা

docker build -t my_docker .


20
এর [ "$arg" = "x" ]পরিবর্তে হওয়া উচিত নয় [ "x$arg" = "x" ]?
কোয়ান্ট

4
এখানে ত্রিনিরি সুনির্দিষ্ট যুক্তির জন্য পরীক্ষার চেয়ে কোনও যুক্তি সরবরাহ করা হয়েছে কিনা তা খতিয়ে দেখছে। এটি আরও সুস্পষ্ট বলে মনে হয় if [ $arg != "" ] ;তবে আবার
লিখলে তবে

21
if [[ -n "$arg" ]]সত্য যদি কোনও পরম খালি না থাকে, if [[ -z "$arg" ]]সত্য যদি কোনও পরম খালি না থাকে
acumartini

6
স্টেটমেন্ট হলে মাল্টলাইন কীভাবে লিখবেন?
আশুতোষ চামোলি

12
@ কোয়ান্ট - না, দেখুন শেল স্ক্রিপ্টগুলি কেন ... [ "x$arg" = "x" ] দেখে মনে হচ্ছে এটি দুটি উদ্ধৃত স্ট্রিংয়ের সাথে তুলনা করছে তবে উদ্ধৃতিগুলি ছিনিয়ে নেওয়া হয়েছে; এটি সিনট্যাক্সকে সঠিক রাখে। পরে উদ্ধৃতি খুলে: গুড: if x = x ..। খারাপ: if = । তবুও, প্যারামিটারের অস্তিত্বের জন্য আরও ভাল উপায় রয়েছে: ইনপুট আর্গুমেন্টের অস্তিত্ব পরীক্ষা করুন
টুলমেকারস্টেভ

20

কিছু কারণে এখানে বেশিরভাগ উত্তর আমাকে সাহায্য করেনি (সম্ভবত এটি ডকফাইফাইলের আমার FROM চিত্রের সাথে সম্পর্কিত)

সুতরাং আমি যুক্তিটি ফাঁকা আছে কি না তা পরীক্ষা করে ডকার বিল্ড করার সময় যদি বিবৃতিটি পরিচালনা করতে হয় তবে bash scriptআমার ওয়ার্কস্পেসে একটি তৈরি করতে পছন্দ করতাম--build-arg

বাশ লিপি:

#!/bin/bash -x

if test -z $1 ; then 
    echo "The arg is empty"
    ....do something....
else 
    echo "The arg is not empty: $1"
    ....do something else....
fi

Dockerfile:

FROM ...
....
ARG arg
COPY bash.sh /tmp/  
RUN chmod u+x /tmp/bash.sh && /tmp/bash.sh $arg
....

ডকার বিল্ড:

docker build --pull -f "Dockerfile" -t $SERVICE_NAME --build-arg arg="yes" .

মন্তব্য: এটি ব্যাশ স্ক্রিপ্টের অন্যথায় (মিথ্যা) যাবে

docker build --pull -f "Dockerfile" -t $SERVICE_NAME .

মন্তব্য: এটি যদি (সত্য) যায়

সম্পাদনা 1:

বেশ কয়েকটি চেষ্টার পরে আমি নিম্নলিখিত নিবন্ধটি পেয়েছি এবং এটি একটি যা আমাকে 2 টি জিনিস বুঝতে সাহায্য করেছে:

1) এফআরএম এর আগে এআরজি বিল্ডের বাইরে

২) ডিফল্ট শেলটি হ'ল / বিন / শ, যার অর্থ যদি অন্যটি ডকার বিল্ডে কিছুটা আলাদা কাজ করে। উদাহরণস্বরূপ আপনার স্ট্রিংগুলির তুলনা করতে "==" এর পরিবর্তে কেবল একটি "=" প্রয়োজন।

সুতরাং আপনি এটি ভিতরে করতে পারেন Dockerfile

ARG argname=false   #default argument when not provided in the --build-arg
RUN if [ "$argname" = "false" ] ; then echo 'false'; else echo 'true'; fi

এবং এর মধ্যে docker build:

docker build --pull -f "Dockerfile" --label "service_name=${SERVICE_NAME}" -t $SERVICE_NAME --build-arg argname=true .


16

প্রস্তাবিত সমাধানগুলির একটি আকর্ষণীয় বিকল্প রয়েছে, এটি একটি একক ডকফেরফিলের সাথে কাজ করে , শর্তাধীন বিল্ডের জন্য ডকার বিল্ডের জন্য কেবল একটি একক কল প্রয়োজন এবং ব্যাশ এড়ানো যায়

সমাধান:

নিম্নলিখিত Dockerfileসমস্যাটি সমাধান করে। এটিকে অনুলিপি করুন এবং নিজে চেষ্টা করুন।

ARG my_arg

FROM centos:7 AS base
RUN echo "do stuff with the centos image"

FROM base AS branch-version-1
RUN echo "this is the stage that sets VAR=TRUE"
ENV VAR=TRUE

FROM base AS branch-version-2
RUN echo "this is the stage that sets VAR=FALSE"
ENV VAR=FALSE

FROM branch-version-${my_arg} AS final
RUN echo "VAR is equal to ${VAR}"

ডকফাইফাইলের ব্যাখ্যা:

আমরা প্রথমে একটি baseচিত্র পাই ( centos:7আপনার ক্ষেত্রে) এবং এটি তার নিজস্ব পর্যায়ে রাখি। baseপর্যায় বিষয় আছে যা আপনি শর্ত সামনে কাজ করতে চান থাকা উচিত। এর পরে, আমাদের আরও দুটি পর্যায় রয়েছে, যা আমাদের অবস্থার শাখাগুলি উপস্থাপন করে: branch-version-1এবং branch-version-2। আমরা উভয় নির্মাণ। finalএই পর্যায়ে তা চয়ন একটির পর্যায় উপর ভিত্তি করে my_arg। শর্তাধীন ডকফেরাইল। এই নাও.

চলমান অবস্থায় আউটপুট:

(আমি এটি একটু সংক্ষেপে ...)

my_arg==2

docker build --build-arg my_arg=2 .
Step 1/12 : ARG my_arg
Step 2/12 : ARG ENV
Step 3/12 : FROM centos:7 AS base
Step 4/12 : RUN echo "do stuff with the centos image"
do stuff with the centos image
Step 5/12 : FROM base AS branch-version-1
Step 6/12 : RUN echo "this is the stage that sets VAR=TRUE"
this is the stage that sets VAR=TRUE
Step 7/12 : ENV VAR=TRUE
Step 8/12 : FROM base AS branch-version-2
Step 9/12 : RUN echo "this is the stage that sets VAR=FALSE"
this is the stage that sets VAR=FALSE
Step 10/12 : ENV VAR=FALSE
Step 11/12 : FROM branch-version-${my_arg}
Step 12/12 : RUN echo "VAR is equal to ${VAR}"
VAR is equal to FALSE

my_var==1

docker build --build-arg my_arg=1 .
...
Step 11/12 : FROM branch-version-${my_arg}
Step 12/12 : RUN echo "VAR is equal to ${VAR}"
VAR is equal to TRUE

এই বিস্ময়কর ধারণার জন্য ট্যানিসকে ধন্যবাদ!


এখন পর্যন্ত, সেরা পদ্ধতির।
ফিলিপ দেশীদারতী

খুব ভেবেছি, কেন আমি এখানে এটি পোস্ট করেছি ts @ ফিলিপডিজাইডারটি
ব্যবহারকারী 12547645

1
এটি এখানে উপস্থাপিত সকলের সেরা সমাধান, কারণ আপনাকে স্ক্রিপ্ট / ব্যাশ সহ ওয়ার্কআউন্ডস ব্যবহার করার দরকার নেই, তবে এমন একটি উপায় ব্যবহার করুন যাতে কেবল ডকফেরফিল জ্ঞান জড়িত থাকে। দুর্দান্ত উত্তর।
আকিতো

"এআরজি এএনভি" কী করে? আপনি কি এই বিষয়ে কিছু আলোকপাত করতে পারেন? ধন্যবাদ।
সর্বোচ্চ

এটি নির্দেশ করার জন্য @ ম্যাক্স ধন্যবাদ। এটি প্রয়োজনীয় নয়
ব্যবহারকারী 12547645

12

এটি করতে সরাসরি "পরীক্ষা" বাইনারি ব্যবহার করুন। আপনার যদি নপ কমান্ড ":" ব্যবহার করা উচিত তবে যদি আপনি "অন্য" শর্তটি নির্দিষ্ট করতে না চান, সুতরাং ডকার একটি শূন্য নয় রিটার্ন মান ত্রুটির সাথে থামবে না।

RUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
RUN test -z "$YOURVAR" && echo "var is not set" || :
RUN test -z "$YOURVAR" || echo "var is set" && :

2
একই হিসাবে RUN [ -z "$YOURVAR" ] && ... || :, আমি বিশ্বাস করি
ওয়ানডে ক্রিকেটার

4
নিম্নলিখিত বিবৃতি জন্য, যদি var সেট করা থাকে তবে উভয় প্রতিধ্বনি সম্পাদিত হয়। RUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
হর্ষদ ভাইয়াাহারে

প্রকৃতপক্ষে. মনে রাখবেন যে এগুলি ব্রাঞ্চযুক্ত শর্তসাপূর্ণ ব্লক নয়, তারা ক্রমিকভাবে সম্পাদন করে, &&সামনে রাখে ||:test ! -z "$YOURVAR" && echo "var is set" || echo "var is not set"
ব্র্যান্ডেট

5

অন্যরা যেমন বলেছেন, শেল স্ক্রিপ্ট সাহায্য করবে

কেবলমাত্র একটি অতিরিক্ত কেস, আইএমএইচও এটি উল্লেখ করার মতো (অন্য কারও জন্য যারা এখানে হোঁচট খায়, একটি সহজ কেস খুঁজছেন), এটি পরিবেশ প্রতিস্থাপন

এনভায়রনমেন্ট ভেরিয়েবল ( ENVবিবৃতি দিয়ে ঘোষিত ) নির্দিষ্ট নির্দেশাবলীতেও ব্যবহার করতে পারে ভেরিয়েবল দ্বারা ব্যাখ্যা করার জন্য Dockerfile

${variable_name}সিনট্যাক্স এছাড়াও মান ব্যাশ সংশোধনকারীদের কয়েক সমর্থন নীচে নির্দিষ্ট হিসাবে:

  • ${variable:-word}ইঙ্গিত করে যে যদি variableসেট করা থাকে তবে ফলাফলটি সেই মান হবে। যদি variableসেট না wordকরা থাকে তবে ফলাফল হবে।

  • ${variable:+word}ইঙ্গিত করে যে যদি variableসেট wordকরা থাকে তবে ফলাফলটি হবে, অন্যথায় ফলাফলটি খালি স্ট্রিং।


5

গৃহীত উত্তর প্রশ্ন সমাধান হতে পারে, কিন্তু যদি আপনি একাধিক লাইন চান ifdockerfile অবস্থার, আপনি যে স্থাপন করতে পারি না \প্রতিটি লাইনের শেষে (আপনি একটি শেল স্ক্রিপ্ট-এ করতে হবে অনুরূপ) এবং সঙ্গে প্রতিটি কমান্ড বিভক্তি এ ;। আপনি এমনকি set -euxপ্রথম কমান্ড হিসাবে সামটিং সংজ্ঞায়িত করতে পারেন ।

উদাহরণ:

RUN set -eux; \
  if [ -f /path/to/file ]; then \
    mv /path/to/file /dest; \
  fi; \
  if [ -d /path/to/dir ]; then \
    mv /path/to/dir /dest; \
  fi

তোমার ক্ষেত্রে:

FROM centos:7
ARG arg
RUN if [ -z "$arg" ] ; then \
    echo Argument not provided; \
  else \
    echo Argument is $arg; \
  fi

তারপরে এটি নির্মাণ করুন:

docker build -t my_docker . --build-arg arg=42

4

ব্যাশ স্ক্রিপ্ট এবং আলপাইন / সেন্টোস ব্যবহার করা

Dockerfile

FROM alpine  #just change this to centos 

ARG MYARG=""
ENV E_MYARG=$MYARG

ADD . /tmp
RUN chmod +x /tmp/script.sh && /tmp/script.sh

script.sh

#!/usr/bin/env sh

if [ -z "$E_MYARG" ]; then
    echo "NO PARAM PASSED"
else
    echo $E_MYARG
fi

পাসিং আরগ: docker build -t test --build-arg MYARG="this is a test" .

....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
 ---> Running in 10b0e07e33fc
this is a test
Removing intermediate container 10b0e07e33fc
 ---> f6f085ffb284
Successfully built f6f085ffb284

তর্ক ছাড়াই: docker build -t test .

....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
 ---> Running in b89210b0cac0
NO PARAM PASSED
Removing intermediate container b89210b0cac0
....
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.