我的自定义Dockerfile遇到一些奇怪的问题,在高山容器中编译了.Net核心应用。
我尝试了许多不同的配置,但都无济于事-当我执行最后的FROM
指令时,缓存总是无效的(如果我对此进行了注释以及其下的所有内容,缓存都可以正常工作)。这是文件:
FROM microsoft/dotnet:2.1-sdk-alpine3.7 AS build
ARG ASPNETCORE_ENVIRONMENT=development
ARG ASPNET_CONFIGURATION=Debug
ARG PROJECT_DIR=src/API/
ARG PROJECT_NAME=MyAPI
ARG SOLUTION_NAME=MySolution
RUN export
WORKDIR /source
COPY ./*.sln ./nuget.config ./
# Copy source project files
COPY src/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done
# # Copy test project files
COPY test/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p test/${file%.*}/ && mv $file test/${file%.*}/; done
RUN dotnet restore
COPY . ./
RUN for dir in test/*.Tests/; do (cd "$dir" && dotnet test --filter TestType!=Integration); done
WORKDIR /source/${PROJECT_DIR}
RUN dotnet build ${PROJECT_NAME}.csproj -c $ASPNET_CONFIGURATION -o /app
RUN dotnet publish ${PROJECT_NAME}.csproj -c $ASPNET_CONFIGURATION -o /app --no-restore
FROM microsoft/dotnet:2.1-aspnetcore-runtime-alpine3.7
ARG ASPNETCORE_ENVIRONMENT=development
RUN export
COPY --from=build /app .
WORKDIR /app
EXPOSE 80
VOLUME /app/logs
ENTRYPOINT ["dotnet", "MyAssembly.dll"]
有什么想法吗?提示?提示?明显的错误?我已经检查了每一层,并且COPY . ./
指令仅复制了我期望的文件-并且在构建之间它们都没有改变。
还值得注意的是,如果我删除最后一条FROM指令(和其他相关行),则缓存可以完美运行-但最终图像大小显然比基础microsoft/dotnet:2.1-aspnetcore-runtime-alpine3.7
(172Mb vs 1.8Gb)大得多。 。我尝试仅在COPY
之后注释掉FROM
指令,但是它不会影响缓存失效。预期效果如下:
FROM microsoft/dotnet:2.1-sdk-alpine3.7 AS build
ARG ASPNETCORE_ENVIRONMENT=development
ARG ASPNET_CONFIGURATION=Debug
ARG PROJECT_DIR=src/API/
ARG PROJECT_NAME=MyAPI
ARG SOLUTION_NAME=MySolution
RUN export
WORKDIR /source
COPY ./*.sln ./nuget.config ./
# Copy source project files
COPY src/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p src/${file%.*}/ && mv $file src/${file%.*}/; done
# # Copy test project files
COPY test/*/*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p test/${file%.*}/ && mv $file test/${file%.*}/; done
RUN dotnet restore
COPY . ./
RUN for dir in test/*.Tests/; do (cd "$dir" && dotnet test --filter TestType!=Integration); done
WORKDIR /source/${PROJECT_DIR}
RUN dotnet build ${PROJECT_NAME}.csproj -c $ASPNET_CONFIGURATION -o /app
RUN dotnet publish ${PROJECT_NAME}.csproj -c $ASPNET_CONFIGURATION -o /app --no-restore
WORKDIR /app
EXPOSE 80
VOLUME /app/logs
ENTRYPOINT ["dotnet", "MyAssembly.dll"]
.dockerignore下面:
base-images/
docker-compose.yml
docker-compose.*.yml
VERSION
**/.*
**/*.ps1
**/*.DotSettings
**/*.csproj.user
**/*.md
**/*.log
**/*.sh
**/Dockerfile
**/bin
**/obj
**/node_modules
**/.vs
**/.vscode
**/dist
**/packages/
**/wwwroot/
最后一点信息:我正在使用docker-compose构建容器-特别是通过运行docker-compose build myservicename
来构建容器,但是使用docker build -f src/MyAssembly/Dockerfile -t MyImageName .
构建图像会产生相同的结果。
答案 0 :(得分:0)
如果您在本地构建并且缓存不起作用 – 那么我不知道问题是什么:)
但是,如果您将构建作为 CI 的一部分,那么问题可能在于您需要明确地拉取、构建和推送中间阶段:
> docker pull MyImageName:build || true
> docker pull MyImageName:latest || true
> docker build --target build --tag MyImageName:build .
> docker build --cache-from MyImageName:build --tag MyImageName:latest .
> docker push MyImageName:build
> docker push MyImageName:latest
存在 || true
部分是因为图像不会在初始 CI 构建中出现。这个食谱的“魔法酱”是docker build --target <intermediate-stage-name>
和docker build --cache-from <intermediate-stage-name>
。
我无法解释为什么需要明确地构建和推送中间阶段才能使缓存工作 - 除了一些关于仅推送最终图像而不是中间阶段及其层的问题。但它对我有用——我从这里学到了这个“技巧”:https://pythonspeed.com/articles/faster-multi-stage-builds/