Dockerfile - setel ENV ke hasil perintah

90

Apakah mungkin untuk menyetel variabel ENV buruh pelabuhan ke hasil perintah? Suka:

ENV MY_VAR whoami

saya ingin MY_VAR mendapatkan nilai "root" atau apa pun yang dikembalikan whoami

Sultanen
sumber

Jawaban:

23

Sebagai tambahan jawaban DarkSideF.

Anda harus menyadari bahwa setiap baris / perintah di Dockerfile dijalankan di penampung lain.

Anda bisa melakukan sesuatu seperti ini:

RUN export bleah=$(hostname -f);echo $bleah;

Ini dijalankan dalam satu wadah.

Dimitrie Mititelu
sumber
14
Hanya untuk memperjelas - $bleahadalah tidak tersedia di mana saja di luar perintah RUN ini, bahkan pada baris berikutnya di dockerfile yang sama, apalagi di gambar lain itu didasarkan dari. Fitur yang benar-benar hilang dari buruh pelabuhan di sini, sepertinya menulis ke dan membaca dari file adalah satu-satunya cara untuk benar-benar menyimpan variabel (dinamis) dalam gambar dan meneruskannya di antara gambar, yang tampaknya sangat hacky.
davnicwil
17

Saya memiliki masalah yang sama dan menemukan cara untuk mengatur variabel lingkungan sebagai hasil dari fungsi dengan menggunakan perintah RUN di dockerfile.

Misalnya saya perlu mengatur SECRET_KEY_BASE untuk aplikasi Rails sekali saja tanpa mengubah seperti ketika saya menjalankan:

docker run  -e SECRET_KEY_BASE="$(openssl rand -hex 64)"

Sebagai gantinya saya menulis ke string Dockerfile seperti:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

dan variabel env saya tersedia dari root, bahkan setelah login bash. atau mungkin

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'

maka variabel itu tersedia dalam perintah CMD dan ENTRYPOINT

Docker men-cache-nya sebagai lapisan dan hanya berubah jika Anda mengubah beberapa string sebelumnya.

Anda juga dapat mencoba berbagai cara untuk menyetel variabel lingkungan.

DarkSideF
sumber
Apakah /etc/profile.d/docker_init.sh masih ada? Jawaban ini adalah satu-satunya penyebutan yang dapat saya temukan dengan Google, dan tidak berhasil untuk saya. Apakah mungkin itu bagian dari mesin eksekusi Docker pada tahun 2016 yang sudah tidak berlaku lagi?
SigmaX
1
@SigmaX Ini bukan hal buruh pelabuhan, ini lebih merupakan hal Linux . Setiap *.shdalam file /etc/profile.d/digunakan untuk mengisi lingkungan
Madacol
7

Jawaban ini adalah respon dari @DarkSideF ,

Metode yang dia usulkan adalah sebagai berikut, dalam Dockerfile:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'

( menambahkan ekspor di/etc/bash.bashrc )

Ini bagus tetapi variabel lingkungan hanya akan tersedia untuk proses tersebut /bin/bash, dan jika Anda mencoba menjalankan aplikasi buruh pelabuhan misalnya aplikasi Node.js, /etc/bash.bashrcakan sepenuhnya diabaikan dan aplikasi Anda tidak akan memiliki petunjuk apa SECRET_KEY_BASEpun saat mencoba untuk mengakses process.env.SECRET_KEY_BASE.

Itulah alasan mengapa ENVkata kunci adalah apa yang semua orang coba gunakan dengan perintah dinamis karena setiap kali Anda menjalankan penampung atau menggunakan execperintah, Docker akan memeriksa ENVdan menyalurkan setiap nilai dalam proses yang saat ini dijalankan (mirip dengan -e).

Salah satu solusinya adalah dengan menggunakan pembungkus (kreditkan ke @duglin dalam masalah github ini ). Memiliki file pembungkus (misalnya envwrapper) di root proyek Anda yang berisi:

#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*

dan kemudian di Dockerfile:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
vdegenne.dll
sumber
2

Sebagai tambahan untuk jawaban @ DarkSideF, jika Anda ingin menggunakan kembali hasil dari perintah sebelumnya Dockerfile selama dalam proses build , Anda dapat menggunakan solusi berikut:

  1. jalankan perintah, simpan hasilnya dalam sebuah file
  2. gunakan substitusi perintah untuk mendapatkan hasil sebelumnya dari file itu ke perintah lain

Sebagai contoh :

RUN echo "bla" > ./result
RUN echo $(cat ./result)

Untuk sesuatu yang lebih bersih, Anda juga dapat menggunakan inti berikut yang menyediakan CLI kecil yang disebut envstore.py:

RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)

Atau Anda dapat menggunakan pustaka python-dotenv yang memiliki CLI serupa.

sebpiq
sumber
2

Tidak yakin apakah ini yang Anda cari, tetapi untuk menyuntikkan ENV vars atau ARGS ke .Dockerfile Anda membangun pola ini bekerja.

di my_build.sh Anda:

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 .

untuk mendapatkan ARG di .Dockerfile Anda, cuplikannya mungkin terlihat seperti ini:

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

sebagai alternatif untuk mendapatkan ENV di .Dockerfile Anda, cuplikannya mungkin terlihat seperti ini:

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

Idenya adalah Anda menjalankan skrip shell dan memanggil .Dockerfile dengan argumen yang diteruskan sebagai opsi pada build.

kat
sumber