在EC2上的Docker,dockerfile中的RUN命令不能读取环境variables
我在AWS上有两个弹性beanstalk环境:开发和生产。 我在每个实例上运行一个glassfish服务器,并且要求在生产和开发环境中可以部署相同的应用程序包,而不需要两个不同的.EAR
文件。这两个实例大小不同:dev有一个微型实例生产有一个中等的实例,因此我需要为glassfish部署两个不同的configuration文件,每个环境一个。
主要的问题是该文件必须在服务器启动之前在glassfish config目录中,因此我认为在创build容器时可以更好地移动它。
当然,每个环境都使用docker容器来托pipeglassfish实例,所以我首先想到的是为elastic-beanstalkconfiguration一个环境variables。 在这种情况下
ypenvironment = dev
为开发环境和
ypenvironment = pro
为生产环境。 然后在我的DOCKERFILE中,我把这个语句放在RUN命令中:
RUN if [ "$ypenvironment"="pro" ] ; then \ mv --force /var/app/GF_domain.xml /usr/local/glassfish/glassfish/domains/domain1/config/domain.xml ; \ elif [ "$ypenvironment"="dev" ] ; then \ mv --force /var/app/GF_domain.xml.dev /usr/local/glassfish/glassfish/domains/domain1/config/domain.xml ; \ fi
不幸的是,当启动完成后,两个GF_domain文件仍然在var/app
。
然后我发现RUN命令在容器满载之前运行了一些东西,可能缺less弹性beanstalk注入的variables。 所以我试图将代码移动到ENTRYPOINT指令。 再次运气,容器启动失败。 也试过了
ENTRYPOINT ["command", "param"]
语法,但它没有工作给一个
System error: exec: "if": executable file not found in $PATH
所以我卡住了。
你需要:
1 / 不使用入口点(或者至less使用sh -c 'if...'
语法):这是为了运行时执行,而不是编译时的图像构build。
2 /使用生成时间variables( --build-arg
) :
您可以在Dockerfile中使用
ENV
指令来定义variables值。 这些值坚持在build成的形象。
但是,往往坚持不是你想要的。 用户想要根据他们在哪个主机上构build图像来指定不同的variables。一个很好的例子是用于拉取中间文件的
http_proxy
或源代码版本。ARG
指令允许Dockerfile作者定义用户可以在构build时使用--build-arg
标志设置的值:
$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
在你的情况下,你的Dockefile应该包括:
ENV ypenvironment
然后docker build --build-arg ypenvironment=dev ... myDevImage
您将构build2个不同的图像(基于相同的Dockerfile)
我需要能够为开发和专业环境使用相同的EAR包,
然后,在运行时,您希望您的ENTRYPOINT根据环境variables的值移动文件。
您的Dockerfile仍然需要包含:
ENV ypenvironment
但是你需要运行你的一个图像
docker run -x ypenvironment=dev ...
确保您的脚本(由您的入口点引用)包含if [ "$ypenvironment"="pro" ] ; then...
if [ "$ypenvironment"="pro" ] ; then...
你提到你的问题,加上你的应用程序的实际启动(在前台)。
您的脚本不需要立即退出,或者您的容器在启动后立即切换到退出状态。
在使用Docker时,您必须区分构build时操作和运行时操作。 Dockerfiles用于构buildDocker镜像 ,而不是用于部署容器。 这意味着Dockerfile中的所有命令在构buildDocker镜像时执行, 而不是在从中部署容器时执行。
CMD
和ENTRYPOINT
命令是特殊的构build时间命令,它告诉Docker在从映像部署容器时要执行什么命令。
现在,在你的情况下,更好的方法是检查GlassFish是否支持domain.xml
(或其他地方)中的环境variables。 如果是这样,您可以在两种环境中使用相同的domain.xml
文件,并为它们使用相同的Docker映像。 然后,通过在本地运行时使用docker run -e "VAR=value"
注入运行时环境variables到容器,并在Elastic Beanstalk上部署时使用Environment Propertiesconfiguration部分,来区分这些环境。
编辑:如果你不能在domain.xml
使用环境variables,你可以通过启动一个脚本来启动容器来解决问题,该脚本读取运行时环境variables,并使用sed
将它们的值放在domain.xml
中的正确位置,然后照常开始你的申请。 你可以在这篇文章中find一个例子。
- AWS – Beanstalk
- 如何在弹性beanstalk docker json中定义多个任务
- 在Dockerrun源码包中部署AWS Elastic Beanstalk Docker部署中的ebextensionsconfiguration的位置?
- 从Docker Elastic Beanstalk容器中获取Elasticache地址
- AWS Elastic Beanstalk Docker部署失败
- 在Elastic Beanstalk上强制HTTPS单容器泊坞窗应用程序
- Amazon Elastic Beanstalk vs使用docker容器的EC2实例
- 在不同的Amazon服务器上运行Docker容器有没有好处?
- AWS Elastic Beanstalk中的多容器Dockerconfiguration版本错误