Bagaimana saya bisa menggunakan variabel di dalam Dockerfile CMD?


112

Di dalam Dockerfile saya:

ENV PROJECTNAME mytestwebsite
CMD ["django-admin", "startproject", "$PROJECTNAME"]

Kesalahan:

CommandError: '$PROJECTNAME' is not a valid project name

Apa solusi tercepat di sini? Apakah Docker memiliki rencana untuk "memperbaiki" atau memperkenalkan fungsionalitas ini di versi Docker yang lebih baru?

CATATAN: Jika saya menghapus baris CMD dari berkas Docker dan kemudian menjalankan wadah Docker, saya dapat menjalankan secara manual Django-admin startproject $ PROJECTNAME dari dalam wadah dan itu akan membuat proyek ...


1
Bagaimana dan kapan Anda mendefinisikan $PROJECTNAME?
Piotr Wittchen

Di awal Dockerfile saya menggunakan ENV. Juga saya lupa menyebutkan bahwa jika saya menghapus baris CMD dari Dockerfile dan kemudian menjalankan wadah, dari dalam wadah saya dapat menjalankan perintah ini dan itu akan membuat proyek (artinya variabel ENV valid).
david

Jenis variabel apa yang Anda maksud: variabel dockerfile atau variabel lingkungan (seperti dalam runtime sistem Anda)?
emix

Jawaban:


171

Saat Anda menggunakan daftar eksekusi, seperti di ...

CMD ["django-admin", "startproject", "$PROJECTNAME"]

... maka Docker akan menjalankan perintah yang diberikan secara langsung , tanpa melibatkan shell. Karena tidak ada shell yang terlibat, itu berarti:

  • Tidak ada ekspansi variabel
  • Tidak ada perluasan karakter pengganti
  • Tidak ada i / o redirection dengan >, <, |, dll
  • Tidak ada banyak perintah melalui command1; command2
  • Dan seterusnya.

Jika Anda ingin CMDmemperluas variabel, Anda perlu mengatur shell. Anda bisa melakukannya seperti ini:

CMD ["sh", "-c", "django-admin startproject $PROJECTNAME"]

Atau Anda dapat menggunakan string sederhana sebagai ganti daftar eksekusi, yang memberi Anda hasil yang sangat identik dengan contoh sebelumnya:

CMD django-admin startproject $PROJECTNAME

2
Beberapa bacaan lagi di pelacak masalah Docker: github.com/docker/docker/issues/5509
jannis

21

Jika Anda ingin menggunakan nilai pada waktu proses, tetapkan ENVnilai di Dockerfile. Jika Anda ingin menggunakannya pada waktu pembuatan, maka Anda harus menggunakan ARG.

Contoh:

ARG value
ENV envValue=$value
CMD ["sh", "-c", "java -jar ${envValue}.jar"]

Teruskan nilai dalam perintah build:

docker build -t tagName --build-arg value="jarName"

12

Katakanlah Anda ingin memulai proses java di dalam wadah:

Contoh kutipan Dockerfile:

ENV JAVA_OPTS -XX +UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm 
... 
ENTRYPOINT ["/sbin/tini", "--", "entrypoint.sh"] 
CMD ["java", "${JAVA_OPTS}", "-myargument=true"]

Contoh kutipan entrypoint.sh:

#!/bin/sh 
... 
echo "*** Startup $0 suceeded now starting service using eval to expand CMD variables ***"
exec su-exec mytechuser $(eval echo "$@")

0

Terinspirasi di atas, saya melakukan ini:

#snapshot by default. 1 is release.
ENV isTagAndRelease=0

CMD     echo is_tag: ${isTagAndRelease} && \
        if [ ${isTagAndRelease} -eq 1 ]; then echo "release build"; mvn -B release:clean release:prepare release:perform; fi && \
        if [ ${isTagAndRelease} -ne 1 ]; then echo "snapshot build"; mvn clean install; fi && \ 
       .....
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.