เป็นไปได้หรือไม่ที่จะตั้งค่าตัวแปร docker ENV ให้เป็นผลลัพธ์ของคำสั่ง ชอบ:
ENV MY_VAR whoami
ฉันต้องการให้ MY_VAR ได้รับค่า "root" หรืออะไรก็ตามที่ส่งคืน whoami
เป็นไปได้หรือไม่ที่จะตั้งค่าตัวแปร docker ENV ให้เป็นผลลัพธ์ของคำสั่ง ชอบ:
ENV MY_VAR whoami
ฉันต้องการให้ MY_VAR ได้รับค่า "root" หรืออะไรก็ตามที่ส่งคืน whoami
คำตอบ:
นอกเหนือจากคำตอบ DarkSideF
คุณควรทราบว่าแต่ละบรรทัด / คำสั่งใน Dockerfile ถูกรันในคอนเทนเนอร์อื่น
คุณสามารถทำสิ่งนี้:
RUN export bleah=$(hostname -f);echo $bleah;
สิ่งนี้ทำงานในคอนเทนเนอร์เดียว
$bleah
คือไม่สามารถใช้ได้ทุกที่นอกคำสั่งทำงานนี้ไม่ได้ในบรรทัดถัดไปใน dockerfile เดียวกันให้อยู่คนเดียวในภาพอื่นมันตามออก คุณลักษณะที่ขาดหายไปอย่างชัดเจนจากนักเทียบท่าที่นี่ดูเหมือนว่าการเขียนและอ่านจากไฟล์เป็นวิธีเดียวในการจัดเก็บตัวแปร (ไดนามิก) ในรูปภาพและส่งต่อระหว่างรูปภาพซึ่งดูเหมือนจะแฮ็กสุด ๆ
ฉันมีปัญหาเดียวกันและพบวิธีตั้งค่าตัวแปรสภาพแวดล้อมอันเป็นผลมาจากฟังก์ชันโดยใช้คำสั่ง RUN ใน dockerfile
ตัวอย่างเช่นฉันต้องตั้งค่า SECRET_KEY_BASE สำหรับแอพ Rails เพียงครั้งเดียวโดยไม่ต้องเปลี่ยนแปลงเหมือนตอนที่ฉันเรียกใช้:
docker run -e SECRET_KEY_BASE="$(openssl rand -hex 64)"
ฉันเขียนลงในสตริง Dockerfile แทนเช่น:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
และตัวแปร env ของฉันพร้อมใช้งานจากรูทแม้หลังจากเข้าสู่ระบบ bash หรืออาจจะ
RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'
จากนั้นตัวแปรที่มีอยู่ในคำสั่ง CMD และ ENTRYPOINT
นักเทียบท่าแคชเป็นเลเยอร์และเปลี่ยนเฉพาะเมื่อคุณเปลี่ยนสตริงก่อนหน้านั้น
คุณยังสามารถลองวิธีต่างๆในการตั้งค่าตัวแปรสภาพแวดล้อม
*.sh
ไฟล์ใด ๆ ที่อยู่ภายใน/etc/profile.d/
จะถูกใช้เพื่อเติมข้อมูลในสภาพแวดล้อม
ในขณะนี้สามารถใช้ผลลัพธ์คำสั่งRUN export
กับENV
ตัวแปรได้แต่ไม่สามารถกำหนดให้กับตัวแปรได้
ปัญหาที่ทราบ: https://github.com/docker/docker/issues/29110
คำตอบนี้ตอบสนองต่อการ@DarkSideF ,
วิธีการที่เขาเสนอมีดังต่อไปนี้ในDockerfile
:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
( เพิ่มการส่งออกใน/etc/bash.bashrc
)
เป็นสิ่งที่ดี แต่ตัวแปรสภาพแวดล้อมจะพร้อมใช้งานสำหรับกระบวนการ/bin/bash
เท่านั้นและหากคุณพยายามเรียกใช้แอปพลิเคชันนักเทียบท่าของคุณตัวอย่างเช่นแอปพลิเคชัน Node.js /etc/bash.bashrc
จะถูกละเว้นโดยสิ้นเชิงและแอปพลิเคชันของคุณจะไม่มีเงื่อนงำใด ๆSECRET_KEY_BASE
เมื่อพยายาม process.env.SECRET_KEY_BASE
ในการเข้าถึง
นั่นคือเหตุผลว่าทำไมENV
คีย์เวิร์ดจึงเป็นสิ่งที่ทุกคนพยายามใช้กับคำสั่งแบบไดนามิกเพราะทุกครั้งที่คุณเรียกใช้คอนเทนเนอร์หรือใช้exec
คำสั่ง Docker จะตรวจสอบENV
และไพพ์ทุกค่าในกระบวนการที่รันอยู่ (คล้ายกับ-e
)
วิธีแก้ปัญหาอย่างหนึ่งคือการใช้ Wrapper (ให้เครดิต@duglinในปัญหา github นี้ ) มีไฟล์ Wrapper (เช่นenvwrapper
) ในรูทโปรเจ็กต์ของคุณซึ่งประกอบด้วย:
#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*
จากนั้นในDockerfile
:
...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
นอกเหนือจากคำตอบของ @ DarkSideF แล้วหากคุณต้องการใช้ผลลัพธ์ของคำสั่งก่อนหน้านี้ซ้ำในDockerfile
ระหว่างกระบวนการสร้างคุณสามารถใช้วิธีแก้ปัญหาต่อไปนี้:
ตัวอย่างเช่น :
RUN echo "bla" > ./result
RUN echo $(cat ./result)
สำหรับสิ่งที่สะอาดกว่าคุณสามารถใช้ส่วนสำคัญต่อไปนี้ซึ่งมี CLI ขนาดเล็กที่เรียกว่าenvstore.py
:
RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)
หรือคุณสามารถใช้ไลบรารีpython-dotenvซึ่งมี CLI ที่คล้ายกัน
ไม่แน่ใจว่านี่คือสิ่งที่คุณกำลังมองหาหรือไม่ แต่เพื่อที่จะฉีด ENV vars หรือ ARGS ลงใน. Dockerfile ของคุณสร้างรูปแบบนี้ได้
ใน my_build.sh ของคุณ:
echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')
echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .
สำหรับการรับ ARG ในไฟล์. Dockerfile ของคุณข้อมูลโค้ดอาจมีลักษณะดังนี้:
FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}
อีกทางเลือกหนึ่งสำหรับการรับ ENV ใน. Dockerfile ของคุณตัวอย่างข้อมูลอาจมีลักษณะดังนี้:
FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}
แนวคิดคือคุณเรียกใช้เชลล์สคริปต์และเรียกว่า.