0

I am trying to create a very simple image from scratch to simply provide a file. But Im not a bit skilled writing dockerfiles (on learning queue).

Id like to whenever the container starts, it copy the file from the container into the local host upon the mapped volume, nothing else. Im struggling to get accomplish it, I can build the image fine but I am unable to put the files into local box.

Dockerfile

FROM scratch
ADD datafile.dat /datafile.dat
ADD true /true
VOLUME ["/tmp/"]
COPY datafile.dat /tmp
CMD ["/true"]

'true' is nothing but an echo program. I am build it with

docker build -t datafile:latest -f Dockerfile .

Apparently, build goes fine. But when I try to run it I get nothing, and container exists with error.

$ docker run -dt -v /:/tmp datafile:latest 
0a317b5d7459c86ff260513093d115f94be74671ebc08bc125d9e871a55695c5
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
0a317b5d7459        datafile:latest     "/true"             6 seconds ago       Exited (1) 4 seconds ago                       laughing_keller
$ docker logs 0a3
standard_init_linux.go:195: exec user process caused "no such file or directory"

From building directory

$ ll
total 36
-rw-rw-r--. 1 vUser vUser     0 Aug 23 12:59 datafile.dat
-rw-rw-r--. 1 vUser vUser   126 Aug 23 13:06 Dockerfile
-rwxr-xr-x. 1 vUser vUser 28920 Aug 23 13:05 true
  • can you please do ls of the current directory from where you are executing the Dockerfile and share. execute docker volume ls and check the volume mount – dassum Aug 23 '18 at 18:35
  • added ls output. – atomic-pork-chop Aug 23 '18 at 18:52
  • true displays some text then exits, it is normal, add ; sleep infinity if you do not want that it exits – user2915097 Aug 23 '18 at 18:57
  • `"no such file or directory"` is being thrown because the shell that `/true` is using does not exist in the image. Any commands you try to add in `/true` such as `sleep` will fail because your image is from scratch. – alvits Aug 23 '18 at 19:48
  • @alvits ok I can get rid of that, it was only for testing. do you know if there is any way to copy the file datafile.dat to the mapped volume once I ran the container? within dockerfile definition, obviously. Im looking for a way to only get the files locally whenever then container runs. – atomic-pork-chop Aug 23 '18 at 20:15
  • What’s your actual goal in this? Usually a Docker image has an actual program in it and would actually do something; a simple tar or zip file is probably an easier way to just copy data around. – David Maze Aug 23 '18 at 20:22
  • You can't copy any data into the host directory when it's not empty. The host directory masks the container directory https://docs.docker.com/storage/bind-mounts/#differences-between--v-and---mount-behavior. However, you can replace `CMD` to copy the data from anywhere in the container into the mapped directory. – alvits Aug 23 '18 at 21:17

2 Answers2

0

You can use docker copy command to copy the file from Container to local disk.

docker cp <containerId>:/file/path/within/container /host/path/target

Also you can first try in interactive mode and try to copy the file manually and see what happens. docker run -i --rm -v ${PWD}/tmp:/tmp/ datafile:latest bash

dassum
  • 4,727
  • 2
  • 25
  • 38
0

I ended up creating a very small 'cat like' binary in go and building the image as:

FROM scratch
COPY FILE_I_WANT_TO_SHARE /
COPY catgo /
ENTRYPOINT ["/catgo", "/FILE_I_WANT_TO_SHARE"]

Go code if anyone's interested on that:

package main

import (
    "os"
    "log"
    "io"
)

func readWrite(src io.Reader, dst io.Writer) {
}

func main() {
    if len(os.Args) == 1 {
        _, err := io.Copy(os.Stdout, os.Stdin)
        if err != nil {
            log.Fatal(err)
        }
    } else {
        for _,fname := range os.Args[1:] {
            fh, err := os.Open(fname)
            if err != nil {
                log.Fatal(err)
            }

            _, err = io.Copy(os.Stdout, fh)
            if err != nil {
                log.Fatal(err)
            }
        }
    }
}