Docker 变量在什么时候可用?

At what point are Docker Variables available?

我正在使用 Rails 做一些工作,在我的数据库配置中,我有以下变量:

host: <%= ENV['MYSQL_PORT_3306_TCP_ADDR'] %>

Rails 一直失败,因为它说它正在尝试通过套接字连接,这向我表明该值为空(这就是 Rails 退回的方式)。

但是,每次我通过 docker exec 登录容器时,环境变量都设置正确。

我后来出于调试目的将其更改为以下内容:

host: 172.17.0.15 # <%= ENV['MYSQL_PORT_3306_TCP_ADDR'] %>

而且效果很好(这是之前报告的值)。

所以我的问题是,在 docker run 期间什么时候设置了 docker 环境变量?我在这里做错了什么吗?我想我很乐意将 nginx 作为我的 Docker 文件中的最后一个命令,但如果环境变量仍未设置,我觉得这不会解决任何问题。

更新

我正在使用此网页中的 Docker 文件 - https://rossfairbanks.com/2015/03/06/rails-app-on-docker-using-passenger-image.html

更新 2 Docker 运行: docker 运行 --rm --name nginx -p 80:80 --link mysql:mysql myNginxImage

引用的 Dockerfile 有:

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

如果你在执行 docker 运行 命令时没有覆盖它,这就是 'entrypoint' (我猜,这也没有发布在问题中).接下来是一堆猜测,但是,我想我是对的:-)

首先,文档指出:

Passenger works like a mod_ruby, mod_nodejs, etc. It changes Nginx into an application server and runs your app from Nginx. So to get your web app up and running, you just have to add a virtual host entry to Nginx which describes where you app is, and Passenger will take care of the rest.

然后,后面在描述Nginx启动的时候:

By default Nginx clears all environment variables (except TZ) for its child processes (Passenger being one of them). That's why any environment variables you set with docker run -e, Docker linking and /etc/container_environment, won't reach Nginx.

这是相当典型的 init 行为,可以在启动进程之前清除 env 变量。由于 nginx 已清除其环境变量,因此它随后启动的任何进程也将清除环境变量。幸运的是,他们告诉您如何将变量传播到子流程:

To preserve these variables, place an Nginx config file ending with *.conf in the directory /etc/nginx/main.d, in which you tell Nginx to preserve these variables. For example when linking a PostgreSQL container or MongoDB container:

然后他们展示了一个例子。你可以创建一个文件,调用是 mysql-env.conf,在你的 Dockerfile 相同的目录中,它包含:

env MYSQL_PORT_3306_TCP_ADDR;

然后,在您的 Dockerfile 中,放入以下行:

ADD mysql-env.conf /etc/nginx/main.d/mysql-env.conf

这应该会为您泄露 env 变量。