6

アルパイン コンテナーで .Net コア アプリをコンパイルしているカスタム Dockerfile で奇妙な問題が発生しています。

さまざまな構成を試してみましたが、役に立ちませんでした。最終的な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 対 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 .も同じ結果が得られます。

4

1 に答える 1

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

最初の|| trueCI ビルドにはイメージが存在しないため、パーツが存在します。このレシピの「魔法のソース」はdocker build --target <intermediate-stage-name>docker build --cache-from <intermediate-stage-name>.

キャッシュを機能させるために、中間ステージを明示的にビルドしてプッシュする必要がある理由を説明できません。中間ステージとそのレイヤーではなく、最終イメージのみがプッシュされることについてのいくつかのハンドウェーブを除きます。しかし、それは私にとってはうまくいきました – 私はここからこの「トリック」を学びました: https://pythonspeed.com/articles/faster-multi-stage-builds/

于 2021-05-13T11:14:34.973 に答える