我正在使用Dockerfile构建映像。我正在提取最新的Ubuntu和golang映像。
在导入所有目录并使用映像内部的go build生成可执行文件后,我要运行可执行文件。因此,我尝试使用ENTRYPOINT
或CMD
,以便可执行文件在容器启动时运行。
问题在于,当我执行此操作并且以连接模式或分离模式运行容器时,它一直一直在重复注册Enter Key
(并且CPU使用率变得疯狂)。我能理解这一点,因为我的脚本等待键被注册,然后一些输入终止,但是由于Enter键再次被立即注册,因此它会打印一条消息,然后再次发生相同的循环。
当我在不执行二进制文件(不执行CMD
或ENTRYPOINT
)的情况下构建映像时,然后使用bash终端运行容器(二进制文件仍在映像内部),然后执行二进制文件,一切正常,而没有任何时间Enter Key
进行注册。
为什么会发生这种情况?
我的Dockerfile的简要说明:
# Import Images
FROM ubuntu:18.04
FROM golang:1.10
# Open ports
EXPORT ...
# Copy dependencies to GOPATH in docker file
COPY github.com/user/dependencies /go/src/github.com/user/dependencies
...
# Set working directory and build executable
WORKDIR /go/src/github.com/user/app-folder
RUN go build
# Run the binary (or not)
CMD ["app_name"]
-----OR-----
CMD ["./app_name"]
-----OR-----
ENTRYPOINT app_name
-----OR-----
ENTRYPOINT /go/src/github.com/user/app-folder/app_name
最后,我一次尝试了所有这些,我只是像这样包含了它们以进行显示。结果总是一样的。终端中的结果是:
...
Are you sure you want to exit? y/n
running. press enter to stop.
Are you sure you want to exit? y/n
running. press enter to stop.
...
go脚本如下:
// running flag is set to True and then it scans for a newline
for running {
fmt.Println("running. press enter to stop.")
fmt.Scanln()
fmt.Println("Are you sure you want to exit? y/n")
if models.ConfirmUserAction() {
running = false
close(models.DbBuffer)
}
}
以及包含ConfirmUserAction
函数的模型包:
//ConfirmUserAction waits (blocks) for user input, returns true if input was Y/y, else false.
func ConfirmUserAction() bool {
var confirm string
fmt.Scanln(&confirm)
if confirm == "y" || confirm == "Y" {
return true
}
return false
}
答案 0 :(得分:0)
我找到了一种方法,可以通过在容器内创建一个shell脚本来绕过此问题,然后运行可执行文件(也许有点怪异,但是Enter键不再一直在注册)。
因此,现在,我不是在Dockerfile上的ENTRYPOINT
上运行可执行文件,而是在ENTRYPOINT
上运行了shell脚本,该脚本仅包含以下内容:
#! /bin/sh
sleep 1;
echo "Starting Metrics Server..."
./metrics_server
metrics_server是我编译后的可执行文件,我正在Dockerfile内设置工作目录WORKDIR
,将其作为可执行文件和shell脚本。
值得一提的是,我已经将Ubuntu映像导入了我的Dockerfile(FROM ubuntu:18.04
)中,因为无论如何我都需要它。我之所以这样说,是因为如果没有它,它可能无法工作(不确定,我没有尝试过。)