ฉันจะใช้ตัวแปรสภาพแวดล้อม Docker ในอาร์เรย์ ENTRYPOINT ได้อย่างไร


111

หากฉันตั้งค่าตัวแปรสภาพแวดล้อมให้พูดENV ADDRESSEE=worldและฉันต้องการใช้ในสคริปต์จุดเริ่มต้นที่เชื่อมต่อกันเป็นสตริงคงที่เช่น:

ENTRYPOINT ["./greeting", "--message", "Hello, world!"]

ด้วยworldการที่คุณค่าของสิ่งแวดล้อมเปลี่ยนแปลงได้ฉันจะทำอย่างไร? ฉันลองใช้"Hello, $ADDRESSEE"แต่ดูเหมือนจะไม่ได้ผลเพราะต้องใช้$ADDRESSEEตัวอักษร.

คำตอบ:


221

คุณกำลังใช้รูปแบบผู้บริหารของ ENTRYPOINT ซึ่งแตกต่างจากรูปแบบเปลือกที่รูปแบบ execไม่เรียกเปลือกคำสั่ง ซึ่งหมายความว่าการประมวลผลเชลล์ตามปกติจะไม่เกิดขึ้น ตัวอย่างเช่นENTRYPOINT [ "echo", "$HOME" ]จะไม่ทำการแทนที่ตัวแปรใน $ HOME หากคุณต้องการการประมวลผลเปลือกแล้วทั้งใช้รูปแบบเปลือกENTRYPOINT [ "sh", "-c", "echo $HOME" ]หรือรันเปลือกโดยตรงตัวอย่างเช่น:
เมื่อใช้ฟอร์ม exec และเรียกใช้เชลล์โดยตรงเช่นในกรณีของรูปแบบเชลล์เป็นเชลล์ที่กำลังทำการขยายตัวแปรสภาพแวดล้อมไม่ใช่นักเทียบท่า (จากการอ้างอิง Dockerfile )

ในกรณีของคุณฉันจะใช้รูปแบบเชลล์

ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\!"

3
ENTRYPOINT java -jar /dockertest.jar -Djava.security.egd=file:/dev/./urandom -Dserver.port=$portในขณะที่ENV port=123. พอร์ต ENV ไม่ได้รับการแก้ไข ความคิดใด ๆ ทำไม?
xetra11

1
ในขณะที่ใช้งานได้ดูเหมือนว่าจะสร้างปัญหาใหม่ ๆ เช่นไม่รวมอาร์กิวเมนต์ที่ส่งผ่านไปยังจุดเข้าใช้งานนั้น ตัวอย่างเช่นคุณไม่สามารถเพิ่ม--attitude "shouting"อาร์กิวเมนต์ให้กับdocker runคำสั่งที่ควรส่งต่อไปยัง./greeting
Daniel F

5
ใช้ENTRYPOINT ./greeting --message "Hello, $ADDRESSEE\! $0 $@"ถ้าคุณต้องการส่งผ่านตัวแปรเพิ่มเติมไปยัง./greetingผ่านการdocker runเรียกใช้ (หรือเพื่อส่งผ่านCMDDockerfile)
Daniel F

3
โปรดทราบว่ารูปแบบเชลล์อาจทำให้สัญญาณไม่สามารถส่งผ่านไปยังกระบวนการได้ ( greetingในตัวอย่างของคุณ) hynek.me/articles/docker-signals
jbg

ฉันสามารถหาค่าของตัวแปรสภาพแวดล้อมในรูปแบบ exec ได้ไหมเช่น `[myexecutable.sh," $ variable "] โดย [" sh "," -c "," echo $ var "] แต่ไม่ ด้วยวิธีนี้
lazarus

14

ฉันพยายามแก้ไขด้วยคำตอบที่แนะนำและยังพบปัญหาบางอย่าง ...

นี่เป็นวิธีแก้ปัญหาของฉัน:

ARG APP_EXE="AppName.exe"
ENV _EXE=${APP_EXE}

# Build a shell script because the ENTRYPOINT command doesn't like using ENV
RUN echo "#!/bin/bash \n mono ${_EXE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

# Run the generated shell script.
ENTRYPOINT ["./entrypoint.sh"]

การกำหนดเป้าหมายปัญหาของคุณโดยเฉพาะ:

RUN echo "#!/bin/bash \n ./greeting --message ${ADDRESSEE}" > ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["./entrypoint.sh"]

ดูเหมือนว่าคำตอบของคุณจะไม่ได้ให้คำตอบที่สมบูรณ์สำหรับคำถามของ OP
user9405863

ฉันคิดว่าฉันไม่เข้าใจว่ามันไม่ได้ให้คำตอบสำหรับคำถามของ OP ... ฉันอัปเดตด้วยตัวอย่างเพื่อแก้ปัญหาโดยคำนึงถึงคำถามที่แน่นอน
Ben Kauffman

คุณพูดถึงคุณยังพบปัญหาบางอย่าง !!
user9405863

ถูกต้องนี่คือเหตุผลที่ฉันแนะนำโซลูชันใหม่ ... คำตอบ "ยอมรับ" ไม่ได้ผลสำหรับฉันดังนั้นฉันจึงสะท้อนไปที่เชลล์สคริปต์และนั่นก็ใช้ได้ผล
Ben Kauffman

2
ฉันสนใจที่จะได้ยินแนวทางของคุณแล้ว @ReverendTim;)
Ben Kauffman

7

หลังจากเจ็บปวดมากและความช่วยเหลือที่ดีจาก @vitr et al ด้านบนฉันตัดสินใจที่จะลอง

  • การทดแทนทุบตีมาตรฐาน
  • รูปแบบเปลือกของENTRYPOINT (เคล็ดลับดีๆจากด้านบน)

และได้ผล

ENV LISTEN_PORT=""

ENTRYPOINT java -cp "app:app/lib/*" hello.Application --server.port=${LISTEN_PORT:-80}

เช่น

docker run --rm -p 8080:8080 -d --env LISTEN_PORT=8080 my-image

และ

docker run --rm -p 8080:80 -d my-image

ทั้งสองตั้งค่าพอร์ตอย่างถูกต้องในคอนเทนเนอร์ของฉัน

อ้างอิง

ดูhttps://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html

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