如何从Docker容器内复制文件到主机及外部服务器?
在Docker容器内通过GitHub Actions复制文件到外部SMB服务器的权限问题解决方法
问题背景
使用.NET Framework SDK Docker镜像在GitHub Actions中构建项目发布版本时,容器内执行Copy-Item命令复制文件到外部SMB共享服务器时出现权限拒绝错误:
Copy-Item : Access is denied At C:\actions-runner\_work\_temp\58a0d5f5-1c21-468a-9cc1-6add157ef7da.ps1:2 char:1 + Copy-Item -Path "./ReleaseFolder*" -Destination "\\SERVERNAME\Destination" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Copy-Item], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.CopyItemCommand
已尝试关闭防火墙、使用服务器IP、host.docker.internal、卷挂载(不适用)等方法,均未解决。
可行解决方案
1. 显式认证SMB共享
容器内默认用户无外部SMB共享访问权限,需先通过账号密码建立SMB映射再复制:
# 建立SMB映射(替换为实际认证信息) New-SmbMapping -LocalPath "Z:" -RemotePath "\\192.168.0.1\Destination" -UserName "DOMAIN\YourUser" -Password "${{ secrets.SMB_PASSWORD }}" # 复制文件到映射盘符 Copy-Item -Path "./ReleaseFolder*" -Destination "Z:\" -Recurse -Force -PassThru # 清理映射(可选) Remove-SmbMapping -LocalPath "Z:" -Force
注意:GitHub Actions中务必用
secrets存储密码,避免明文泄露。
2. 使用主机网络模式运行容器
Windows Docker容器支持host网络模式,容器将直接使用主机网络栈,继承主机对外部共享的访问权限。在GitHub Actions步骤中配置:
- name: Build and copy to external server uses: docker://mcr.microsoft.com/dotnet/framework/sdk:4.8 with: args: | powershell -Command " # 这里放你的项目构建命令 dotnet publish -c Release; Copy-Item -Path './ReleaseFolder*' -Destination '\\SERVERNAME\Destination' -Recurse -Force -PassThru " options: network: host
3. 先将文件同步到主机,再从主机推送
通过卷挂载将容器内的发布目录同步到主机临时目录,再在主机层面执行复制命令(利用主机权限访问外部共享):
- name: Create host temp directory run: mkdir -p ${{ runner.temp }}\release-files shell: powershell - name: Build and sync to host uses: docker://mcr.microsoft.com/dotnet/framework/sdk:4.8 with: args: | powershell -Command " # 执行构建命令 dotnet publish -c Release -o ./ReleaseFolder; # 复制到容器内挂载的目录 Copy-Item -Path './ReleaseFolder*' -Destination 'C:\host-mount' -Recurse -Force -PassThru " volumes: - ${{ runner.temp }}\release-files:C:\host-mount - name: Push to external server from host run: | Copy-Item -Path "${{ runner.temp }}\release-files\*" -Destination "\\SERVERNAME\Destination" -Recurse -Force -PassThru shell: powershell
4. 以管理员身份执行复制命令
尝试在容器内提升权限执行Copy-Item:
Start-Process powershell -ArgumentList "Copy-Item -Path './ReleaseFolder*' -Destination '\\192.168.0.1\Destination' -Recurse -Force -PassThru" -Verb RunAs -Wait
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

