Reputation: 24477
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?
Upvotes: 573
Views: 545503
Reputation: 3902
If using docker-compose.yml, there is additional_contexts
in the API that we can use to take resources from a parent folder outside the main context.
https://docs.docker.com/compose/compose-file/build/#additional_contexts
Here is how it works:
# docker-compose.yml
version: '3.3'
services:
my_service:
build:
context: ./
additional_contexts:
assets: ../../assets
dockerfile: ./docker/my_service/Dockerfile
# Dockerfile
...
COPY --from=assets . /app/assets
...
Upvotes: 19
Reputation: 764
As some others have pointed out, you could use context: ../
, here is a full example:
Directory structure
.
├── docker
│ ├── Dockerfile
│ └── docker-compose.yaml
└── go.mod
docker-compose.yaml
version: '3.1'
services:
golang:
build:
context: ../
dockerfile: docker/Dockerfile
ports:
- '80:80'
Dockerfile
FROM golang:1.18.3
WORKDIR /app
COPY . .
# RUN some-stuff
And then from the root directory run:
docker-compose -f docker/docker-compose.yaml up --build
Upvotes: 1
Reputation: 917
--if this is still relevant--
As alternative:
You can now use --build-context
with Dockerfile 1.4. This allows you to reference directories outside of the Dockerfile location.
docker build -t myapp --build-context root=../../ .
and then COPY --from=root myapp.war /opt/tomcat7/webapps/
Upvotes: 6
Reputation: 12913
Unfortunately, (for practical and security reasons I guess), if you want to add/copy local content, it must be located at the same level in the directory tree as 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.
Upvotes: 204
Reputation: 3508
In May 2022, Docker announced it added the --build-context flag to the docker build
command.
For your example, you can run your build command like this:
docker build --build-context myapp=../.. .
And your Dockerfile can reference that context with any commands that support the --from option
# Dockerfile
COPY --from=myapp myapp.war /opt/tomcat7/webapps/
Upvotes: 22
Reputation: 18585
You should not do this bcs the idea is for the build to be portable but if you must:
Instruct Docker to set context:
to the parent folder. For example if you have a Documents
parent folder with /ssl
and /my-proj
subfolders you could instruct Docker to copy ssl files to the container like this:
This Docker compose file would be at Documents/my-proj/compose.yaml
.
nginx:
build:
context: ../
dockerfile_inline: |
FROM nginx:latest
WORKDIR /etc/nginx
COPY /ssl/example.com/certificate.crt ssl/
COPY /ssl/example.com/private.key ssl/
container_name: nginx
restart: unless-stopped
ports: [80:80,443:443,59840:59840]
volumes:
- $NGINX_CONF_FILEPATH:/etc/nginx/conf.d/default.conf
Upvotes: 2
Reputation: 624
Given the following setup:
+ parent
+ service1
- some_file.json
+ service2
- Dockerfile
If you have a Dockerfile in service2
and want to copy some_file.json
from service1
, you can run this inside the service2 directory:
docker build -t my_image ../ --file Dockerfile
This will set the target context one level above. The tricky part here is that the target Dockerfile is set explicitly (as it is not in the target context).
In service2/Dockerfile
, you must issue the COPY
command as if the file were one level above:
COPY service1/some_file.json /target/location/some_file.json
instead of
COPY ../service1/some_file.json /target/location/some_file.json # will not work
Upvotes: 13
Reputation: 109
Let setting context: ../../ in parent folder in docker-compose.yml
Ex:
app:
build:
context: ../../
dockerfile: ./source/docker/dockerfile/Dockerfile
Upvotes: 10
Reputation: 7783
cd
to your parent directory insteaddocker build -t <some tag> -f <dir/dir/Dockerfile> .
In this case, the context of the docker will be switched to the parent directory and accessible for ADD and COPY
Upvotes: 658
Reputation: 2987
With docker-compose, you could set context folder:
# docker-compose.yml
version: '3.3'
services:
yourservice:
build:
context: ./
dockerfile: ./docker/yourservice/Dockerfile
Upvotes: 290
Reputation: 1649
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 commandsLet'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
Upvotes: 4
Reputation: 5460
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
Upvotes: 1
Reputation: 915
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
Upvotes: 2
Reputation: 2576
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.
Upvotes: 0
Reputation: 5918
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 .
Upvotes: 50
Reputation: 6502
Since -f
caused another problem, I developed another solution.
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
Upvotes: 18