2015-05-27 18 views

Trả lời

466

Bạn có thể chuyển biến môi trường cho các vùng chứa của mình với cờ -e.

Một ví dụ từ một kịch bản 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 mà nó sẽ được hiển thị bằng ps, vv -e có thể kéo trong giá trị từ môi trường hiện tại nếu bạn chỉ cần cung cấp cho nó mà không có sự =:

sudo PASSWORD='foo' docker run [...] -e PASSWORD [...] 

Nếu bạn có nhiều biến môi trường và đặc biệt là nếu họ đang có nghĩa là phải bí mật, bạn có thể use an env-file:

$ docker run --env-file ./env.list ubuntu bash 

Các --env-file cờ có một tên tập tin như một cuộc tranh cãi và dự kiến ​​mỗi dòng được trong VAR = định dạng VAL, bắt chước đối số truyền cho --env. dòng chú thích chỉ cần được bắt đầu bằng #

+0

Có cách nào dễ dàng hơn để làm điều này? Thật là khó chịu khi phải tạo lại container với các biến khác nhau mỗi lần. Có thể lưu trữ nó trong một tập tin? –

+10

Tôi lưu trữ các lệnh chạy docker trong các kịch bản shell, (./start_staging.sh etc ..) sau đó thực hiện chúng từ xa bằng Ansible. – errata

+0

Tôi gặp sự cố khi tải phiên bản thứ hai để hoạt động; Tôi đặt PASSWORD = foo trong môi trường, sau đó truyền --env PASSWORD, và chỉ từ "PASSWORD" xuất hiện trong tệp config.json của vùng chứa; mọi biến môi trường khác đều có khóa và giá trị. Tôi đang sử dụng Docker 1.12.1. –

55

Bạn có thể vượt qua bằng -e thông số với docker run .. lệnh như đã đề cập here và như đã đề 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ó.
Để đảm bảo an toàn hơn, bạn có thể ghi thông tin đăng nhập của mình vào tệp cấu hình và thực hiện docker run với --env-file như đã đề cập here. 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.

+2

Tôi đã thêm một cách khác để giải quyết vấn đề này với câu trả lời của @ errata. – Bryan

+8

Hãy cẩn thận với '--env-file', khi bạn sử dụng' --env' 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 vùng chứa sẽ khác nhau. Lệnh docker chạy chỉ đọc tệp, phân tích cú pháp rất cơ bản và chuyển các giá trị thông qua vào vùng chứa, nó không tương đương với cách mà shell của bạn hoạt động. Chỉ cần một dấu hiệu nhỏ để nhận biết nếu bạn đang chuyển đổi một loạt các mục '--env' thành' --env-file'. – Shorn

+1

Để giải thích về câu trả lời Shorn, khi sử dụng tệp env, tôi phải đặt giá trị của biến môi trường rất dài trên một dòng vì dường như không có cách nào để đặt ngắt dòng trong đó hoặc chia nhỏ thành nhiều dòng như: $ MY_VAR = stuff $ MY_VAR = $ MY_VAR –

32

Nếu bạn đang sử dụng 'docker-compose' làm phương pháp xoay vòng (các) vùng chứa của bạn, 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 vùng chứa Docker.

Trong file docker-compose.yml của bạn, hãy nói rằng bạn đang quay lên một container HAPI-js cơ bản và mã trông giống như:

hapi_server: 
    container_name: hapi_server 
    image: node_image 
    expose: 
    - "3000" 

Hãy nói rằng các máy chủ địa phương mà dự án Docker của bạn nằm trên có một biến môi trường có tên 'NODE_DB_CONNECT' mà bạn muốn chuyển tới 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 tập tin docker-compose.yml, bạn sẽ vượt qua biến môi trường địa phương để các thùng chứa và đổi tên nó như vậy:

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 được hard-coding một cơ sở dữ liệu kết nối chuỗi trong bất kỳ tập tin trong thùng chứa của bạn!

9

Sử dụng giá trị -e hoặc --env để đặt biến môi trường (mặc định []).

Một ví dụ từ một kịch bản 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 sau đó trước mỗi biến môi trường sử dụng -e cờ.

Ví dụ:

sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh 

Lưu ý: Đảm bảo đặt tên chứa sau các biến môi trường, không phải trước đó.

Nếu bạn cần phải thiết lập nhiều biến, sử dụng --env-file cờ

Ví dụ,

$ docker run --env-file ./my_env ubuntu bash 

Đối với bất kỳ sự giúp đỡ khác, nhìn vào sự giúp đỡ Docker:

$ docker run --help 

Tài liệu chính thức: https://docs.docker.com/compose/environment-variables/

5

Sử dụng docker-compose, ví dụ bên dưới cho thấy cách bạn có thể kế thừa các biến shell env trong cả docker-compose.yml và lần lượt bất kỳ (các) Dockerfile nào được gọi là docker-compose để tạo hình ảnh. Tôi đã thấy điều này hữu ích nếu nói trong lệnh DockerfileRUN tôi cần thực thi các lệnh cụ thể cho môi trường.

(shell của bạn có 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 biến môi trường trong các tệp hoặc docker-composebuild/up lệnh:

docker-compose build 
docker-compose up 
Các vấn đề liên quan