Docker building image from command line - docker

I try to run following commands:
$ docker build - <<EOF
FROM mysql:8
ENV MYSQL_ROOT_PASSWORD=password
COPY ./data.sql /docker/entrypoint-initdb.d/
EOF
but I always get this error:
failed to compute cache key: "/data.sql" not found: not found
The data.sql is where I run the command from, so I don't understand why it does not find the data.sql file.

When you pass a Dockerfile like this, you implicitly do not pass the build context. From the documentation:
docker build - < Dockerfile
This will read a Dockerfile from STDIN without context. Due to the lack of a context, no contents of any local directory will be sent to the Docker daemon. Since there is no context, a Dockerfile ADD only works if it refers to a remote URL.
Therefore, there is no context to copy the data.sql file from. The input when you run docker build - is either a Dockerfile or a compressed tar of the context:
docker build - < context.tar.gz
This will build an image for a compressed context read from STDIN. Supported formats are: bzip2, gzip and xz.

Related

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

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/
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.
#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.
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 :
In an empty directory, create a Dockerfile_test file, with this content
FROM nginx:1.21.3-alpine
COPY test_file /my_test_file
Then create a dummy file:
touch test_file
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
[..]
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
[..]
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
FWIW this same error shows up when running gcloud builds submit if the files are included in .gitignore
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.
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.
Inside my Dockerfile, I had the file copying like this:
COPY ./example-folder/example-folder /home/example-folder/example-folder
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.

Docker and DockerFile build

I am a Docker Beginner and I have some trouble with Dockerfile build..and a lot of questions
Do I have to start command build in path /var/lib/docker/builder ?
How do I know that it does not build because my Dockerfile is not correct written?
Do I have to call my folder Dockerfile?
docker build -t dokcerfile/xdebugphp .
than i got
Error response from daemon: unexpected error reading Dockerfile: read lstat /var/lib/docker/builder/Dokcerfile: no such file or directory
with
Get-Content Dockerfile | docker build -
Error response from daemon: the Dockerfile (Dockerfile) cannot be empty
You can launch docker build from any directory. If you try to COPY a file into an image that doesn't exist in the directory you name, you will see an error message that references /var/lib/docker, but that's an artifact of the Docker build implementation. (In fact, you really shouldn't look inside or try to directly use the /var/lib/docker directory at all.)
The file containing the build instructions is conventionally named Dockerfile (on systems with case-sensitive filesystems, with a capital D and no extension). It's most often located at the root of your source repository. This shouldn't be a directory.
The docker build -t option assigns a tag (name) to the image that's built. It doesn't have to correspond to a file on disk. If you're using Docker Hub to store your images (or just want to emulate its naming) these have the form username/imagename:version; there is an extended format if you're using some other Docker image registry.
You can name the Dockerfile something else; if you do, you need the docker build -f option to reference that file. If it's in a subdirectory of the repository root, the important detail is that COPY statements copy from the "context" directory you pass as the directory argument to docker build; this could be different from the directory that contains the Dockerfile. For example, if your Dockerfile has COPY index.php ., and you run docker build -f docker/xdebugphp ., the file is copied from the . current directory, which is the parent directory of the Dockerfile.
Looks like line endings, try changing dockerfile line endings to LF
Also for Docker build command you need to be in the directory where the dockerfile is or specify the path to the dockerfile
so in the directory where dockerfile is command is
docker build -t IMAGENAMEHERE .
So I solved it with this command
docker build -t imagename -f Dockerfile/xdebugphp .

how to change docker source of the context of the build

Dockerfile is:
FROM nginx
COPY html /usr/share/nginx/html
Dockerfile is in pwd directory(which is home/ubuntu/app), when use following command:
docker build -t mynginx .
I was giving an error:
copy failed: stat /var/lib/docker/tmp/docker-builder344/html: no such file or directory.
how to change docker source of the context of the build?
Docker build only look files in Dockerfile file context, mean the build will copy /home/ubuntu/app/ from this location where your Dockerfile is.
So better to place your html the /home/ubuntu/app in this location as docker build send tar of the context to docker daemon so it is recommended to keep the context minimal.
docker build -t mynginx . would expect to find Dockerfile in the current directory. Moreover, relative paths used by Dockerfile instructions would be relative to the current directory.
You can set the build context path to a different path docker build -t mynginx [some_folder_path]. Docker would search for Dockerfile there. You can modify the path to Dockerfile using -f option docker build -f [path_to_dockerfile] -t mynginx [some_folder_path]

How to copy local filesystem into Docker container

I have a local project directory structure like:
config
test
docker-compose.yaml
DockerFile
pip-requirements.txt
src
app
app.py
I'm trying to use Docker to spin up a container to run app.py. Simple in concept, but this has proven extraordinarily difficult. I'm keeping my Docker files in a separate sub-folder because I plan on having a large number of different environments, and I don't want to clutter my top-level folder with dozens of files like Dockerfile.1, Dockerfile.2, etc.
My docker-compose.yaml looks like:
version: '3'
services:
worker:
image: myname:mytag
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./src/app:/usr/local/myproject/src/app
My Dockerfile looks like:
FROM python:2.7
# Set the working directory.
WORKDIR /usr/local/myproject/src/app
# Copy the current directory contents into the container.
COPY src/app /usr/local/myproject/src/app
COPY pip-requirements.txt pip-requirements.txt
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r pip-requirements.txt
# Define environment variable
ENV PYTHONUNBUFFERED 1
CMD ["./app.py"]
If I run from the top-level directory of my project:
docker-compose -f config/test/docker-compose.yaml up
it succeeds in building the image, but fails when attempting to run the image with the error:
ERROR: for worker Cannot start service worker: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"./app.py\": stat ./app.py: no such file or directory": unknown
If I inspect the image's filesystem with:
docker run --rm -it --entrypoint=/bin/bash myname:mytag
it correctly dumps me into /usr/local/myproject/src/app. However, this directory is empty, explaining the runtime error. Why is this empty? Shouldn't the COPY statement and volumes have populated the image with my application code?
For one, you're clobbering the data set by including the content during the build stage and then using docker-compose to overlay a directory on top of it. Let's first discuss the differences between the Dockerfile (Image) and the Docker-compose (Runtime)
Normally, you would use the COPY directive in the dockerfile to copy a component of your local directory into the image so that it is immutable. In most application deployments, this means we bundle our entire application into the directory and prepare it to run. This means that it is not dynamic (Meaning changes you make to the code after that are not visible in the container) but is a gain in terms of security.
Docker-compose is a runtime specification meaning, "Once I have an image, I want to programmatically define how it runs". By defining a volume here, you're saying "I want the local directory (From the perspective of the compose file) /src/app to be overlaid onto /usr/local/myproject/src/app
Thus anything you built into the image doesn't really matter. You're adding another layer on top of the image which will take precedance over what was built into the image.
It may also be something to do with you specifying the Workdir already and then specifying a ./ reference in the CMD. Would be worth trying it as just CMD ["app.py"]
What happens if you
Build the image: docker build -t "test" .
Run the image manually : "docker run --rm -it test

Why does Docker require PATH when building from custom Dockerfile in another directory?

When building docker images with a Dockerfile in the same directory, the following works every time
$ docker build -t project/app:latest .
Sending build context to Docker daemon 135.9MB
...
However, when using -f to specify a different Dockerfile to use, docker complains ...
$ docker build -t project/app:latest -f ../some/path/Dockerfile.other
"docker build" requires exactly 1 argument.
See 'docker build --help'.
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
I can easily provide the PATH, and the build will work, but why is the PATH still required if I'm specifying the absolute path to the Dockerfile with -f?
The PATH is for specifying the build context (the tree from which COPY instructions copy things), which need not have any relation to the location of the Dockerfile.
Quoting the docs:
The docker build command builds Docker images from a Dockerfile and a “context”. A build’s context is the set of files located in the specified PATH or URL. The build process can refer to any of the files in the context. For example, your build can use a COPY instruction to reference a file in the context.

Resources