我首先使用 root 用户构建我的 dotnet 应用程序来构建我的 docker 镜像。然后为了构建测试目标,我切换到测试用户。我想利用用于 nuget 恢复的 docker 缓存装载类型,以便在我的 runUnitTests.sh 中运行 dotnet 测试时避免重新拉取所有 nuget。这适用于构建和发布目标 (dotnet publish),因为它们都在 root 用户下运行。但是,当我切换到测试用户并且 dotnet 尝试再次恢复时它失败了。
项目结构:
/MyApp.sln (points to below csproj)
/src/app/MyApp.Main/MyApp.Main.csproj
/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj
/src/test/runUnitTests.sh
/src/docker/Dockerfile
Dockerfile(简化):
FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim AS build-env
WORKDIR /appcode
COPY . ./
RUN --mount=type=cache,id=nuget-packages,target=/root/.nuget/packages \
--mount=type=cache,id=nuget-cache,target=/root/.local/share/NuGet/v3-cache \
--mount=type=cache,id=nuget-plugins,target=/root/.local/share/NuGet/plugins-cache \
--mount=type=cache,id=nuget-scratch,target=/tmp/NuGetScratch \
dotnet restore
# Unit Testing
FROM build-env AS unit-test-env
ARG UID=999
RUN useradd -u ${UID} --shell /bin/bash -m test-user \
&& chown -R test-user /appcode/*
USER test-user
WORKDIR /appcode/src/test/MyApp.UnitTests
RUN --mount=type=cache,id=nuget-packages,target=/home/test-user/.nuget/packages \
--mount=type=cache,id=nuget-cache,target=/home/test-user/.local/share/NuGet/v3-cache \
--mount=type=cache,id=nuget-plugins,target=/home/test-user/.local/share/NuGet/plugins-cache \
--mount=type=cache,id=nuget-migrations,target=/home/test-user/.local/share/NuGet/Migrations \
--mount=type=cache,id=nuget-scratch,target=/tmp/NuGetScratch \
dotnet restore
CMD ["/appcode/src/test/runUnitTests.sh"]
错误:
$ docker build -f src/docker/Dockerfile -t my-app:1 --target=unit-test-env --rm .
[+] Building 7.4s (12/12) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 3.18kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim 0.2s
=> [build-env 1/4] FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim@sha256:79042d5b225ec9f40a4144f6a60492aeccf5eea1d47a390e428c736cd368351c 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 101.18kB 0.1s
=> CACHED [build-env 2/4] WORKDIR /appcode 0.0s
=> [build-env 3/4] COPY . ./ 0.2s
=> [build-env 4/4] RUN --mount=type=cache,id=nuget-packages,target=/root/.nuget/packages --mount=type=cache,id=nuget-cache,target=/root/.local/share/NuGet/v3-cache --mount=type=cache,id=nuget-plugins,target 5.0s
=> [unit-test-env 1/4] RUN useradd -u 999 --shell /bin/bash -m test-user && chown -R test-user /appcode/* && chmod -R a+x /appcode/src/deploy/* && mkdir -p /output/report && chown test-user /output && chown test-use 0.6s
=> [unit-test-env 2/4] RUN --mount=type=cache,id=nuget-scratch,target=/tmp/NuGetScratch chown -R test-user /tmp 0.2s
=> [unit-test-env 3/4] WORKDIR /appcode/src/test/MyApp.UnitTests 0.0s
=> ERROR [unit-test-env 4/4] RUN --mount=type=cache,id=nuget-packages,target=/home/test-user/.nuget/packages --mount=type=cache,id=nuget-cache,target=/home/test-user/.local/share/NuGet/v3-cache --mount=type=cach 0.8s
------
> [unit-test-env 4/4] RUN --mount=type=cache,id=nuget-packages,target=/home/test-user/.nuget/packages --mount=type=cache,id=nuget-cache,target=/home/test-user/.local/share/NuGet/v3-cache --mount=type=cache,id=nuget-plugins,target=/home/test-user/.local/share/NuGet/plugins-cache --mount=type=cache,id=nuget-migrations,target=/home/test-user/.local/share/NuGet/Migrations --mount=type=cache,id=nuget-scratch,target=/tmp/NuGetScratch dotnet restore:
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: The "WarnForInvalidProjectsTask" task failed unexpectedly. [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: System.InvalidOperationException: Unable to set permission while creating /tmp/NuGetScratch, errno=1. [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at NuGet.Common.NuGetEnvironment.<GetFolderPath>g__CreateSharedDirectory|6_0(String path) [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at NuGet.Common.NuGetEnvironment.GetFolderPath(NuGetFolderPath folder) [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at NuGet.Common.PathUtility.CheckIfFileSystemIsCaseInsensitive() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at System.Lazy`1.CreateValue() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at System.Lazy`1.get_Value() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at NuGet.Common.PathUtility.get_IsFileSystemCaseInsensitive() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at NuGet.Common.PathUtility.GetStringComparerBasedOnOS() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at NuGet.Build.Tasks.WarnForInvalidProjectsTask.Execute() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
#11 0.815 /usr/share/dotnet/sdk/6.0.406/NuGet.targets(394,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [/appcode/src/test/MyApp.UnitTests/MyApp.UnitTests.csproj]
------
executor failed running [/bin/sh -c dotnet restore]: exit code: 1
我尝试在创建测试用户后将
RUN chown -R test-user /tmp
添加为root。我也试过RUN rm -rf /tmp/NuGetScratch
。都没有用。
我有同样的问题
解决方案
ls -ld /tmp
默认应该是 1777 drwxrwxrwt 注 1 = 粘性位
chmod 1777 /tmp
#or
chmod a+trwx /tmp