首页 > 解决方案 > -v(--volume) 似乎很懒惰!奇怪的行为

问题描述

问题描述

-v 的行为似乎是懒惰的,这导致了no such file or directory 错误

以下是我所做的。

  1. 从名为 frp 的 go 项目构建映像,这是我的Dockerfile

    FROM golang:rc-alpine AS builder
    WORKDIR /builddir
    COPY . /builddir/
    RUN GO111MODULE=on CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o bin/frps ./cmd/frps
    
    FROM scratch
    WORKDIR /app
    COPY --from=builder /builddir/bin/frps /app/
    ENTRYPOINT [ "/app/frps"]
    CMD [ "-c /etc/frp/frps.ini" ]
    

    请注意,我使用/etc/frp/frps.ini图像中不存在的配置文件

  2. 我成功构建了镜像,您可以从存储库 290007431/frps:v0 中提取镜像,但是当我尝试运行它时遇到了问题。

  3. 我从我的 ubuntu VPS 中提取图像,并在 /etc/frp/frps.ini 上创建一个配置文件

    [common]
    # A literal address or host name for IPv6 must be enclosed
    # in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
    bind_addr = 0.0.0.0
    bind_port = 9000
    
    dashboard_addr = 0.0.0.0
    dashboard_port = 7500
    
  4. 然后我使用下一个命令运行

    docker run -d \
    -p 9000:9000 \
    -v /etc/frp:/etc/frp/:ro \
    --name frps \
    290007431/frps:v0
    

    文件不存在错误出现在这里。

我检查过的

  1. docker logs 获取错误信息,如第一图所示。
  2. docker contains cp 复制停止容器内的文件,检查/etc/frp/frps.ini 是否存在,答案是YES!!!

我如何克服它

我使用命令

docker run -d \
-p 9000:9000 \
-v /etc/frp:/etc/frp/:ro \
--name frps \
290007431/frps:v0 echo /etc/frp/frps.ini

你看,只需 echo /etc/frp/frps.ini在尾部添加 ,应用程序现在可以在容器中找到配置文件。这里是结果

更重要的是,我发现尾部的任何附加命令都会使其工作! 这让我很困惑

我知道这ENTRYPOINT将覆盖任何 cmd但为什么稍后docker run会成功运行?引擎盖下是否有惰性卷加载策略?

标签: dockerdockerfilefast-reverse-proxy

解决方案


CMD有两种口味。它可以写成不带方括号的 shell 命令,在这种情况下 Docker 将执行分词,如下所示:

CMD -c /etc/frp/frps.ini

或者您可以使用方括号语法来准确地告诉它参数是什么,如下所示:

CMD ["-c", "/etc/frp/frps.ini"]

你写的是两者的混合:

CMD [ "-c /etc/frp/frps.ini" ]

这看起来像两个参数,但它实际上是一个带有嵌入空间的单个参数。

我怀疑 frps 然后像大多数 UNIX 实用程序一样解析这个,其中选项参数可以附加到选项中,如-c<filename>. 它解释"-c /etc/frp/frps.ini""-c"后跟文件名" /etc/frp/frps.ini"

请注意,文件名有一个前导空格。这就是为什么您找不到文件的原因。它没有打开你想要的路径。如果您仔细观察,您会在错误消息中看到额外的空格:

Error: open  /etc/frp/frps.ini: no such file or directory
            ^
2021/01/29 17:10:27 [I] [root.go:108] frps uses config file:  /etc/frp/frps.ini
                                                             ^

更重要的是,我发现尾部的任何附加命令都会使其工作!

当您提供自己的命令时,您将覆盖CMDDockerfile 中的 ,摆脱有问题的-c.


推荐阅读