首页 > 解决方案 > Docker/Compose:定义和使用环境变量

问题描述

在我的 github 上,我正在从 debian 最小 docker 映像创建一个小叉。它实际上是在以前的基础上构建的 5 个软件包:

debian-base-minimal
debian-base-standard
debian-base-security
debian-base-apache
debian-base-apache-php

在 debian-base-apache 上,我想获得一个工作环境变量,我可以稍后在 docker-compose 文件中定义它。环境应该做什么?

如果在 docker-compose 上定义,它应该写ServerName $SERVER_NAME在末尾/etc/apache2/apache2.conf以设置全局服务器名称。如果为空,则不应写入新行。

但是为什么它在空的时候什么都不写呢?Cauz 在将 Dockerfile 构建到映像时不应包含SERVER_NAME.

我已经尝试过类似的东西: echo "ServerName $SERVER_NAME" >> /etc/apache2/apache2.conf

在我的 040-debian-base-apache 文件上。但是在构建它ServerName的时候,因为我没有定义一个值和它的使用null。如果我在 Dockerfile ( ENV SERVER_NAME=127.0.0.1) 中设置了默认值,它使用它构建图像127.0.0.1并且我无法127.0.0.1通过变量进行更改,因为变量已经填充了该值。

在 Dockerfile中定义的建筑物的输出ENV SERVER_NAME=127.0.0.1(实际上不在 repo 中):

[...]
+ echo 'ServerName 127.0.0.1'
+ /etc/init.d/apache2 stop
Stopping Apache httpd web server: apache2.
ok.
+ /etc/init.d/apache2 start
Starting Apache httpd web server: apache2.
ok.
[...]

没关系,如果有默认 127.0.0.1 因为 apache 可以启动。但我现在无法在 docker-compose.yml 中定义它,因为它的硬编码 127.0.0.1 而不是变量的输出。

在 Dockerfile 中没有定义 ENV 的建筑物的输出(实际上是 repo 版本):

[...]
+ echo 'ServerName '
+ /etc/init.d/apache2 stop
Stopping Apache httpd web server: apache2.
+ /etc/init.d/apache2 start
Starting Apache httpd web server: apache2 failed!
The apache2 configtest failed. ... (warning).
Output of config test was:
AH00526: Syntax error on line 228 of /etc/apache2/apache2.conf:
ServerName takes one argument, The hostname and port of the server 
[...]

任何人都可以帮我完成这项工作吗?很高兴了解它是如何工作的。

提前谢谢了。

标签: apachedockerdebian

解决方案


正如您所观察到的,Dockerfile 中的每个 RUN 命令都会同时发生docker build,特别是文件的内容将根据您运行构建时的环境变量来修复。您希望它根据变量的运行时值进行更改,这意味着您需要编写一个在启动时运行的脚本来执行此操作。

一种典型的方法是编写一个 ENTRYPOINT 脚本来进行首次设置。ENTRYPOINTdocker run作为命令行参数传递给 CMD(或传递给 的任何命令),所以如果它以 结尾exec "$@",它所做的最后一件事就是启动“正常”命令。你可以在这里使用任何普通的 shell 脚本逻辑,所以我可能会写

#!/bin/sh
if [ -n "$SERVER_NAME" ]; then
  echo "ServerName $SERVER_NAME" >> /etc/apache2/apache2.conf
fi
exec "$@"

然后你可以在你的 Dockerfile 中提供这个

COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["apachectl", "-DFOREGROUND"]

chmod如果您可以保证该文件在您的非 Windows 主机上具有执行权限,则不需要。ENTRYPOINT必须使用 JSON-ish 形式。如果您有另一个基于此构建的图像,请记住组合图像仅获取一个入口点和一个 CMD;你建议的非常深的图像堆栈是一个非常不寻常的设置。)


推荐阅读