.NET Core Docker容器中ENTRYPOINT参数自动添加连字符问题
这个错误看起来有点迷惑,但本质上是Docker解析ENTRYPOINT指令和镜像默认配置之间的冲突导致的,我来帮你一步步排查解决:
1. 错误根源分析
你看到的dotnet-Project.name.dll这个奇怪的命令名,说明Docker把dotnet和Project.name.dll当成了一个整体的可执行文件来寻找,而不是把Project.name.dll作为参数传给dotnet命令。这种情况通常有两种诱因:
情况一:镜像默认ENTRYPOINT已经是dotnet
你使用的microsoft/dotnet:2.0.0-sdk-stretch镜像,默认ENTRYPOINT已经设置为["dotnet"]。如果你自己再写ENTRYPOINT ["dotnet", "Project.name.dll"],部分旧版本的Docker或镜像可能会出现解析异常,把两个参数错误拼接成一个命令名。
正确的做法是用CMD代替ENTRYPOINT,让默认的dotnet作为入口,只指定要运行的dll:
CMD ["Project.name.dll"]
情况二:ENTRYPOINT格式错误
虽然你说写法和官方一致,但还是要仔细检查你的Dockerfile:
- 确保是exec格式(方括号包裹,每个参数单独用双引号,逗号分隔):
ENTRYPOINT ["dotnet", "Project.name.dll"] - 不要写成shell格式:
ENTRYPOINT dotnet Project.name.dll(这种格式在某些环境下可能被错误解析) - 不要把两个参数写到一个引号里:
ENTRYPOINT ["dotnet Project.name.dll"](这会让Docker直接寻找名为dotnet Project.name.dll的可执行文件,系统会自动把空格转成连字符来查找)
2. 优化镜像选择(推荐)
2.0.0-sdk-stretch是用于构建.NET Core应用的SDK镜像,体积大且包含很多不必要的构建工具。运行应用建议使用专门的Runtime镜像,比如microsoft/dotnet:2.0.0-aspnetcore-runtime-stretch,它只包含运行ASP.NET Core应用所需的环境,更轻量且更稳定。
3. 确保应用正确发布并复制到容器
一定要确认你已经把发布后的应用文件复制到了容器里:
- 本地先执行发布命令:
dotnet publish -c Release
- 在Dockerfile里指定工作目录并复制发布文件:
WORKDIR /app COPY ./bin/Release/netcoreapp2.0/publish .
(路径根据你的项目结构调整,确保Project.name.dll在/app目录下)
4. 验证容器内的文件
如果还是有问题,可以运行一个临时容器查看文件是否存在:
docker run --rm -it microsoft/dotnet:2.0.0-sdk-stretch /bin/bash
进入容器后,切换到你的工作目录(比如/app),用ls命令查看是否有Project.name.dll文件。
按照上面的步骤调整后,应该就能正常运行你的Web API容器了。
内容的提问来源于stack exchange,提问作者Arkadiusz Kałkus

