英文:
Can't get docker to run Go executable using Docker-Compose
问题
我正在使用Go创建一个简单的Rest API,并希望使用Docker进行容器化以进行部署。我的Dockerfile如下:
FROM golang:1.19
# 要暴露的端口
ENV PORT=8080
WORKDIR /go/src/app
# 安装libvips
RUN apt-get update && apt-get install -y libvips-dev
# 复制go.mod和go.sum
COPY go.mod go.sum ./
# 安装Go依赖项
RUN go mod download
# 为libvips设置PKG_CONFIG_PATH
ENV PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
RUN pkg-config --libs vips
# 复制源代码
COPY . .
# 取消注释以构建应用程序
# 构建应用程序
RUN go build -o main .
# 暴露端口
EXPOSE 8080
# 运行应用程序
CMD ["./main"]
而我的docker-compose文件如下:
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: backend
command: ./main
ports:
- "3000:8080"
volumes:
- .:/go/src/app
我对Docker和容器化还不太熟悉,但我认为这应该在设置方面是有效的(注意:之前已经有几次成功,但最近因某种原因停止工作)。我遇到以下错误:Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./main": stat ./main: no such file or directory: unknown
。
这个错误让我认为我的可执行文件没有在工作目录中构建,但我不确定它在哪里构建,因为我已经使用相对路径设置了构建命令。对于可能导致这个问题的原因有什么想法吗?
英文:
I'm making a simple Rest API using Go and I want to containerize it using docker for deployment. My Dockerfile looks like this
FROM golang:1.19
# Port to expose
ENV PORT=8080
WORKDIR /go/src/app
# Install libvips
RUN apt-get update && apt-get install -y libvips-dev
# Copy go.mod and go.sum
COPY go.mod go.sum ./
# Install go dependencies
RUN go mod download
# Set PKG_CONFIG_PATH for libvips
ENV PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig
RUN pkg-config --libs vips
# Copy the source code
COPY . .
# Uncomment to build the app
# Build the app
RUN go build -o main .
# Expose the port
EXPOSE 8080
# Run the app
CMD ["./main"]
and my docker-compose file looks like this:
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: backend
command: ./main
ports:
- "3000:8080"
volumes:
- .:/go/src/app
I'm new to docker and containerization, but I think this should work in terms of setup (Note: It has worked a few times before, but recently stopped working for some reason). I get the following error: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "./main": stat ./main: no such file or directory: unknown
.
This error leads me to believe that my exe is not being built in the working directory, but I am unsure where it gets built since I've set the build command using relative paths. Any idea on what could be causing this issue?
答案1
得分: 1
不应该在 docker-compose
文件中包括 volumes
映射(.:/go/src/app
)。
这样做会覆盖容器中的文件夹,用主机的文件夹替换它。
两者之间的一个关键区别是容器的文件夹包括 go build
的输出。你正在构建二进制文件(/go/src/app/main
),然后用 volumes
映射覆盖整个文件夹。
注意 最好的做法是使用
ENTRYPOINT
而不是CMD
来运行二进制文件,即ENTRYPOINT ["./main"]
。CMD
的值会在运行容器时被任何提供的参数覆盖,而ENTRYPOINT
只能通过显式设置--entrypoint
标志来覆盖。按照惯例,使用ENTRYPOINT
来定义容器始终要调用的二进制文件(以及任何标志),并使用CMD
用于可以被覆盖的可选标志。
英文:
You shouldn't include the volumes
mapping (.:/go/src/app
) in the docker-compose
file.
When you do this, you're overwriting the container's folder with your host's folder.
A key difference between the two is that the container's folder includes the output from go build
. You're building the binary (/go/src/app/main
) and then overwriting the entire folder with the volumes
mapping.
> NOTE It's better practice to use ENTRYPOINT
rather than CMD
to run the binary, i.e. ENTRYPOINT ["./main"]
. The value(s) of CMD
are overwritten by any parameters provided when the container is run whereas ENTRYPOINT
may only be overwritten by explicitly setting the --entrypoint
flag. Conventionally, use ENTRYPOINT
to define the binary (and any flags) that must always be invoked by the container and use CMD
for optional flags that may be overwritten.
答案2
得分: 0
这是一个稍微偏离主题的建议,但在使用libvips时,请使用--no-install-recommends
选项。Debian软件包在libvips-dev
的建议列表中包括libvips-tools
,而libvips-tools
又会引入libvips的GUI和大部分X11。
您可以通过以下方式看到这种差异:
$ docker run -it --rm golang:1.19
root@c54a0cab0cb0:/go#
root@c54a0cab0cb0:/go#
root@c54a0cab0cb0:/go# apt update
...
root@c54a0cab0cb0:/go# apt install libvips-dev
...
需要下载 189 MB 的存档。
此操作完成后,将使用额外 740 MB 的磁盘空间。
您要继续吗?[Y/n] ^C
...
因此,常规安装需要740MB的空间。但是:
root@c54a0cab0cb0:/go# apt install libvips-dev --no-install-recommends
需要下载 92.2 MB 的存档。
此操作完成后,将使用额外 374 MB 的磁盘空间。
您要继续吗?[Y/n] ^C
大约一半的大小。
英文:
This is a slight tangent, but use --no-install-recommends
with libvips. The Debian package includes libvips-tools
in the recommends list for libvips-dev
, and that in turn will pull in the libvips GUI and most of X11.
You can see the difference it makes like this:
$ docker run -it --rm golang:1.19
root@c54a0cab0cb0:/go#
root@c54a0cab0cb0:/go#
root@c54a0cab0cb0:/go# apt update
...
root@c54a0cab0cb0:/go# apt install libvips-dev
...
Need to get 189 MB of archives.
After this operation, 740 MB of additional disk space will be used.
Do you want to continue? [Y/n] ^C
...
So a reular install is 740mb of space. But:
root@c54a0cab0cb0:/go# apt install libvips-dev --no-install-recommends
Need to get 92.2 MB of archives.
After this operation, 374 MB of additional disk space will be used.
Do you want to continue? [Y/n] ^C
About half the size.
答案3
得分: 0
当您运行容器时,CMD 的值将被提供的任何参数覆盖。最好使用 ENTRYPOINT 来运行二进制文件,即 ENTRYPOINT ["./main"]。
英文:
When you run the container, the value of CMD will be overwritten by any parameters provided. It is better to use ENTRYPOINT instead of CMD to run binary files, that is ENTRYPOINT ["./main"].
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论