Nhận giá trị biến môi trường trong Dockerfile


254

Tôi đang xây dựng một container cho một ứng dụng ruby. Cấu hình ứng dụng của tôi được chứa trong các biến môi trường (được tải bên trong ứng dụng bằng dotenv ).

Một trong những biến cấu hình đó là ip công khai của ứng dụng, được sử dụng nội bộ để tạo liên kết. Tôi cần thêm một mục dnsmasq trỏ ip này vào 127.0.0.1 bên trong container, để nó có thể tìm nạp các liên kết của ứng dụng như thể nó không được chứa.

Do đó, tôi đang cố gắng thiết lập một ENVDockerfile của mình để chuyển một biến môi trường cho vùng chứa.

Tôi đã thử một vài điều.

ENV REQUEST_DOMAIN $REQUEST_DOMAIN
ENV REQUEST_DOMAIN `REQUEST_DOMAIN`

Mọi thứ đều vượt qua chuỗi "REQUEST_DOMAIN" thay vì giá trị của biến môi trường. Có cách nào để chuyển các giá trị biến môi trường từ máy chủ sang container không?

Câu trả lời:


392

Bạn nên sử dụng các ARGchỉ thị trong Dockerfile của bạn mà có nghĩa là cho mục đích này.

Các ARGhướng dẫn định nghĩa một biến mà người dùng có thể vượt qua ít build-thời gian để các nhà xây dựng với Docker build lệnh bằng cách sử dụng --build-arg <varname>=<value>lá cờ.

Vì vậy, Dockerfile của bạn sẽ có dòng này:

ARG request_domain

hoặc nếu bạn thích một giá trị mặc định:

ARG request_domain=127.0.0.1

Bây giờ bạn có thể tham chiếu biến này trong Dockerfile của bạn:

ENV request_domain=$request_domain

sau đó bạn sẽ xây dựng container của bạn như vậy:

$ docker build --build-arg request_domain=mydomain Dockerfile


Lưu ý 1: Hình ảnh của bạn sẽ không được xây dựng nếu bạn đã tham chiếu một ARGtrong Dockerfile của mình nhưng loại trừ nó trong --build-arg.

Lưu ý 2: Nếu người dùng chỉ định đối số bản dựng không được xác định trong Dockerfile, bản dựng sẽ đưa ra cảnh báo:

[Cảnh báo] Một hoặc nhiều arg-build [foo] không được sử dụng.


12
ARG có sẵn từ docker v1.9 trở đi.
Synesso

Điều này có được hỗ trợ để được xây dựng từ xa trên docker repo không?
James Lin

4
Your image will not build if you have referenced an ARG in your Dockerfile but excluded it in --build-argbạn sai rồi. Bạn có thể xây dựng hình ảnh với các tham chiếu ngay cả khi không có --build-arg. Ngoài ra, bạn có thể đặt giá trị mặc định cho bản dựng arg.
ALex_hha

1
Mục đích của dòng ENV là gì? Đối với tôi --build-arg + ARG là đủ.
Phil

3
ARG định nghĩa một biến được sử dụng bên trong dockerfile trong các lệnh tiếp theo. ENV định nghĩa một biến môi trường được chuyển đến vùng chứa.
Herm

56

Vì vậy, bạn có thể làm: cat Dockerfile | envsubst | docker build -t my-target -

Sau đó, có một Dockerfile với một cái gì đó như:

ENV MY_ENV_VAR $MY_ENV_VAR

Tôi đoán có thể có một vấn đề với một số nhân vật đặc biệt, nhưng điều này ít nhất hoạt động với hầu hết các trường hợp.


13
Điều này dường như không hoạt động nếu bạn cần THÊM các tệp từ thư mục chứa Dockerfile.
Tom Hennen

2
Giải pháp rất hay! Trên máy Mac, bạn có thể nhận được envsubstmột phần của brew install gettext. Nhưng do các xung đột có thể xảy ra với hệ thống xây dựng BSD, nó chỉ "keg" và không có symlnks nào được thực hiện. Tuy nhiên, sẽ an toàn ln -s /usr/local/Cellar/gettext/*/bin/envsubst /usr/local/bin/khi thêm một lệnh đó vào PATH của bạn. (Đó thực sự là những điều đáng lo ngại.) Hoặc bạn có thể sử dụng nó ở /usr/local/Cellar/gettext/*/bin/envsubstvị trí của nó
Bruno Bronosky 11/03/2015

1
Để làm rõ nhận xét của @ TomHennen docker build -, cụ thể đường ống Dockerfile là, điều gì không hoạt động khi bạn tham chiếu các đường dẫn tương đối từ Dockerfile của bạn, bất kể thay thế env var.
superEb

4
Re @ bình luận TomHennen, nếu bạn làm muốn sử dụng lệnh bối cảnh phụ thuộc như COPY trong Dockerfile của bạn, bạn luôn có thể chuyển hướng đầu ra của envsubst vào một tập tin tạm thời và sau đó thức ăn đó vào docker buildthay thế. Ví dụ : cat Dockerfile | envsubst > DockerfileWithEnvVars, sau đó docker build -t my-target -f DockerfileWithEnvVars ., sau đórm DockerfileWithEnvVars
sủa

Hoặc bạn có thể sử dụng miếng bọt biển từ gói envsubst < Dockerfile | sponge Dockerfile
moreutils

19

Một cách khác để sử dụng envsubstmà không làm mất khả năng sử dụng các lệnh như COPYhoặc ADDkhông sử dụng các tệp trung gian sẽ là sử dụng Thay thế quy trình của Bash :

docker build -f <(envsubst < Dockerfile) -t my-target .

3
thật không may, điều đó dường như không hoạt động (Docker 17,09), tôi gặp lỗiunable to prepare context: the Dockerfile (/dev/fd/63) must be within the build context
Alexander Klimetschek

11

Tải các biến môi trường từ một tệp bạn tạo trong thời gian chạy.

export MYVAR="my_var_outside"
cat > build/env.sh <<EOF
MYVAR=${MYVAR}
EOF

... sau đó trong Dockerfile

ADD build /build
RUN /build/test.sh

nơi test.sh tải MYVAR từ env.sh

#!/bin/bash
. /build/env.sh
echo $MYVAR > /tmp/testfile

4

Nếu bạn chỉ muốn tìm và thay thế tất cả các biến môi trường ($ exampleEnvVar) trong Dockerfile thì hãy xây dựng nó, nó sẽ hoạt động:

envsubst < /path/to/Dockerfile | docker build -t myDockerImage . -f -


Câu trả lời tốt nhất ở đây, và dựa vào đó, đã có thể làm: envsubst < ./Dockerfile | docker build -squash -t ${DOCKIMG}:${VERSION} . -f -nơi FROMdòng đang sử dụng biến môi trường.
mikequentel

-6

thêm -ekhóa để chuyển các biến môi trường vào container. thí dụ:

$ MYSQLHOSTIP=$(sudo docker inspect -format="{{ .NetworkSettings.IPAddress }}" $MYSQL_CONRAINER_ID)
$ sudo docker run -e DBIP=$MYSQLHOSTIP -i -t myimage /bin/bash

root@87f235949a13:/# echo $DBIP
172.17.0.2

6
Damien đang tìm cách xây dựng một hình ảnh. -e làm việc với lệnh chạy thay thế.
Andres Restrepo
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.