Câu trả lời:
Bạn có thể truyền các biến môi trường cho các thùng chứa của bạn bằng -e
cờ.
Một ví dụ từ tập lệnh khởi động:
sudo docker run -d -t -i -e REDIS_NAMESPACE='staging' \
-e POSTGRES_ENV_POSTGRES_PASSWORD='foo' \
-e POSTGRES_ENV_POSTGRES_USER='bar' \
-e POSTGRES_ENV_DB_NAME='mysite_staging' \
-e POSTGRES_PORT_5432_TCP_ADDR='docker-db-1.hidden.us-east-1.rds.amazonaws.com' \
-e SITE_URL='staging.mysite.com' \
-p 80:80 \
--link redis:redis \
--name container_name dockerhub_id/image_name
Hoặc, nếu bạn không muốn có giá trị trên dòng lệnh nơi nó sẽ được hiển thị ps
, v.v., -e
có thể lấy giá trị từ môi trường hiện tại nếu bạn chỉ đưa ra mà không có =
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Nếu bạn có nhiều biến môi trường và đặc biệt nếu chúng có nghĩa là bí mật, bạn có thể sử dụng tệp env :
$ docker run --env-file ./env.list ubuntu bash
Cờ tệp --env lấy tên tệp làm đối số và hy vọng mỗi dòng có định dạng VAR = VAL, bắt chước đối số được truyền cho --env. Các dòng bình luận chỉ cần có tiền tố #
export PASSWORD=foo
Thay vào đó và biến sẽ được chuyển sang docker run
dưới dạng biến môi trường, làm cho docker run -e PASSWORD
công việc.
Bạn có thể chuyển bằng cách sử dụng -e
các tham số với docker run ..
lệnh như được đề cập ở đây và như được đề cập bởi @errata.
Tuy nhiên, nhược điểm có thể có của phương pháp này là thông tin đăng nhập của bạn sẽ được hiển thị trong danh sách quy trình, nơi bạn chạy nó.
Để làm cho nó an toàn hơn, bạn có thể viết thông tin quan trọng của bạn trong một tập tin cấu hình và làm docker run
với --env-file
như đã đề cập ở đây . Sau đó, bạn có thể kiểm soát quyền truy cập của tệp cấu hình đó để những người khác có quyền truy cập vào máy đó sẽ không thấy thông tin đăng nhập của bạn.
--env-file
, khi bạn sử dụng --env
các giá trị env của bạn sẽ được trích dẫn / thoát với ngữ nghĩa chuẩn của bất kỳ shell nào bạn đang sử dụng, nhưng khi sử dụng --env-file
các giá trị bạn sẽ nhận được bên trong container của bạn sẽ khác. Lệnh chạy docker chỉ đọc tệp, thực hiện phân tích cú pháp rất cơ bản và chuyển các giá trị qua vùng chứa, nó không tương đương với cách hành xử của trình bao của bạn. Chỉ cần một chú chó nhỏ để nhận biết nếu bạn đang chuyển đổi một loạt các --env
mục thành một --env-file
.
Nếu bạn đang sử dụng 'docker-compose' làm phương pháp để tăng (các) bộ chứa của mình, thì thực sự có một cách hữu ích để chuyển một biến môi trường được xác định trên máy chủ của bạn sang bộ chứa Docker.
Trong docker-compose.yml
tệp của bạn , giả sử bạn đang tạo ra một thùng chứa hapi-js cơ bản và mã trông như sau:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Giả sử máy chủ cục bộ mà dự án docker của bạn đang bật có biến môi trường có tên 'NODE_DB_CONNECT' mà bạn muốn chuyển đến vùng chứa hapi-js của mình và bạn muốn tên mới của nó là 'HAPI_DB_CONNECT'. Sau đó, trong docker-compose.yml
tệp, bạn sẽ chuyển biến môi trường cục bộ vào vùng chứa và đổi tên nó như sau:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Tôi hy vọng điều này sẽ giúp bạn tránh mã hóa cứng một chuỗi kết nối cơ sở dữ liệu trong bất kỳ tệp nào trong vùng chứa của bạn!
Sử dụng docker-compose
, bạn có thể kế thừa các biến env trong docker-compose.yml và sau đó bất kỳ (các) Dockerfile nào được gọi docker-compose
để xây dựng hình ảnh. Điều này rất hữu ích khi Dockerfile
RUN
lệnh sẽ thực thi các lệnh cụ thể cho môi trường.
(vỏ của bạn RAILS_ENV=development
đã tồn tại trong môi trường)
docker-compose.yml :
version: '3.1'
services:
my-service:
build:
#$RAILS_ENV is referencing the shell environment RAILS_ENV variable
#and passing it to the Dockerfile ARG RAILS_ENV
#the syntax below ensures that the RAILS_ENV arg will default to
#production if empty.
#note that is dockerfile: is not specified it assumes file name: Dockerfile
context: .
args:
- RAILS_ENV=${RAILS_ENV:-production}
environment:
- RAILS_ENV=${RAILS_ENV:-production}
Dockerfile :
FROM ruby:2.3.4
#give ARG RAILS_ENV a default value = production
ARG RAILS_ENV=production
#assign the $RAILS_ENV arg to the RAILS_ENV ENV so that it can be accessed
#by the subsequent RUN call within the container
ENV RAILS_ENV $RAILS_ENV
#the subsequent RUN call accesses the RAILS_ENV ENV variable within the container
RUN if [ "$RAILS_ENV" = "production" ] ; then echo "production env"; else echo "non-production env: $RAILS_ENV"; fi
Bằng cách này, tôi không cần chỉ định các biến môi trường trong tệp hoặc docker-compose
build
/ up
lệnh:
docker-compose build
docker-compose up
Sử dụng -e
hoặc --env value để đặt các biến môi trường (mặc định []).
Một ví dụ từ tập lệnh khởi động:
docker run -e myhost='localhost' -it busybox sh
Nếu bạn muốn sử dụng nhiều môi trường từ dòng lệnh thì trước mỗi biến môi trường đều sử dụng -e
cờ.
Thí dụ:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Lưu ý: Đảm bảo đặt tên thùng chứa sau biến môi trường, không phải trước đó.
Nếu bạn cần thiết lập nhiều biến, hãy sử dụng --env-file
cờ
Ví dụ,
$ docker run --env-file ./my_env ubuntu bash
Đối với bất kỳ trợ giúp nào khác, hãy xem trợ giúp Docker:
$ docker run --help
Tài liệu chính thức: https://docs.docker.com/compose/envir-variabled/
ubuntu bash
? Nó có áp dụng cho hình ảnh được tạo bằng ubfox làm hình ảnh cơ sở hoặc cho mọi hình ảnh không?
-e
đối số từ lâu! Tôi thậm chí không thể bắt đầu hiểu lý do tại sao họ làm điều này cần thiết ...
Có một cách hay để làm thế nào để chuyển các biến môi trường của máy chủ sang bộ chứa docker:
env > env_file && docker run --env-file env_file image_name
Sử dụng kỹ thuật này rất cẩn thận, vì
env > env_file
sẽ đổ TẤT CẢ các biến ENV của máy chủ sangenv_file
và làm cho chúng có thể truy cập được trong vùng chứa đang chạy.
Đối với Amazon AWS ECS / ECR, bạn nên quản lý các biến môi trường của mình ( đặc biệt là các bí mật ) thông qua nhóm S3 riêng. Xem bài đăng trên blog Cách quản lý bí mật cho các ứng dụng dựa trên dịch vụ container của Amazon EC2 bằng cách sử dụng Amazon S3 và Docker .
Nếu bạn có các biến môi trường trong một env.sh
cục bộ và muốn thiết lập nó khi container bắt đầu, bạn có thể thử
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Lệnh này sẽ khởi động container với shell bash (tôi muốn bash shell vì source
là lệnh bash), lấy env.sh
tệp (đặt các biến môi trường) và thực thi tệp jar.
Các env.sh
ngoại hình như thế này,
#!/bin/bash
export FOO="BAR"
export DB_NAME="DATABASE_NAME"
Tôi đã thêm printenv
lệnh chỉ để kiểm tra rằng lệnh nguồn thực sự hoạt động. Bạn có thể nên loại bỏ nó khi bạn xác nhận lệnh nguồn hoạt động tốt hoặc các biến môi trường sẽ xuất hiện trong nhật ký docker của bạn.
--env-file
arg cho docker run
lệnh. Ví dụ: nếu bạn đang triển khai một ứng dụng bằng công cụ ứng dụng Google và ứng dụng chạy bên trong bộ chứa cần các biến môi trường được đặt bên trong bộ chứa docker, bạn không có cách tiếp cận trực tiếp để đặt các biến môi trường vì bạn không có quyền kiểm soát docker run
lệnh . Trong trường hợp như vậy, bạn có thể có một tập lệnh giải mã các biến env bằng cách sử dụng say, KMS và thêm chúng vào tập lệnh env.sh
có thể có nguồn gốc để đặt các biến env.
.
(dấu chấm) có sẵn thông thường sh
thay vì source
. ( source
giống như .
)
Sử dụng jq để chuyển đổi env thành JSON:
env_as_json=`jq -c -n env`
docker run -e HOST_ENV="$env_as_json" <image>
cái này yêu cầu jq phiên bản 1.6 trở lên
điều này làm cho máy chủ env là json, về cơ bản là như vậy trong Dockerfile:
ENV HOST_ENV (all env from the host as json)
docker run -e HOST_ENV="$env_as_json" <image>
? Trong trường hợp của tôi, Docker dường như không giải quyết được các biến hoặc các chuỗi con ( ${}
hoặc $()
) khi được chuyển như docker args. Ví dụ: A=123 docker run --rm -it -e HE="$A" ubuntu
sau đó bên trong container đó: root@947c89c79397:/# echo $HE root@947c89c79397:/#
.... HE
Biến không tạo ra nó.
chúng tôi cũng có thể lưu trữ biến môi trường máy bằng cờ -e và $:
docker run -it -e MG_HOST=$MG_HOST -e MG_USER=$MG_USER -e MG_PASS=$MG_PASS -e MG_AUTH=$MG_AUTH -e MG_DB=$MG_DB -t image_tag_name_and_version
Bằng cách sử dụng phương thức này, hãy đặt biến env tự động với tên đã cho của bạn trong trường hợp của tôi (MG_HOST, MG_USER)
Nếu bạn đang sử dụng python, bạn có thể truy cập các biến envment bên trong docker bằng cách
import os
host,username,password,auth,database=os.environ.get('MG_HOST'),os.environ.get('MG_USER'),os.environ.get('MG_PASS'),os.environ.get('MG_AUTH'),os.environ.get('MG_DB')
docker run --rm -it --env-file <(bash -c 'env | grep <your env data>')
Là một cách để grep dữ liệu được lưu trữ trong a .env
và chuyển chúng đến Docker, mà không có gì được lưu trữ không an toàn (vì vậy bạn không thể chỉ nhìn docker history
và lấy khóa.
Giả sử bạn có rất nhiều thứ AWS .env
giống như vậy:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
đang chạy docker với `` `docker run --rm -it --env-file <(bash -c 'env | grep AWS_') sẽ lấy tất cả và chuyển nó an toàn để có thể truy cập từ trong container.