74

I need to pipe (inject) a file or some data into docker as part of the run command and have it written to a file within the container as part of the startup. Is there best practise way to do this ?

I've tried this.

cat data.txt |  docker run -a stdin -a stdout -i -t ubuntu /bin/bash -c 'cat >/data.txt'

But can't seem to get it to work.

user1513388
  • 7,165
  • 14
  • 69
  • 111
  • Does this file have to be injected at run time? Can you build it into the image? Alternatively, can you prepare the file in advance and then mount the file/folder from the host to the container? – Xiongbing Jin Feb 28 '16 at 21:26
  • Yes - to add a bit more colour, the file is actually a crypto key that is retrieved from an API and I was hoping to inject into the container so that's it's only available to the containers file system. – user1513388 Feb 29 '16 at 16:23
  • cat setup.json | docker run -a stdin -a stdout -i ubuntu /bin/bash -c 'cat' Works for me. Drop the -t. – jamie Jul 21 '16 at 18:22

2 Answers2

111
cat setup.json |  docker run -i  ubuntu /bin/bash -c 'cat'

This worked for me. Remove the -t. Don't need the -a's either.

jamie
  • 2,963
  • 1
  • 26
  • 27
  • 5
    Because of the default entrypoint, `cat setup.json | docker run -i ubuntu cat` will work in many cases – Zero Jan 20 '17 at 22:05
  • 9
    Note, docker-compose automatically allocates TTY. So with docker compose `cat setup.json | docker-compose exec -T myservice sh -c "echo"` where `-T` disables automatic TTY allocation. – Eric H. Aug 24 '18 at 15:46
  • I need to pipe to an application and redirect its output to a file: `cat file1 | docker run -i my-docker-image bash -c 'my-app > file2'` but it doesn't work. I needed to use `docker exec`: `docker run -i -d my-docker-image` and `cat file1 | docker exec -i my-docker-container bash -c 'my-app > file2'` – Jeff Pal Nov 04 '21 at 12:34
  • I noticed that the pipe and redirect bash commands don't work in `docker run`, but they work in `docker exec`. – Jeff Pal Nov 04 '21 at 13:28
  • This was helpful to be able to use run and not exec. `cat mybash.sh | docker run -i myimage script` then the entrypoint has a case statement with `script) cat | /bin/bash -l ;;` Now I can easily send any host script to run on the container in a login shell! Thx. – DKebler Apr 12 '23 at 21:12
-10

The better solution is to make (mount) you host folder be accessible to docker container. E.g. like this

docker run -v /Users/<path>:/<container path> ... 

Here is /Users/<path> is a folder on your host computer and <container path> mounted path inside container.

Also see Manage data in containers manual page.

UPDATE another Accessing External Files from Docker Containers example.

Andriy Kryvtsun
  • 3,220
  • 3
  • 27
  • 41
  • Is it possible to mount a filesystem that's only available to a specific container ? – user1513388 Feb 29 '16 at 16:24
  • @user1513388 sure. in your case it can looks like `docker run -v data.txt:/data.txt -t ubuntu /bin/bash` in the first call and `docker run -v data2.txt:/data2.txt -t ubuntu /bin/bash` in the second call for the same `ubuntu` image – Andriy Kryvtsun Feb 29 '16 at 16:31
  • Thanks for the update. Is it actually possible to pass data in via STDIN and have that written to a file within the container ? – user1513388 Feb 29 '16 at 19:52
  • So this works but I have to run it after the containers already started, ideally I would like to do it before the container starts. `cat data.txt | docker exec -i ubuntu sh -c 'cat >/data.txt'` – user1513388 Feb 29 '16 at 20:56
  • @user1513388 can you explain what result do you want to reach? I can't clearly understand your task. Exact effect from your last comment with STDIN example is reachable with `-v` mounting from my example. Frankly, I can't understand what is not suitable for you :( – Andriy Kryvtsun Feb 29 '16 at 21:11
  • I believe that mounted files/volumes are available before the startup script is run. Assuming that your startup script is already defined in the Dockerfile in the CMD section, you can just use `docker run -v host_path/data.txt:container_path/data.txt ubuntu`, or if you are running the script manually, use `docker run -v host_path/data.txt:container_path/data.txt ubuntu script` – Xiongbing Jin Feb 29 '16 at 23:58
  • @Andriy Kryvtsun This is what I'm trying to achieve. I need is to call an api to retrieve a cryptographic key without writing it to a file (for security reasons), then pass that key to docker and make it available only to that container so it can be read by an application running in the container. The key needs to be in place before the application starts. – user1513388 Mar 01 '16 at 00:33
  • @user1513388 I understood you. There is no well known standard way to do this. [Here is](https://github.com/docker/docker/issues/13490) good review of existing solutions. Using passing to a docker container in runtime env. variables (instead of using pipes) is the best and simplest option for now. – Andriy Kryvtsun Mar 01 '16 at 01:56
  • @Andriy Kryvtsun - Thanks I'll take a look at this. – user1513388 Mar 01 '16 at 17:17