27
votes

All, i'm trying to persistently copy files from my host to an image so those files are available with every container launched based on that image. Running on debian wheezy 64bit as virtualbox guest.

the Dockerfile is fairly simple (installing octave image):

FROM debian:jessie 
MAINTAINER GG_Python <[redacted]@gmail.com>
RUN apt-get update 
RUN apt-get update
RUN apt-get install -y octave octave-image octave-missing-functions octave-nan octave-statistics

RUN mkdir /octave
RUN mkdir /octave/libs
RUN mkdir /octave/libs/jsonlab
COPY ~/octave/jsonlab/loadjson.m /octave/libs/jsonlab/.

I'm getting the following trace after issuing a build command: docker build -t octave .

Sending build context to Docker daemon 423.9 kB
Sending build context to Docker daemon 
Step 0 : FROM debian:jessie
 ---> 58052b122b60
Step 1 : MAINTAINER GG_Python <[..]@gmail.com>
 ---> Using cache
 ---> 90d2dd2f7ee8
Step 2 : RUN apt-get update
 ---> Using cache
 ---> 4c72c25cd829
Step 3 : RUN apt-get update
 ---> Using cache
 ---> b52f0bcb9f86
Step 4 : RUN apt-get install -y octave octave-image octave-missing-functions octave-nan octave-statistics
 ---> Using cache
 ---> f0637ab96d5e
Step 5 : RUN mkdir /octave
 ---> Using cache
 ---> a2d278b2819b
Step 6 : RUN mkdir /octave/libs
 ---> Using cache
 ---> 65efbbe01c99
Step 7 : RUN mkdir /octave/libs/jsonlab
 ---> Using cache
 ---> e41b80901266
Step 8 : COPY ~/octave/jsonlab/loadjson.m /octave/libs/jsonlab/.
INFO[0000] ~/octave/jsonlab/loadjson.m: no such file or directory 

Docker absolutely refuses to copy this file from the host into the image. Needless to say a the file loadjson.m is there (cat displays), all my attempts to change the path (relative, absolute, etc.) failed. Any advice why this simple task is problematic?

5
With the mkdir you can use the -p option to create them all in one go: mkdir -p /octave/libs/jsonlab - dalore
And also the first 3 lines should be combined into one RUN - dalore

5 Answers

22
votes

At the time I originally wrote this, Docker didn’t expand ~ or $HOME. Now it does some expansions inside the build context, but even so they are probably not what you want—they aren’t your home directory outside the context. You need to reference the file explicitly, or package it relative to the Dockerfile itself.

21
votes

Docker can only copy files from the context, the folder you are minus any file listed in the dockerignore file.

When you run 'docker build' docker tars the context and it sends it to the docker daemon you are connected to. It only lets you copy files inside of the context because the daemon might be a remote machine.

8
votes

I couldn't get COPY to work until I understood the context (I was trying to copy a file from outside of the context)

The docker build command builds an image from a Dockerfile and a context. The build’s context is the files at a specified location PATH. The PATH is a directory on your local filesystem.

A context is processed recursively. So, a PATH includes any subdirectories.

The build is run by the Docker daemon, not by the CLI. The first thing a build process does is send the entire context (recursively) to the daemon. In most cases, it’s best to start with an empty directory as context and keep your Dockerfile in that directory. Add only the files needed for building the Dockerfile.

Warning: Do not use your root directory, /, as the PATH as it causes the build to transfer the entire contents of your hard drive to the Docker daemon.

Reference: https://docs.docker.com/engine/reference/builder/#usage

3
votes

I had similar issue. I solved it by checking two things:

  1. Inside your, docker-compose.yaml check context of the service, docker will not copy any file outside of this directory. For example if the context is app/ then you cannot copy anything from ../app

  2. Check .dockerignore to be sure that you are not ignoring the file you want to copy.

0
votes

I got it working by first checking what the context was, setting an absolute path before the source file in your Dockerfile to get that information:

# grep COPY Dockerfile
COPY /path/to/foo   /whatever/path/in/destination/foo

Building with that:

docker build -t bar/foo .

you'll get an error, which states the context-path that Docker is apparently looking into for its files, e.g. it turns out to be:

/var/lib/docker/tmp      # I don't remember

Copying(!) your set of build-files in that directory (here: /var/lib/docker/tmp), cd into it, build from there.

See if that works, and don't forget to do some housekeeping cleaning up the tmp, deleting your files before the next visit(or).

HTH

Michael