Docker: adding a file from a parent directory

Docker

Docker Problem Overview


In my Dockerfile I've got :

ADD ../../myapp.war /opt/tomcat7/webapps/

That file exists as ls ../../myapp.war returns me the correct file but when I execute sudo docker build -t myapp . I've got :

Step 1 : ADD ../../myapp.war /opt/tomcat7/webapps/
2014/07/02 19:18:09 ../../myapp.war: no such file or directory

Does somebody know why and how to do it correctly?

Docker Solutions


Solution 1 - Docker

You can build the Dockerfile from the parent directory:

docker build -t <some tag> -f <dir/dir/Dockerfile> .

Solution 2 - Docker

With docker-compose, you could set context folder:

# docker-compose.yml

version: '3.3'    
services:
  yourservice:
    build:
      context: ./
      dockerfile: ./docker/yourservice/Dockerfile

Solution 3 - Docker

Unfortunately, (for practical and security reasons I guess), if you want to add/copy local content, it must be located under the same root path than the Dockerfile.

From the documentation:

> The <src> path must be inside the context of the build; you > cannot ADD ../something/something, because the first step of a docker > build is to send the context directory (and subdirectories) to the > docker daemon.

EDIT: There's now an option (-f) to set the path of your Dockerfile ; it can be used to achieve what you want, see @Boedy 's response.

Solution 4 - Docker

Adding some code snippets to support the accepted answer.

Directory structure :

setup/
 |__docker/DockerFile
 |__target/scripts/<myscripts.sh>
src/
 |__<my source files>

Docker file entry:

RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/scripts/
RUN mkdir -p /home/vagrant/dockerws/chatServerInstaller/src/
WORKDIR /home/vagrant/dockerws/chatServerInstaller

#Copy all the required files from host's file system to the container file system.
COPY setup/target/scripts/install_x.sh scripts/
COPY setup/target/scripts/install_y.sh scripts/
COPY src/ src/

Command used to build the docker image

docker build -t test:latest -f setup/docker/Dockerfile .

Solution 5 - Docker

Since -f caused another problem, I developed another solution.

  • Create a base image in the parent folder
  • Added the required files.
  • Used this image as a base image for the project which in a descendant folder.

The -f flag does not solved my problem because my onbuild image looks for a file in a folder and had to call like this:

-f foo/bar/Dockerfile foo/bar

instead of

-f foo/bar/Dockerfile .

Also note that this is only solution for some cases as -f flag

Solution 6 - Docker

The solution for those who use composer is to use a volume pointing to the parent folder:

#docker-composer.yml

foo:
  build: foo
  volumes:
    - ./:/src/:ro

But I'm pretty sure the can be done playing with volumes in Dockerfile.

Solution 7 - Docker

If you are using skaffold, use 'context:' to specify context location for each image dockerfile - context: ../../../

			apiVersion: skaffold/v2beta4
			kind: Config
			metadata:
				name: frontend
			build:
				artifacts:
					- image: nginx-angular-ui
					  context: ../../../
					  sync:
						  # A local build will update dist and sync it to the container
						  manual:
							  - src: './dist/apps'
								dest: '/usr/share/nginx/html'
					  docker:
						  dockerfile: ./tools/pipelines/dockerfile/nginx.dev.dockerfile
					- image: webapi/image
					  context: ../../../../api/
					  docker:
						  dockerfile: ./dockerfile
			deploy:
				kubectl:
					manifests:
						- ./.k8s/*.yml

skaffold run -f ./skaffold.yaml

Solution 8 - Docker

  • build the img from an upper dir

  • name the img

  • enable proper volume sharing

  • check the Makefile in the link above on how-to start the container ...

    docker build . -t proj-devops-img --no-cache --build-arg UID=$(shell id -u) --build-arg GID=$(shell id -g) -f src/docker/devops/Dockerfile
    

Solution 9 - Docker

Let's say you have your directories tree like this:

dir0
├───dir1
│   └───dir11
|   |   └───dockerfile
|   └───dir12 (current)
└───dir2 (content to be copied)

and your dockerfile look like this:

FROM baseImage
COPY / /content

Let's say you want to copy dir2 content into a new docker image using COPY or ADD of dockerfile that is in dir11 and your current directory is dir12

You will have to run this command in order to build your image properly:

docker build -t image-name:tag -f ../dir11/dockerfile ../../dir2
  • -t your-image-name Name and optionally a tag in the 'name:tag' format
  • -f ../dir11/dockerfile Name of the Dockerfile (Default is 'PATH/Dockerfile')
  • ../../dir2 path to be current for COPY or ADD commands

Update

Let's say you run this by mistake:

docker build -t image-name:tag -f ../dir11/dockerfile ../../

This will not solve your problem because in this case the COPY / /content will look like it's copying dir0 content (dir1 & dir2) so in order to fix that you can either change the command using the right path or you can also change the COPY source path in the dockerfile like this:

COPY /dir2 /content

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnthony O.View Question on Stackoverflow
Solution 1 - DockerBoedyView Answer on Stackoverflow
Solution 2 - DockerNikita KuznetsovView Answer on Stackoverflow
Solution 3 - DockermbarthelemyView Answer on Stackoverflow
Solution 4 - DockerBinita BharatiView Answer on Stackoverflow
Solution 5 - DockerguneysusView Answer on Stackoverflow
Solution 6 - DockerwikierView Answer on Stackoverflow
Solution 7 - DockerSukhminder SandhuView Answer on Stackoverflow
Solution 8 - DockerYordan GeorgievView Answer on Stackoverflow
Solution 9 - DockerAffes SalemView Answer on Stackoverflow