docker构建镜像问题之工作目录和入口文件问题
docker 构建时遇到的问题执行docker build之后,显示can't load package: package .: no Go files in /go构建完毕后,在本地可以完美执行,但是在travis cli集成工作上构建后无法工作,报错:docker: Error response from daemon: invalid header field value "oci
docker 构建时遇到的问题
- 执行
docker build
之后,显示can't load package: package .: no Go files in /go
构建完毕后,在本地可以完美执行,但是在travis cli集成工作上构建后无法工作,报错:
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"./MathApp\\\": permission denied\"\n".
问题的解决
首先,我的项目结构如下:
MathApp
├── conf
│ └── app.conf
├── Dockerfile
├── main.go
├── main_test.go
└── views
├── invalid-route.html
└── result.html
一个简单的数学计算应用。通过访问网址,可以返回计算结果。更多内容请参考:如何使用Docker部署Go Web应用程序
显示can't load package: package .: no Go files in /go
问题的原因及解决
这是第一次构建镜像,我的Dockefile
文件内容如下:
FROM golang:latest
# Create the directory where the application will reside
RUN mkdir /app
# build
RUN go build
# Copy the application files (needed for production)
ADD MathApp /app
ADD views /app/views
ADD conf /app/conf
# Set the working directory to the app directory
WORKDIR /app
# Expose the application on port 8080.
# This should be the same as in the app.conf file
EXPOSE 8080
# Set the entry point of the container to the application executable
ENTRYPOINT [ "./MathApp" ]
由于构建的镜像体积比较到,所以我希望尽可能减小镜像的体积,所以就希望只将可执行文件及其执行时用到的资源文件加入到镜像中。为了免去麻烦,直接在Dockerfile
文件中执行编译命令。然后,却报出了上面的错误。
其中的原因只要和docker镜像的分层有关。docker构建过程中,每一个命令都在它的上一层镜像的环境中执行,而并不是在我们的项目环境下执行。也就是说,在我执行RUN go build
命令时,它的运行环境应该是执行了RUN mkdir /app
的镜像环境,此时镜像中并不包含main.go, main_test.go等代码文件,自然无法完成build任务。
更多关于docker镜像分层的问题,请参考:浅析Docker镜像分层的注意事项_docker
docker构建的镜像运行时的权限问题
修正第一次的问题后的Dockerfile文档如下(在构建docker镜像前进行编译):
FROM golang:latest
# Create the directory where the application will reside
RUN mkdir /app
# Copy the application files (needed for production)
ADD MathApp /app
ADD views /app/views
ADD conf /app/conf
# Set the working directory to the app directory
WORKDIR /app
# Expose the application on port 8080.
# This should be the same as in the app.conf file
EXPOSE 8080
# Set the entry point of the container to the application executable
ENTRYPOINT [ "./MathApp" ]
这个在本地运行,完全没有问题。但是,无论是通过阿里云第三方构建而后拉倒本地运行,或者通过travis cli构建后运行测试,都会报错:
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"./MathApp\\\": permission denied\"\n
从错误的描述中可以看出,运行镜像时,没有执行入口文件MathApp
的权限。那么,我们就在构建镜像时,赋予它这个权限,在添加入口文件的命令执行前,增加赋予权限的命令:
RUN chmod +x MathApp
最终,修改后的Dockefile
如下:
FROM golang:latest
# Create the directory where the application will reside
RUN mkdir /app
# Copy the application files (needed for production)
ADD MathApp /app
ADD views /app/views
ADD conf /app/conf
# Set the working directory to the app directory
WORKDIR /app
# Expose the application on port 8080.
# This should be the same as in the app.conf file
EXPOSE 8080
# give a permission
RUN chmod +x MathApp
# Set the entry point of the container to the application executable
ENTRYPOINT /app/MathApp
更多推荐
所有评论(0)