When you implement .NET Core module in C#, which reads/writes files, you might run in several permission related issues. For example, your module outputs some configuration file in the output folder of build process. You can do it typically by setting file property in solution explorer to "copy always" or "copy if newer".
This is all fine, but if you build image for Linux containers, your application might (will) fail with following exception, when file is touched:
System.IO.IOException: Permission denied
The reason for this is that your application by default has no permission to read any file copied to output folder. If you run container with bash and list permissions, you will see following:
docker run -it --entrypoint bash IMAGENAME
Then execute following in container to see file permissions:
Here is a typical result:
8 -rwxr-xr-x 1 root root 4530
In my example, I have a Machine Learning model file model.json and want to set extra permissions. The workaround for this issue is to place RUN chmod inside of dockerfile. However the command must be placed before USER moduleuser.
This is dockerfile, which sets correrctly permissions:
FROM microsoft/dotnet:2.0-sdk AS build-env WORKDIR /app COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM microsoft/dotnet:2.0-runtime WORKDIR /app COPY --from=build-env /app/out ./ # Note, this is before USER moduleuser RUN chmod 777 /app/model.json RUN useradd -ms /bin/bash moduleuser USER moduleuser ENTRYPOINT ["dotnet", "xyz.dll"]
This is an example of dockerfile, which will NOT set permissions on file. It will fail with error:
chmod: changing permissions of '/app/model.json': Operation not permitted
FROM microsoft/dotnet:2.0-sdk AS build-env WORKDIR /app COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM microsoft/dotnet:2.0-runtime WORKDIR /app COPY --from=build-env /app/out ./ RUN useradd -ms /bin/bash moduleuser USER moduleuser # This does not work, because it is executing after USER moduleuser RUN chmod 777 /app/model.json ENTRYPOINT ["dotnet", "xyz.dll"]
You can follow this issue on github.