简体   繁体   English

在文件 Dockerfile、docker-compose.yml、python.py 和 Z2591C98B70119FE6248Z198B1E4 之间共享值

[英]sharing values among files Dockerfile, docker-compose.yml, python.py, and shell

How do I share a value among the stack of technologies docker , docker-compose , Python , and POSIX shell for a single project? How do I share a value among the stack of technologies docker , docker-compose , Python , and POSIX shell for a single project?

For example, I would like to set the value PORT once.例如,我想将值PORT设置一次。 It would be nice if PORT was set within one file and other files would reference that value.如果PORT设置在一个文件中并且其他文件将引用该值,那就太好了。

However, in my foo project the value PORT must be set among several files, each of which is a parsed by different a technology:但是,在我的foo项目中,值PORT必须在几个文件中设置,每个文件都由不同的技术解析:


File foo.py文件foo.py

#!/usr/bin/env python
PORT = 80

File Dockerfile文件Dockerfile

# foo
ENV PORT=80
EXPOSE ${PORT}

File docker-compose.yml文件docker-compose.yml

version: '2'
services:
  web:
    image: docker.corp.com/foo
  expose:
    - '80'

File run.sh文件run.sh

#!/usr/bin/env sh
PORT=80


It is preferable to git commit the files "as is", eg no "on the fly" code generators. git commit文件,例如没有“即时”代码生成器。

It seems like the easiest solution would be setting PORT in your local environment.似乎最简单的解决方案是在本地环境中设置PORT

Then:然后:

  • Your python code can read the value from os.environ .您的 python 代码可以从os.environ读取值。

  • You can provide the value to your container in docker-compose by including:您可以通过包括以下内容为docker-compose中的容器提供值:

     environment: PORT: ${PORT}
  • If you need to start a container outside of docker-compose , you can pass it on the docker run command line:如果您需要在docker-compose之外启动一个容器,您可以在docker run命令行上传递它:

     docker run -e PORT=$PORT...
  • And of course your run.sh script can just reference $PORT directly.当然你的run.sh脚本可以直接引用$PORT

There are a couple of things like filesystem paths and TCP port numbers where Docker allows picking a value when the container is run, and that value doesn't have to be the same as what's inside the image.有一些东西,比如文件系统路径和 TCP 端口号,其中 Docker 允许在容器运行时选择一个值,并且该值不必与图像中的值相同。 For the example you give of a TCP port, it's usually easier to just pick some number and not try to make it configurable at the Docker layer.对于您给出的 TCP 端口的示例,通常更容易选择一些数字,而不是尝试在 Docker 层进行配置。

# Dockerfile
# Don't bother setting ENV PORT
EXPOSE 80
# docker-compose.yml
services:
  web:
    image: docker.corp.com/foo
  # expose: is already in the Dockerfile, but you probably need
  ports:
    - '8000:80'
      #     ^^ where this matches the image

You also don't need to set values at every level.您也不需要在每个级别设置值。 If you EXPOSE a port in your Dockerfile you don't need to also expose: the same port in docker-compose.yml ;如果您在EXPOSE中公开一个端口,则您不需要也expose: Dockerfile docker-compose.yml的相同端口; if you set an ENV in the Dockerfile you don't need to set it in shell scripts that run inside the container.如果您在Dockerfile中设置ENV ,则无需在容器内运行的 shell 脚本中设置它。

In your script itself, you'll probably be running it both inside Docker and also outside Docker for day-to-day development, so it's useful to make details like the port number, database connectivity, ... configurable there.在您的脚本本身中,您可能会在 Docker 内部和 Docker 外部运行它以进行日常开发,因此在此处进行诸如端口号、数据库连接等详细信息是很有用的。

# foo.py
PORT = int(os.environ.get('PORT', '80'))

The general approach I take to this in my day job is to make the defaults in the script match what a developer needs – "high" ports like 8000, the database is running on localhost – but in the Docker deployment reconfigure it for the different environment.我在日常工作中对此采取的一般方法是使脚本中的默认值与开发人员的需求相匹配——“高”端口,如 8000,数据库在localhost上运行——但在 Docker 部署中为不同的环境重新配置它.

For things that aren't related to Docker settings like port numbers, there's a more general answer to the specific question you asked.对于与 Docker 设置(如端口号)无关的事情,对于您提出的具体问题,有一个更一般的答案。 Say you have some other environment variable假设您有其他一些环境变量

# The URL the service is ultimately reachable at, taking
# things like load balancers into account
EXTERNAL_URL = os.environ.get('EXTERNAL_URL', '')
#!/bin/sh
echo "Your service will be reachable at $EXTERNAL_URL"
exec ./myscript.py

These variables aren't resolved until the script is ultimately run, so if you set it once in docker-compose.yml everyone else will be able to read it.这些变量在脚本最终运行之前不会被解析,所以如果你在docker-compose.yml中设置一次,其他人都可以阅读它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM