Moerwald
Moerwald

Reputation: 11254

Dockerfile: Copy directory from Windows host to docker container

I want to build a Docker image including my custom Powershell modules. Therefore I use Microsofts microsoft/powershell:latest image, from where I wanted to create my own image, that includes my psm1 files.

For simple testing I've the following docker file:

FROM microsoft/powershell:latest
RUN mkdir -p /tmp/powershell
COPY  C:/temp/somedirectory /tmp/powershell

I want to copy the files included in C:\temp\somedirectory to the docker linux container. When building the image I get the following error:

C:\temp\docker_posh> docker build --rm -f Dockerfile -t docker_posh:latest .

Sending build context to Docker daemon 2.048kB

Step 1/3 : FROM microsoft/powershell:latest ---> 9654a0b66645

Step 2/3 : RUN mkdir -p /tmp/powershell ---> Using cache ---> 799972c0dde5

Step 3/3 : COPY C:/temp/somedirectory /tmp/powershell COPY failed: stat /var/lib/docker/tmp/docker-builder566832559/C:/temp/somedirectory: no such file or directory

Of course I know that Docker says that I can't find the file/directory. Therefore I also tried C:/temp/somedirectory/., C:/temp/somedirectory/*, and C:\\temp\\somedirectory\\ as alternativ source paths in the Dockerfile -> Result: none of them worked.

docker version
    Client:
       Version:       17.12.0-ce
       API version:   1.35
       Go version:    go1.9.2
       Git commit:    c97c6d6
       Built: Wed Dec 27 20:05:22 2017
       OS/Arch:       windows/amd64

    Server:
       Engine:
       Version:      17.12.0-ce
       API version:  1.35 (minimum version 1.12)
       Go version:   go1.9.2
       Git commit:   c97c6d6
       Built:        Wed Dec 27 20:12:29 2017
       OS/Arch:      linux/amd64
       Experimental: true

How can I copy a folder including subfolder and files via a Dockerfile?

Upvotes: 6

Views: 23829

Answers (3)

Matt
Matt

Reputation: 365

I found this "feature" very inconvenient and just wrote my own build script that copies everything I cared about into a new temp folder, then builds the docker image in the proper context. Here's a Powershell script for anyone that finds this approach helpful.

Folder structure (feel free to change) looks like this for me:

lib\somefile1.ps1
lib\somefile2.ps1
dockerfolder\Dockerfile
dockerfolder\mybuilderscript.ps1
my-main-file.ps1

Here's the script:

# Docker Image Tag Name
$tagname = "myimage"

#   Generate temp directory
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
$dockerBuildDirectory = New-Item -ItemType Directory -Path (Join-Path $parent $name)

#   Copy things we care about from the parent repo into our build dir

# Copy source folder that has our Dockerfile (and this script) into a folder called "dockerworking" in the temp build directory
Copy-Item -Recurse "../dockerfolder" $dockerBuildDirectory/dockerworking

# Copy directories above our current folder into the dockerworking directory
Copy-Item -Recurse "../lib" $dockerBuildDirectory/dockerworking

# Copy the main script into the working directory
Copy-Item -Recurse "../my-main-file.ps1" $dockerBuildDirectory/dockerworking

# Let the user know where these files are for any troubleshooting that comes up
Write-Host -ForegroundColor Green "Docker files stage at $dockerBuildDirectory"

#   Create the docker image in the "dockerworking" folder where everything resides
docker build --no-cache --tag $tagname $dockerBuildDirectory/dockerworking

The Dockerfile has "local" COPY commands (and all the files are pre-staged to the right location) so Docker is happy.

Dockerfile snippet:

FROM mcr.microsoft.com/windows/servercore:ltsc2019

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]


RUN New-Item -Type Directory -Path "c:\scripts" | Out-Null
COPY "lib" "c:\scripts"
COPY "my-main-file.ps1" "c:\scripts"

ENTRYPOINT ["powershell", "-NoProfile", "-Command", "c:\\scripts\\my-main-file.ps1"]

Upvotes: 1

SushilG
SushilG

Reputation: 731

If you want to copy something from host machine to running docker container then you can use docker cp command like:

docker cp [OPTIONS] CONTAINER_NAME:CONTAINER_SRC_PATH DEST_PATH
docker cp [OPTIONS] SRC_PATH CONTAINER_NAME:CONTAINER_DEST_PATH

Options:

--archive      -a   Archive mode (copy all uid/gid information)
--follow-link  -L   Always follow symbol link in SRC_PATH

If you don't want to use options you can ignore them.

Upvotes: 1

yamenk
yamenk

Reputation: 51768

You cannot copy files that are outside the build context when building a docker image. The build context is the path you specify to the docker build command. In the case of the instruction

C:\temp\docker_posh> docker build --rm -f Dockerfile -t docker_posh:latest .

The . specifies that the build context is C:\temp\docker_posh. Thus C:/temp/somedirectory cannot be accessed. You can either move the Dockerfile to temp, or run the same build command under C:\temp. But remember to fix the Dockerfile instructions to make the path relative to the build context.

Upvotes: 15

Related Questions