Tin Ng
Tin Ng

Reputation: 1047

docker copy file from one container to another?

Here is what I want to do:

  1. docker-compose build
  2. docker-compose $COMPOSE_ARGS run --rm task1
  3. docker-compose $COMPOSE_ARGS run --rm task2
  4. docker-compose $COMPOSE_ARGS run --rm combine-both-task2
  5. docker-compose $COMPOSE_ARGS run --rm selenium-test

And a docker-compose.yml that looks like this:

task1:
  build: ./task1
  volumes_from:
    - task1_output
  command: ./task1.sh

task1_output:
  image: alpine:3.3
  volumes:
    - /root/app/dist
  command: /bin/sh

# essentially I want to copy task1 output into task2 because they each use different images and use different tech stacks... 
task2:
  build: ../task2
  volumes_from:
    - task2_output
    - task1_output:ro
  command: /bin/bash -cx "mkdir -p task1 && cp -R /root/app/dist/* ."

So now all the required files are in task2 container... how would I start up a web server and expose a port with the content in task2?

I am stuck here... how do I access the stuff from task2_output in my combine-tasks/Dockerfile:

combine-both-task2:
  build: ../combine-tasks
  volumes_from:
     - task2_output

Upvotes: 18

Views: 42206

Answers (2)

Saman Salehi
Saman Salehi

Reputation: 1034

For me the best way to copy file from or to container is using docker cp for example: If you want copy schema.xml from apacheNutch container to solr container then:

  1. docker cp apacheNutch:/root/nutch/conf/schema.xml /tmp/schema.xml server/solr/configsets/nutch/

  2. docker cp /tmp/schema.xml solr:/opt/solr-8.1.1/server/solr/configsets/nutch/conf

Upvotes: 4

Jett Jones
Jett Jones

Reputation: 452

In recent versions of docker, named volumes replace data containers as the easy way to share data between containers.

docker volume create --name myshare
docker run -v myshare:/shared task1
docker run -v myshare:/shared -p 8080:8080 task2
...

Those commands will set up one local volume, and the -v myshare:/shared argument will make that share available as the folder /shared inside each of each container.

To express that in a compose file:

version: '2'
services:
  task1:
    build: ./task1
  volumes:
    - 'myshare:/shared'

  task2:
    build: ./task2
  ports:
    - '8080:8080'
  volumes:
    - 'myshare:/shared'

volumes:
  myshare:
    driver: local 

To test this out, I made a small project:

- docker-compose.yml (above)
- task1/Dockerfile
- task1/app.py
- task2/Dockerfile

I used node's http-server as task2/Dockerfile:

FROM node
RUN npm install -g http-server
WORKDIR /shared
CMD http-server

and task1/Dockerfile used python:alpine, to show two different stacks writing and reading.

FROM python:alpine
WORKDIR /app
COPY . .
CMD python app.py

here's task1/app.py

import time

count = 0
while True:
  fname = '/shared/{}.txt'.format(count)
  with open(fname, 'w') as f:
    f.write('content {}'.format(count))
    count = count + 1
  time.sleep(10)

Take those four files, and run them via docker compose up in the directory with docker-compose.yml - then visit $DOCKER_HOST:8080 to see a steadily updated list of files.

Also, I'm using docker version 1.12.0 and compose version 1.8.0 but this should work for a few versions back.

And be sure to check out the docker docs for details I've probably missed here:
https://docs.docker.com/engine/tutorials/dockervolumes/

Upvotes: 26

Related Questions