提问人:Unnamed 提问时间:5/31/2023 最后编辑:Unnamed 更新时间:6/3/2023 访问量:1044
Docker Compose。调用自定义脚本
Docker Compose. Call a custom script
问:
我有一个简单的定义,我想运行一个简单的/命令:docker-compose
cmd
bash
basictests:
image: ${DOCKER_REGISTRY-}mytests
build:
context: .
dockerfile: MyTests/Dockerfile
container_name: "mytestscontainer"
command:
- echo "test"
depends_on:
dependent_env:
condition: service_healthy
注意:这是一个简化的测试。与其调用,我实际上想运行一些更复杂的脚本。echo
但是,当我运行此配置时,它会抛出以下错误:
==> /dev/null <==
tail: cannot open 'echo "test"' for reading: No such file or directory
不知道从哪里来以及如何修复。看看这个,它应该可以工作。如果我删除,它可以正常工作。任何帮助都将得到赞赏。tail
command
更新:DockerFile 除了安装和构建我的库外不做任何事情。dotnet
UPDATE2:基础 docker 文件为:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
# restore
COPY ["MyTests/MyTests.csproj", "MyTests/"]
RUN dotnet restore "MyTests/MyTests.csproj"
# build
COPY . .
WORKDIR "/src/MyTests"
RUN dotnet build "MyTests.csproj" -c Release -o /app/build
在上面的 docker 文件的末尾添加建议无济于事。
注意:我是 docker 和 docker-compose 的新手。ENTRYPOINT ["/bin/bash", "-c"]
UPDATE3:
添加到docketfile的末尾并更改我调用命令的方式,这无济于事。总的来说,我很好奇这是怎么回事?为什么会出现这种情况?ENTRYPOINT ["tail", "-f", "/dev/null"]
command: [echo, test]
tail
注意:对于上下文,我想配置适用于少数容器的集成测试,因此我想为我的集成测试运行,而不是echo ..
dotnet test ..
UPDATE4:配置如下:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
EXPOSE 80
EXPOSE 443
# restore
COPY ["MyTests/MyTests.csproj", "MyTests/"]
RUN dotnet restore "MyTests/MyTests.csproj"
# build
COPY . .
WORKDIR "/src/MyTests"
RUN dotnet build "MyTests.csproj" -c Release -o /app/build
ENTRYPOINT ["/bin/bash"]
如果我在本地从 cmd 运行它,效果很好:
%SomePath%\Demo>docker build -f MyTests/Dockerfile -t mytest .
[+] Building 0.3s (12/12) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 32B
=> [internal] load .dockerignore
=> => transferring context: 35B
=> [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0
=> [1/7] FROM mcr.microsoft.com/dotnet/sdk:6.0
=> [internal] load build context
=> => transferring context: 2.00kB
=> CACHED [2/7] WORKDIR /src
=> CACHED [3/7] COPY [MyTests/MyTests.csproj, MyTests/]
=> CACHED [4/7] RUN dotnet restore "MyTests/MyTests.csproj"
=> CACHED [5/7] COPY . .
=> CACHED [6/7] WORKDIR /src/MyTests
=> CACHED [7/7] RUN dotnet build "MyTests.csproj" -c Release -o /app/build
=> exporting to image
=> => exporting layers
=> => writing image sha256:9c...
=> => naming to docker.io/library/mytest
%SomePath%\Demo>docker run -it mytest
root@999afef78716:/src/MyTests# ls
MyTests.csproj ApiTests.cs Properties obj
因此,看起来问题仅在于如何从 docker-compose 配置正确调用它。我还尝试设置以下选项
..
image: ${DOCKER_REGISTRY-}mytests
stdin_open: true # docker run -i
tty: true # docker run -t
..
没有运气。
UPDATE5: 我试图用新的控制台应用程序简化我对这 2 个文件的所有逻辑:
Docker文件:
FROM alpine:3.14
WORKDIR "/src"
CMD ["/bin/bash"]
# same behavior if I use `CMD ["/bin/sh"]`
docker-compose:
version: '3.4'
services:
consoleappdocker:
image: ${DOCKER_REGISTRY-}consoleappdocker
build:
context: .
dockerfile: ConsoleAppDocker/Dockerfile
container_name: "consoleappdocker"
command: ["/bin/bash", "-c", "echo test"]
仍然失败并出现错误,但是我刚刚注意到以下输出:tail: invalid number 'echo test'
docker ps -a --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
%id% consoleappdocker:dev "tail -f /dev/null /bin/bash -c 'echo test'" 7 minutes ago Exited (1) 7 minutes ago consoleappdocker
所以看起来@VonC是对的,但是我不知道这部分最初是在哪里添加的tail
UPDATE6 :
显然,该部分是由我用来构建和运行应用程序的 Visual Studio 添加的,我在日志中找到了它:tail
docker-compose -f "%PATH%\docker-compose.yml" -f "%PATH%\docker-compose.override.yml" -f "%PATH%\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose14997374556887134345 --ansi never --profile "*" config
name: dockercompose14997374556887134345
services:
consoleappdocker:
build:
context: %PATH%
dockerfile: ConsoleAppDocker/Dockerfile
labels:
com.microsoft.created-by: visual-studio
com.microsoft.visual-studio.project-name: ConsoleAppDocker
command:
- /bin/bash
- -c
- echo test
container_name: consoletest
entrypoint:
- tail
- -f
- /dev/null
environment:
..
image: consoleappdocker:dev
labels:
..
networks:
default: null
tty: true
volumes:
..
networks:
default:
name: dockercompose14997374556887134345_default
docker-compose -f "%PATH%\docker-compose.yml" -f "%PATH%\docker-compose.override.yml" -f "%PATH%\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose14997374556887134345 --ansi never build
相当出乎意料的情况,但我认为下一步该怎么做或多或少是清楚的
答:
文件中的 command
指令用于覆盖 中指定的缺省值。
该指令等同于您将在 之后传递的命令。docker-compose.yml
CMD
Dockerfile
command
docker run <image> <command>
你看到一个错误,因为你的 Dockerfile 可能配置为运行一个命令,该命令涉及其执行结束时,并且当您覆盖文件中的命令时,该命令正在尝试读取一个名为 的文件,该文件不存在。tail
tail
docker-compose.yml
tail
echo "test"
在本例中,您希望在容器内运行命令。应如下所示:docker-compose.yml
basictests:
image: ${DOCKER_REGISTRY-}mytests
build:
context: .
dockerfile: MyTests/Dockerfile
container_name: "mytestscontainer"
command: ["/bin/bash", "-c", "echo test"]
depends_on:
dependent_env:
condition: service_healthy
这将在容器内执行命令。echo test
要运行复杂的命令或脚本,您可以:
在生成过程中将脚本添加到 Docker 映像,然后从指令调用脚本。
command
在构建过程中将脚本添加到 Docker 映像中,然后从 或 中调用该脚本。
CMD
ENTRYPOINT
Dockerfile
将包含脚本的卷挂载到容器中,然后从 中的指令调用脚本。
command
docker-compose.yml
对于有关运行集成测试的最后说明,可以将运行测试的脚本添加到 Docker 映像,然后在指令中调用该脚本。脚本可能如下所示:command
#!/bin/bash
# Run the tests
dotnet test MyTests/MyTests.csproj
然后在你的 :docker-compose.yml
basictests:
image: ${DOCKER_REGISTRY-}mytests
build:
context: .
dockerfile: MyTests/Dockerfile
container_name: "mytestscontainer"
command: ["/bin/bash", "-c", "/path/to/your/script.sh"]
depends_on:
dependent_env:
condition: service_healthy
请将“”替换为 Docker 容器中脚本的实际路径。/path/to/your/script.sh
并确保脚本具有执行权限。您可以在 Docker 构建期间使用以下指令设置这些内容:RUN
COPY ./host/path/to/your/script.sh /path/to/your/script.sh
RUN chmod +x /path/to/your/script.sh
请将“”替换为主机上脚本的路径。./host/path/to/your/script.sh
这是一个很好的猜测,但不,我没有在任何地方配置/看到它
您提供的 Dockerfile 不显示涉及该命令的 or 指令。但是,您看到的错误消息表明该命令正在运行,并尝试将“echo ”test“作为文件打开,这表明该命令正在某处调用。CMD
ENTRYPOINT
tail
tail
tail
也有可能作为基础映像或父映像的一部分运行,或者由容器中的某个进程运行。如果基础映像或父映像具有包含 的 或,并且您没有在 Dockerfile 中覆盖它,则可以解释为什么您会在错误消息中看到该命令。tail
CMD
ENTRYPOINT
tail
tail
在 Dockerfile 中的一个常见用途是让容器无限期地运行,即使其主进程已终止(就像我在这里所做的那样)。这有时用于开发环境或需要保持运行但可能并不总是有进程要运行的服务。
如果以这种方式调用,则尝试将命令替换为其他内容(例如 )可能会导致您看到的错误消息。tail -f /dev/null
tail
tail -f /dev/null
echo "test"
若要确认这一点,可以检查基本映像或父映像,或者在 Dockerfile 或文件中运行的任何脚本或命令。docker-compose.yml
当我使用命令应用配置时,我看到此错误:,这仍然是关于......
docker-compose
command: ["/bin/bash", "-c", "echo test"]
tail: invalid number of bytes: 'echo test'
tail
如果 在 Dockerfile 或基础映像中设置为命令,并且您正在使用 docker-compose 文件中的指令运行 ,则 Docker 将尝试将 附加到命令中。
在这种情况下,它会尝试执行类似 的东西,这不是一个有效的命令,会导致您看到的错误。ENTRYPOINT
tail
command
bash -c "echo test"
command
ENTRYPOINT
tail bash -c "echo test"
您会在此处发现类似的“无效编号”错误,其中基础映像 alpine 没有 bash,并且内置命令没有所有更常见的选项。
“BUSYBOX脚本是错误的”中的相同想法"
显然,尾部部分是由我用来构建和运行应用程序的 Visual Studio 添加的,我在日志中找到了它:
docker-compose -f "%PATH%\docker-compose.yml" -f "%PATH%\docker-compose.override.yml" -f "%PATH%\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose14997374556887134345 --ansi never --profile "*" config
name: dockercompose14997374556887134345
services:
consoleappdocker:
build:
context: %PATH%
dockerfile: ConsoleAppDocker/Dockerfile
labels:
com.microsoft.created-by: visual-studio
com.microsoft.visual-studio.project-name: ConsoleAppDocker
command:
- /bin/bash
- -c
- echo test
container_name: consoletest
entrypoint:
- tail
- -f
- /dev/null
environment:
..
image: consoleappdocker:dev
labels:
..
networks:
default: null
tty: true
volumes:
..
networks:
default:
name: dockercompose14997374556887134345_default
docker-compose -f "%PATH%\docker-compose.yml" -f "%PATH%\docker-compose.override.yml" -f "%PATH%\obj\Docker\docker-compose.vs.debug.g.yml" -p dockercompose14997374556887134345 --ansi never build
您可以看到之前(VS 2019)和此处提到的实践。
如“Docker 容器中的 Azure 函数在 Visual Studio 中运行,但不从命令行执行任何操作”中所述:
发布的命令仅用于 Visual Studios 调试功能。它用 tail -f /dev/null 覆盖入口点,这基本上是“永远循环”。
官方文档:
入口点是 ,这是保持容器运行的无限等待。
当通过调试器启动应用时,调试器负责运行应用(即 )。
如果在未调试的情况下启动,则工具将运行 a 以运行应用。tail -f /dev/null
dotnet webapp.dll
docker exec -i {containerId} dotnet webapp.dll
若要修改仅用于调试的容器,请创建一个阶段,然后使用 MSBuild 属性 DockerfileFastModeStage 告知 Visual Studio 在调试时使用自定义阶段。有关 Dockerfile 命令的信息,请参阅 Docker 文档中的 Dockerfile 参考。
因此,请检查您的项目属性文件中是否有如下部分:
<PropertyGroup>
<!-- other property settings -->
<DockerfileFastModeStage>debug</DockerfileFastModeStage>
</PropertyGroup>
评论
docker-compose
command: ["/bin/bash", "-c", "echo test"]
tail: invalid number of bytes: 'echo test'
tail
评论
ENTRYPOINT
Dockerfile
ENTRYPOINT ["/bin/sh", "-c"]
CMD ["echo foo"]
sh
"/bin/bash"
ENTRYPOINT ["tail", "-f", "/dev/null"]
command:
command: [echo, test]
ENTRYPOINT ["tail", "-f", "/dev/null"]
command
command: [echo, test]
tail