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 ...

David
sumber
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
larsks
sumber
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"
rex roy
sumber
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 "$@")
Flavio Aiello
sumber
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 && \ 
       .....
csomakk.dll
sumber