Dockerfile - đặt ENV thành kết quả của lệnh


Câu trả lời:


23

Như một phần bổ sung cho câu trả lời DarkSideF.

Bạn nên biết rằng mỗi dòng / lệnh trong Dockerfile được chạy trong một vùng chứa khác.

Bạn có thể làm điều gì đó như sau:

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

Điều này được chạy trong một vùng chứa duy nhất.


14
Chỉ cần làm rõ - $bleahkhông có sẵn ở bất cứ đâu bên ngoài lệnh RUN này, thậm chí không trên dòng tiếp theo trong dockerfile cùng, hãy để một mình trong một hình ảnh nó dựa tắt. Tính năng thực sự bị thiếu rõ ràng từ docker ở đây, có vẻ như ghi và đọc từ một tệp là cách duy nhất để thực sự lưu trữ các biến (động) trong hình ảnh và chuyển chúng giữa các hình ảnh, điều này có vẻ siêu hacky.
davnicwil ngày

17

Tôi đã gặp vấn đề tương tự và đã tìm thấy cách đặt biến môi trường là kết quả của hàm bằng cách sử dụng lệnh RUN trong dockerfile.

Ví dụ: tôi cần đặt SECRET_KEY_BASE cho ứng dụng Rails chỉ một lần mà không thay đổi như khi tôi chạy:

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

Thay vào đó, tôi ghi vào chuỗi Dockerfile như:

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

và biến env của tôi có sẵn từ gốc, ngay cả sau khi đăng nhập bash. hoặc có thể

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

thì biến nó có sẵn trong các lệnh CMD và ENTRYPOINT

Docker cache nó dưới dạng lớp và chỉ thay đổi nếu bạn thay đổi một số chuỗi trước nó.

Bạn cũng có thể thử các cách khác nhau để đặt biến môi trường.


/Etc/profile.d/docker_init.sh có còn là một thứ không? Câu trả lời này là đề cập duy nhất về nó mà tôi có thể tìm thấy với Google và nó không phù hợp với tôi. Có lẽ nó là một phần của công cụ thực thi Docker vào năm 2016 không còn hiện tại nữa?
SigmaX

1
@SigmaX Nó không phải là một thứ docker, nó là một thứ Linux hơn. Bất kỳ *.shtệp nào bên trong /etc/profile.d/được sử dụng để điền vào môi trường
Madacol


7

Câu trả lời này là phản hồi cho @DarkSideF ,

Phương pháp mà anh ấy đang đề xuất như sau, trong Dockerfile:

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

( thêm một bản xuất trong/etc/bash.bashrc )

Nó tốt nhưng biến môi trường sẽ chỉ có sẵn cho quá trình /bin/bashvà nếu bạn cố gắng chạy ứng dụng docker của mình, chẳng hạn như ứng dụng Node.js, /etc/bash.bashrcsẽ hoàn toàn bị bỏ qua và ứng dụng của bạn sẽ không có manh mối nào SECRET_KEY_BASEkhi thử. để truy cập process.env.SECRET_KEY_BASE.

Đó là lý do tại sao ENVtừ khóa là thứ mà mọi người đang cố gắng sử dụng với lệnh động bởi vì mỗi khi bạn chạy vùng chứa của mình hoặc sử dụng một execlệnh, Docker sẽ kiểm tra ENVvà chuyển mọi giá trị trong quá trình hiện đang chạy (tương tự như -e).

Một giải pháp là sử dụng trình bao bọc (tín dụng cho @duglin trong vấn đề github này ). Có một tệp trình bao bọc (ví dụ envwrapper) trong gốc dự án của bạn chứa:

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

và sau đó trong Dockerfile:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp

2

Như một phần bổ sung cho câu trả lời của @ DarkSideF, nếu bạn muốn sử dụng lại kết quả của một lệnh trước đó trong Dockerfile quá trình xây dựng của bạn, bạn có thể sử dụng cách giải quyết sau:

  1. chạy một lệnh, lưu trữ kết quả trong một tệp
  2. sử dụng thay thế lệnh để lấy kết quả trước đó từ tệp đó thành một lệnh khác

Ví dụ :

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

Đối với một cái gì đó rõ ràng hơn, bạn cũng có thể sử dụng ý chính sau đây cung cấp một CLI nhỏ được gọi là envstore.py:

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

Hoặc bạn có thể sử dụng thư viện python-dotenv có CLI tương tự.


2

Không chắc liệu đây có phải là thứ bạn đang tìm kiếm hay không, nhưng để đưa các vars ENV hoặc ARGS vào .Dockerfile, hãy xây dựng mẫu này hoạt động.

trong my_build.sh của bạn:

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 .

để nhận ARG trong tệp .Dockerfile của bạn, đoạn mã có thể trông giống như sau:

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

cách khác để nhận ENV trong tệp .Dockerfile của bạn, đoạn mã có thể trông giống như sau:

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

ý tưởng là bạn chạy tập lệnh shell và gọi tệp .Dockerfile với các args được chuyển vào dưới dạng tùy chọn trên bản dựng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.