microsoft / Windows-Containers

Welcome to our Windows Containers GitHub community! Ask questions, report bugs, and suggest features — let's work together.
MIT License
431 stars 64 forks source link

Docker build issue with server content: COPY --from=...server:10.0.20348.2529 C:/Windows/SystemResources/mfplat.dll.mun... failed to copy files: failed to copy file: open ...Windows\SystemResources\mfplat.dll.mun: Access is denied. #536

Closed doctorpangloss closed 1 week ago

doctorpangloss commented 2 months ago

Describe the bug

Using the server files should work.

Errors like these will sometimes manifest as

failed to copy files: failed to copy directory: unexpected EOF

when one of the source/destinations raises an access denied error.

Minimal reproduction:

COPY --from=mcr.microsoft.com/windows/server:10.0.20348.2529 C:/Windows/SystemResources/mfplat.dll.mun C:/Windows/SystemResources/mfplat.dll.mun failed to copy files: failed to copy file: open \\?\Volume{19443b0d-864a-4f84-9f5d-2db512ad3877}\Windows\SystemResources\mfplat.dll.mun: Access is denied.

To Reproduce

Dockerfile:

FROM mcr.microsoft.com/windows/servercore:10.0.20348.2529 as final
USER ContainerAdministrator
COPY --from=mcr.microsoft.com/windows/server:10.0.20348.2529 C:/Windows/SystemResources/mfplat.dll.mun C:/Windows/SystemResources/mfplat.dll.mun

Expected behavior I should be able to copy this file from the server image.

Configuration:

Server: Docker Desktop 4.32.0 (157355) Engine: Version: 27.0.3 API version: 1.46 (minimum version 1.24) Go version: go1.21.11 Git commit: 662f78c Built: Sat Jun 29 00:02:13 2024 OS/Arch: windows/amd64 Experimental: false

github-actions[bot] commented 2 months ago

Thank you for creating an Issue. Please note that GitHub is not an official channel for Microsoft support requests. To create an official support request, please open a ticket here. Microsoft and the GitHub Community strive to provide a best effort in answering questions and supporting Issues on GitHub.

vagokuln-msft commented 2 months ago

We have investigated the issue and found that the mfplat.dll.mun file is not present in the ServerCore image. The problem you are seeing seems to be related to the inability to write to the directory where you are trying to copy the file.

The security settings on that directory are designed to prevent writes, even from an administrator. This is likely the reason you are encountering the "Access is Denied" error. To proceed, we would need more details on what you are trying to accomplish. This will help us suggest possible alternatives.

Could you please provide more details on why you need to copy the file into that specific directory? This information will help us provide a more tailored solution.

doctorpangloss commented 2 months ago

the purpose of copying files from the server to servercore images is to enable media functionality without the whole server image. For example, to run Photoshop, Unity, Unreal Engine, etc.

vagokuln-msft commented 2 months ago

Thanks for the additional information. Now that I understand your scenario better, I would like to know if you been able to manually copy all the files you need and get your media functionality to work on a ServerCore?

doctorpangloss commented 2 months ago

sometimes. The Unreal Containers folks did this a little bit for Unreal containers but maybe the approach is fundamentally flawed. I was trying to get the libraries I need for opencv in Python to work, but I couldn't, so I just use the server image.

vagokuln-msft commented 2 months ago

Thank you for your feedback. We understand the concern and recommend using the full server SKU for now. We will explore potential solutions to address this issue in the future.

vagokuln-msft commented 1 month ago

Installing Missing Component: ServerMediaFoundation

We have a document about installing optional font packages to Windows containers, which can also be used to install missing components such as ServerMediaFoundation in a Server Core image. The document in question is here: Installing Optional Font Packages. This document outlines how to install the component either from the host's WinSxS folder or using an ISO of the Full Server OS.

Approach 1: Using the WinSxS Folder

Note: The version of the container image and the host OS must match exactly if the WinSxS folder approach is used.

You will need the following files:

Create a Shared User:

net user ShareUser <password> /ADD

Run the following to give access to the Shared User to the WinSxS folder:

net user ShareUser <password> /ADD
net share WinSxS=${env:windir}\WinSxS /grant:ShareUser,READ

Place InstallSMF.cmd and Dockerfile in your application's folder

InstallSMF.cmd:

REM Connect to the WinSxS share on the container host 

for /f "tokens=3 delims=: " %%g in ('netsh interface ip show address ^| findstr /c:"Default Gateway"') do set GATEWAY=%%g

net use o: \\%GATEWAY%\WinSxS /user:ShareUser %SHARE_PW%
if errorlevel 1 goto :eof 

REM Install the ServerMediaFoundation feature 

dism /online /enable-feature /featurename:ServerMediaFoundation /Source:O:\ /LimitAccess 

Dockerfile:

# Use the Windows Server base image 
FROM mcr.microsoft.com/windows/servercore:10.0.20348.2762 
ARG SHARE_PW=
WORKDIR /install 
COPY InstallSMF.cmd . 
RUN InstallSMF.cmd 

# Remaining contents dockerfile ...

Note: My host version and container image version were the same (10.0.20348.2762).

To build the container, use:

docker build -t <newname:tag> --build-arg SHARE_PW=<password> .

Approach 2: Using the ISO that Matches the Container Image Version

You will need the following for this approach:

Create a Shared User:

net user ShareUser <password> /ADD

After you have downloaded the ISO image, run the following script to mount and share the image with the Shared User:

$imagePath = <path to RTM ISO>
Mount-DiskImage -ImagePath $imagePath
# Find the drive letter of the mounted ISO
$driveLetter = <drive letter of mounted ISO>
$repairMountDir = "${env:systemdrive}\repair"
mkdir $repairMountDir
dism /mount-image /imagefile:"$driveLetter\sources\install.wim" /index:1 /mountdir:$repairMountDir
net share RTM=$repairMountDir /grant:ShareUser,READ

Place InstallSMF.cmd and Dockerfile in your application's folder

InstallSMF.cmd:

REM Connect to the shared 'RTM' folder that contains the ISO files 

for /f "tokens=3 delims=: " %%g in ('netsh interface ip show address ^| findstr /c:"Default Gateway"') do set GATEWAY=%%g

net use r: \\%GATEWAY%\RTM /user:ShareUser %SHARE_PW%
if errorlevel 1 goto :eof

REM Install the ServerMediaFoundation feature 

dism /online /enable-feature /featurename:ServerMediaFoundation /Source:R:\ /LimitAccess 

Dockerfile:

# Use the Windows Server base image 
FROM mcr.microsoft.com/windows/servercore:10.0.20348.2762 
ARG SHARE_PW=
WORKDIR /install 
COPY InstallSMF.cmd . 
RUN InstallSMF.cmd 

# Remaining contents dockerfile ...

To build the container, use:

docker build -t <newname:tag> --build-arg SHARE_PW=<password> .