Docker: COPY failed: file not found in build context (Dockerfile)
Asked Answered
S

12

51

I'd like to instruct Docker to COPY my certificates from the local /etc/ folder on my Ubuntu machine.

I get the error:

COPY failed: file not found in build context or excluded by .dockerignore: stat etc/.auth_keys/fullchain.pem: file does not exist

I have not excluded in .dockerignore

How can I do it?

Dockerfile:

FROM nginx:1.21.3-alpine

RUN rm /etc/nginx/conf.d/default.conf
RUN mkdir /etc/nginx/ssl
COPY nginx.conf /etc/nginx/conf.d
COPY ./etc/.auth_keys/fullchain.pem /etc/nginx/ssl/
COPY ./etc/.auth_keys/privkey.pem /etc/nginx/ssl/

WORKDIR /usr/src/app

I have also tried without the dot --> same error

COPY /etc/.auth_keys/fullchain.pem /etc/nginx/ssl/
COPY /etc/.auth_keys/privkey.pem /etc/nginx/ssl/

By placing the folder .auth_keys next to the Dockerfile --> works, but not desireable

COPY /.auth_keys/fullchain.pem /etc/nginx/ssl/
COPY /.auth_keys/privkey.pem /etc/nginx/ssl/
Sheasheaf answered 5/11, 2021 at 11:35 Comment(4)
You can only COPY files that are located within your local source tree; you'll need to cp the files outside Docker space. How to include files outside of Docker's build context? discusses this further, though it's impractical to pass the entire host filesystem as the build context.Morty
For the particular case of private keys, you shouldn't COPY them into an image, though, since they can be very easily copied back out. The docker run -v option or Compose volumes: can inject arbitrary host content into a container and isn't subject to COPY's path restrictions.Morty
Thanks, very useful and concise answer, May I please ask what a common solution is, to safety handle those keys in a production environment (by a separate script?)Sheasheaf
In my case, I was just overworked and didn't realize that what I'm trying to copy doesn't exist on the host. COPY filexyz /src/filexyz Now, my current working directory on host didn't have any filexyz file so it failed.Hodgkinson
M
44

The docker context is the directory the Dockerfile is located in. If you want to build an image that is one of the restrictions you have to face.

In this documentation you can see how contexts can be switched, but to keep it simple just consider the same directory to be the context. Note; this also doesn't work with symbolic links.

So your observation was correct and you need to place the files you need to copy in the same directory.

Alternatively, if you don't need to copy them but still have them available at runtime you could opt for a mount. I can imagine this not working in your case because you likely need the files at startup of the container.

Maypole answered 5/11, 2021 at 11:42 Comment(1)
Bind-mounted files will be available at container startup (when the ENTRYPOINT/CMD runs) but not before (during RUN steps). For keys used to sign and encrypt TLS network traffic this is probably fine.Morty
N
17

@JustLudo's answer is correct, in this case. However, for those who have the correct files in the build directory and still seeing this issue; remove any trailing comments.

Coming from a C and javascript background, one may be forgiven for assuming that trailing comments are ignored (e.g. COPY my_file /etc/important/ # very important!), but they are not! The error message won't point this out, as of my version of docker (20.10.11).

For example, the above erroneous line will give an error:

COPY failed: file not found in build context or excluded by .dockerignore: stat etc/important/: file does not exist

... i.e. no mention that it is the trailing # important! that is tripping things up.

Negrophobe answered 21/12, 2021 at 14:57 Comment(0)
V
17

It's also important to note that, as mentioned into the docs:

If you use STDIN or specify a URL pointing to a plain text file, the system places the contents into a file called Dockerfile, and any -f, --file option is ignored. In this scenario, there is no context.

That is, if you're running build like this:

docker build -t dh/myimage - < Dockerfile_test

Any COPY or ADD, having no context, will throw the error mentioned or another similar:

failed to compute cache key: "xyz" not found: not found

If you face this error and you're piping your Dockerfile, then I advise to use -f to target a custom Dockerfile.

docker build -t dh/myimage -f Dockerfile_test .

(. set the context to the current directory)


Here is a test you can do yourself :

  1. In an empty directory, create a Dockerfile_test file, with this content
FROM nginx:1.21.3-alpine
COPY test_file /my_test_file
  1. Then create a dummy file:
touch test_file
  1. Run build piping the test Dockerfile, see how it fails because it has no context:
docker build -t dh/myimage - < Dockerfile_test
[..]
failed to compute cache key: "/test_file" not found: not found
[..]
  1. Now run build with -f, see how the same Dockerfile works because it has context:
docker build -t dh/myimage -f Dockerfile_test .
[..]
 => [2/2] COPY test_file /my_test_file
 => exporting to image
[..]
Villeinage answered 27/7, 2022 at 20:12 Comment(1)
I had this problem because I was building using STDIN thank you for the insightBabbittry
T
2

Let me share my solution

Here is the outline of my project

├-app
 ├── Dockerfile
 ├── pom.xml
 ├── src

Now my docker command was to be fired from a directory outside of app and not inside app folder. So this is what worked for me

docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f app/Dockerfile app

Note the context which is generally specified as "." was now replaced with the "app" folder.

Thimble answered 5/4, 2023 at 9:9 Comment(0)
K
1

FWIW this same error shows up when running gcloud builds submit if the files are included in .gitignore

Kalasky answered 7/2, 2023 at 20:41 Comment(0)
E
0

Check your docker-compos.yml, it might be changing the context directory.

I had a similar problem, with the only clarification: I was running Dockerfile with docker-compos.yml

This is what my Dockerfile looked like when I got the error:

FROM alpine:3.17.0
ARG DB_NAME \
    DB_USER \
    DB_PASS
RUN apk update && apk upgrade && apk add --no-cache \
    php \
    ...
EXPOSE 9000
COPY ./conf/www.conf /etc/php/7.3/fpm/pool.d   #<--- an error was here
COPY ./tools /var/www/                         #<--- and here
ENTRYPOINT ["sh", "/var/www/start.sh"]

This is part of my docker-compose.yml where I described my service.

wordpress:
container_name: wordpress
build:
  context: .          #<--- the problem was here
  dockerfile: requirements/wordpress/Dockerfile
  args:
    DB_NAME: ${DB_NAME}
    DB_USER: ${DB_USER}
    DB_PASS: ${DB_PASS}
ports:
  - "9000:9000"
depends_on:
  - mariadb
restart: unless-stopped
networks:
  - inception
volumes:
  - wp:/var/www/

My docker-compos.yml was changing the context directory. Then I wrote a new path in the Dockerfile and it all worked.

COPY ./requirements/wordpress/conf/www.conf /etc/php/7.3/fpm/pool.d
COPY ./requirements/wordpress/tools /var/www/

project structure

Esmond answered 4/2, 2023 at 21:33 Comment(0)
C
0

Have you tried doing a simlink with ln -s to the /etc/certs/ folder in the docker build directory?

Alternatively you could have one image that has the certificates and in your image you just COPY FROM the docker image having the certs.

Carlie answered 7/2, 2023 at 20:48 Comment(0)
H
0

In my case was same error:

ERROR: Service 'php' failed to build: COPY failed: file not found in build context or excluded by .dockerignore: stat src/: file does not exist

I had: docker-compose.yml

version: '3'
services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./src:/var/www/html
    ports:
      - 8080:80
    depends_on:
      - mysql
  mysql:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: my_db_root_pass
      MYSQL_DATABASE: my_db
      MYSQL_USER: my_db_user
      MYSQL_PASSWORD: my_db_pass
    volumes:
      - mysql_data:/var/lib/mysql
volumes:
  mysql_data:

and Dockerfile

FROM php:7.4-apache
COPY src/ /var/www/html/

When I created a src folder and then added an index.php file to the src folder for example

<!DOCTYPE>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Docker</title>
  </head>
  <body><p>Docker</p></body>
</html>

Everything worked

Histochemistry answered 9/8, 2023 at 8:37 Comment(0)
D
0

This works for me

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker} .

Publish folder in Docker folder was not available

Domiciliate answered 15/10, 2023 at 10:41 Comment(0)
D
0

Do try removing it from .gitignore as well, some cloud builds (Like Gcloud submit) check .gitignore if .dockerignore is not found.

For me removing the build folder from .gitignore worked as i was trying to copy the build files

Defluxion answered 19/7 at 8:35 Comment(0)
C
-1

I merely had quoted the source file while building a windows container, e.g.,
COPY "file with space.txt" c:/some_dir/new_name.txt
Docker doesn't like the quotes.

Catto answered 25/10, 2022 at 14:10 Comment(0)
H
-1
  1. I had the same error. I resolved it by adding this to my Docker build command:
docker build --no-cache -f ./example-folder/example-folder/Dockerfile
  • This repoints Docker to the home directory. Even if your Dockerfile seems to run (i.e. the system seems to locate it and starts running it), I found I needed to have the home directory pre-defined above, for any copying to happen.
  1. Inside my Dockerfile, I had the file copying like this:
COPY ./example-folder/example-folder /home/example-folder/example-folder
Haloid answered 17/2, 2023 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.