AJc*_*dez 733 environment-variables docker dockerfile
我是Docker的新手,目前还不清楚如何从容器访问外部数据库.是连接字符串中硬编码的最佳方法吗?
# Dockerfile
ENV DATABASE_URL amazon:rds/connection?string
Run Code Online (Sandbox Code Playgroud)
err*_*ata 1115
您可以使用-e
标志将环境变量传递给容器.
启动脚本的示例:
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
Run Code Online (Sandbox Code Playgroud)
或者,如果您不希望在命令行上显示值ps
,等等,-e
可以从当前环境中获取值,如果您只是在没有=
:
sudo PASSWORD='foo' docker run [...] -e PASSWORD [...]
Run Code Online (Sandbox Code Playgroud)
如果您有许多环境变量,特别是如果它们是秘密的,您可以使用env文件:
$ docker run --env-file ./env.list ubuntu bash
Run Code Online (Sandbox Code Playgroud)
--env-file标志将文件名作为参数,并期望每一行都是VAR = VAL格式,模仿传递给--env的参数.注释行只需要以#为前缀
Sab*_*bin 88
您可以使用此处提到的命令传递-e
参数,docker run ..
如@errata所述.
但是,此方法的可能缺点是您的凭据将显示在运行它的进程列表中.
为了使它更安全,你可能会写你的凭据在配置文件中,并做有提到这里.然后,您可以控制该配置文件的访问权限,以便其他有权访问该计算机的人不会看到您的凭据.docker run
--env-file
Mar*_*dor 49
如果您使用'docker-compose'作为旋转容器的方法,实际上有一种方法可以将服务器上定义的环境变量传递给Docker容器.
在你的docker-compose.yml
文件中,假设你正在启动一个基本的hapi-js容器,代码如下:
hapi_server:
container_name: hapi_server
image: node_image
expose:
- "3000"
Run Code Online (Sandbox Code Playgroud)
假设您的docker项目所在的本地服务器有一个名为'NODE_DB_CONNECT'的环境变量,您希望将其传递给hapi-js容器,并且您希望其新名称为'HAPI_DB_CONNECT'.然后在docker-compose.yml
文件中,您将本地环境变量传递给容器并重命名,如下所示:
hapi_server:
container_name: hapi_server
image: node_image
environment:
- HAPI_DB_CONNECT=${NODE_DB_CONNECT}
expose:
- "3000"
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助您避免在容器中的任何文件中对数据库连接字符串进行硬编码!
Mob*_*san 38
我们还可以使用-e标志和$来使用主机环境变量:
在运行以下命令之前,我们需要导出(即设置)本地环境变量。
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
Run Code Online (Sandbox Code Playgroud)
通过使用此方法,您可以使用您的给定名称自动设置环境变量。就我而言,是 MG_HOST 和 MG_USER。
如果您使用 Python,则可以通过以下方式访问 Docker 内的这些环境变量:
import os
host = os.environ.get('MG_HOST')
username = os.environ.get('MG_USER')
password = os.environ.get('MG_PASS')
auth = os.environ.get('MG_AUTH')
database = os.environ.get('MG_DB')
Run Code Online (Sandbox Code Playgroud)
Vis*_*hra 25
使用-e
或--env值设置环境变量(默认[]).
启动脚本的示例:
docker run -e myhost='localhost' -it busybox sh
Run Code Online (Sandbox Code Playgroud)
如果要从命令行使用多个环境,则在每个环境变量之前使用该-e
标志.
例:
sudo docker run -d -t -i -e NAMESPACE='staging' -e PASSWORD='foo' busybox sh
Run Code Online (Sandbox Code Playgroud)
注意:确保将容器名称放在环境变量之后,而不是之前.
如果需要设置许多变量,请使用--env-file
标志
例如,
$ docker run --env-file ./my_env ubuntu bash
Run Code Online (Sandbox Code Playgroud)
如需其他帮助,请查看Docker帮助:
$ docker run --help
Run Code Online (Sandbox Code Playgroud)
官方文档:https: //docs.docker.com/compose/environment-variables/
jos*_*eir 25
使用docker-compose
,下面的示例显示了如何在docker-compose.yml中继承shell env变量,以及依次调用docker-compose
构建映像的任何Dockerfile .我发现这很有用,如果在Dockerfile
RUN
命令中我需要执行特定于环境的命令.
(你的shell RAILS_ENV=development
已经存在于环境中)
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}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这样我就不需要在files或docker-compose
build
/ up
commands中指定环境变量:
docker-compose build
docker-compose up
Run Code Online (Sandbox Code Playgroud)
Ale*_*x T 10
有一个不错的技巧,如何将主机环境变量通过管道传递给Docker容器:
env > env_file && docker run --env-file env_file image_name
Run Code Online (Sandbox Code Playgroud)
请非常小心地使用此技术,因为这
env > env_file
会将所有主机ENV变量都转储到env_file
并使它们在运行的容器中可访问。
小智 8
docker run --rm -it --env-file <(bash -c 'env | grep <your env data>')
是一种 grep 存储在 a 中的数据并将.env
它们传递给 Docker 的方法,而不会不安全地存储任何内容(因此您不能只查看docker history
并获取密钥。
假设您有大量 AWS 内容,如下所示.env
:
AWS_ACCESS_KEY: xxxxxxx
AWS_SECRET: xxxxxx
AWS_REGION: xxxxxx
Run Code Online (Sandbox Code Playgroud)
运行 docker withdocker run --rm -it --env-file <(bash -c 'env | grep AWS_')
将抓取所有内容并安全地传递它以便可以从容器内访问。
有多种方法可以将环境变量传递到容器,包括使用docker-compose(如果可能的话最好的选择)。
我建议使用env 文件以便于组织和维护。
示例(docker-compose
CLI)
docker-compose -f docker-compose.yml --env-file ./.env up
Run Code Online (Sandbox Code Playgroud)
示例(docker
CLI)
docker-compose -f docker-compose.yml --env-file ./.env up
Run Code Online (Sandbox Code Playgroud)
重要提示: CLI对于环境变量(见下文)docker
有一些限制。
奇怪的是,该docker run
子命令不接受格式为有效 BASH(“Shell”)脚本的env 文件,因此它将周围的引号和双引号视为环境变量值的一部分,因此容器将获取 (在 env 文件中,对于例子)...
docker run -it --name "some-ctn-name" --env-file ./.env "some-img-name:Dockerfile"
Run Code Online (Sandbox Code Playgroud)
...作为"some value a"
和不some value a
。除此之外,我们在其他上下文(包括 BASH 本身)中使用相同的env 文件时会遇到问题。
这是非常奇怪的行为,因为 .env 文件是常规的BASH(“Shell”)脚本。
然而,BASH(“Shell”)为我们提供了强大的功能,因此让我们在解决方案中利用它来发挥我们的优势。
我的解决方案涉及一个Dockerfile、一个env 文件、一个BASH 脚本文件和特殊方式的run
子命令 ( )。docker run
该策略包括使用子run
命令中设置的另一个环境变量注入环境变量,并使用容器本身来设置这些变量。
例子
FROM python:3.10-slim-buster
WORKDIR /some-name
COPY . /some-name/
RUN apt-get -y update \
&& apt-get -y upgrade \
[...]
ENTRYPOINT bash entrypoint.bash
Run Code Online (Sandbox Code Playgroud)
例子
SOME_ENV_VAR_A="some value a"
Run Code Online (Sandbox Code Playgroud)
例子
FROM python:3.10-slim-buster
WORKDIR /some-name
COPY . /some-name/
RUN apt-get -y update \
&& apt-get -y upgrade \
[...]
ENTRYPOINT bash entrypoint.bash
Run Code Online (Sandbox Code Playgroud)
例子
#!/bin/bash
# Some description a
SOME_ENV_VAR_A="some value a"
# Some description b
SOME_ENV_VAR_B="some value b"
# Some description c
SOME_ENV_VAR_C="some value c"
[...]
Run Code Online (Sandbox Code Playgroud)
docker -compose不存在这个问题,因为它使用 YAML。YAML 不将引号和双引号视为环境变量值的一部分,而子命令则没有这样做docker run
。
谢了!
如果你本地有环境变量env.sh
并且想在容器启动时设置它,你可以尝试
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Run Code Online (Sandbox Code Playgroud)
该命令将使用 bash shell 启动容器(我想要一个 bash shell,因为它source
是 bash 命令),获取env.sh
文件(设置环境变量)并执行 jar 文件。
看起来env.sh
像这样,
COPY env.sh /env.sh
COPY <filename>.jar /<filename>.jar
ENTRYPOINT ["/bin/bash" , "-c", "source /env.sh && printenv && java -jar /<filename>.jar"]
Run Code Online (Sandbox Code Playgroud)
我添加该printenv
命令只是为了测试实际的源命令是否有效。当您确认 source 命令正常工作或者环境变量将出现在 docker 日志中时,您可能应该将其删除。
另一种方法是使用 的权力/usr/bin/env
:
docker run ubuntu env DEBUG=1 path/to/script.sh
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我将 --env-file 放在命令的末尾
docker run -it --rm -p 8080:80 imagename --env-file ./env.list
Run Code Online (Sandbox Code Playgroud)
使固定
docker run --env-file ./env.list -it --rm -p 8080:80 imagename
Run Code Online (Sandbox Code Playgroud)
为了通过 docker-compose 传递多个环境变量,环境文件也可以在 docker-compose 文件中使用。
web:
env_file:
- web-variables.env
Run Code Online (Sandbox Code Playgroud)
https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option
对于 Amazon AWS ECS/ECR,您应该通过私有 S3 存储桶管理您的环境变量(尤其是 secrets)。请参阅博客文章如何使用 Amazon S3 和 Docker 管理基于 Amazon EC2 容器服务的应用程序的密钥。
归档时间: |
|
查看次数: |
712246 次 |
最近记录: |