Specify dockerignore from command line - docker

I have a .dockerignore file, but for one use case, I want to specify the contents of .dockerignore at the command line, something like:
docker build --ignore="node_modules" -t foo .
is there a way to do this from the command line? I am not seeing this in the docs: https://docs.docker.com/engine/reference/commandline/build/#build-with--

No, docker build does not offer an alternative to the .dockerignore file.
That is why I usually keep a symbolic link .dockerignore pointing to the actual .dockerignore_official, except for certain case, where I switch the symlink to .dockerignore_module.
This is a workaround, but that allows me to version the different version of dockerignore I might need, and choose between the two.
Update April 2019: as mentioned by Alba Mendez in the comments, PR 901 should help:
dockerfile: add dockerignore override support
Frontend will first check for <path/to/Dockerfile>.dockerignore and, if it is found, it will be used instead of the root .dockerignore.
See moby/buildkit commit b9db1d2.
It is in Docker v19.03.0 beta1, and Alba has posted an example here:
You need to enable Buildkit mode to use i
$ export DOCKER_BUILDKIT=1
$ echo "FROM ubuntu \n COPY . tmp/" > Dockerfile
$ cp Dockerfile Dockerfile2
$ touch foo bar
$ echo "foo" > .dockerignore
$ echo "bar" > Dockerfile2.dockerignore
$ docker build -t container1 -f Dockerfile .
$ docker build -t container2 -f Dockerfile2 .
$ docker run container1 ls tmp
Dockerfile
Dockerfile2
Dockerfile2.dockerignore
bar
$ docker run container2 ls tmp
Dockerfile
Dockerfile2
Dockerfile2.dockerignore
foo
Update August 2019: this is now in Docker 19.03, with the following comment from Tõnis Tiigi:
#12886 (comment) allows setting a dockerignore file per Dockerfile if the repository contains many. (Note that this was the exact description for the initial issue)
BuildKit automatically ignores files that are not used, automatically removing the problem where different sets of files needed to ignore each other.
The cases where same Dockerfile uses different sets of files for different "modes" of build (eg. dev vs prod) can be achieved with multi-stage builds and defining the mode changes with build arguments.

Related

How to get files not being .dockerignored when getting an unexpectedly large docker build context? [duplicate]

This question already has answers here:
How to test dockerignore file?
(8 answers)
Closed last year.
I have a large monorepo that I'm using as a docker context. The src for the repo is only 250MB, but many of the sub-projects have .gitignored virtualenvs, npm_modules, etc.
It appears that one or many of these .gitignores didn't make it into .dockerignore, because I'm seeing 5GB of context being transmitted on my machine, which is both slow, and I want to debug what's missing from .dockerignore.
Is there a way to get a list of the files being sent as part of the docker context so I can debug what's in .gitignore that's missing from .dockerignore?
Not directly that I know of, but indirectly it wouldn't be that hard. You can COPY the entire build context into an image and then do whatever you want with that content.
FROM busybox
WORKDIR /stuff
# Just copy everything to the image
COPY . .
# Some default CMD is usually a good idea
CMD du -m | sort -n
# Build and run the image
docker build -t where-is-my-space -f Dockerfile.debug .
# The default `CMD` lists directories in the copied content
# sorted by size
docker run --rm where-is-my-space
# Huh, let's dig in more
docker run --rm where-is-my-space ls -l data/unexpected
# Or with an interactive shell (note, busybox doesn't have bash)
docker run --rm -it where-is-my-space sh
# All done, let's clean up
docker rmi where-is-my-space

What does this command do?: `docker build . -f Dockerfile2 -t `

From my tutorial, it creates clone Dockerfile (Dockerfile2) and build the second Docker.
docker build . -f Dockerfile2 -t
But I don't understand what . does.
According to Docker documentation.:
-t : tag ...
-f : file...
What is this command doing? - Thanks
Obviously the tag is missing. Anyway you're telling Docker:
Hey Docker, the current directory is your build context so copy everything from this location (except the files and directories mentioned in the .dockerignore file) and build the image for me using the instructions from the Dockerfile2 file. Also, please tag it using the provided tag so I can reference it easily.
If you ommit the file (drop the -f argument), then the default Dockerfile file is assumed.
. means the current directory where you are. And the Dockerfile is in it. If you do not in the directory of the Dockerfile, you will get the error.
The full command : docker build path -f Dockfile -t containerName. Also the document docker build [OPTIONS] PATH | URL | -.
From the Docker build documentation:
Usage:
docker build [OPTIONS] PATH | URL | -
build: Build an image from a Dockerfile
.: Specifies that the PATH is ., and so all the files in the local directory get tar d and sent to the Docker daemon. The PATH specifies where to find the files for the “context” of the build on the Docker daemon.
--file , -f: Name of the Dockerfile (Default is ‘PATH/Dockerfile’).
--tag , -t: Name and optionally a tag in the ‘name:tag’ format. You can apply multiple tags to an image.
So, what is happening is: Docker I want to build an image from a Dockerfile called Dockerfile2 tagged with the value (you didn't set the value of the tag) in the current path.

docker build - exactly 1 argument

I've been trying to build syntaxnet on my ubuntu setup and bumped into a problem (simple as it may be) that I had hard time finding the solution to.
Whenever I try to build using the command:
docker build -t dragnn-oss:latest-minimal -f docker-devel/Dockerile.min
I get the error message:
"docker build" requires exactly 1 argument(s).
Now, my docker version is 17.06 and according to this page,
[docker: "build" requires 1 argument. See 'docker build --help', I should be able to specify a Dockerfile that is located in a different directory, so I don't see what the problem is.
Edit: I created a symlink by doing:
ln -s docker-devel/Dockerfile.min link1
Then I just went through with the command:
docker build -t dragnn-oss:latest-minimal -f link1 .
and it worked.
I thought I did not need to put the . at the end since I specified the Dockerfile with -f but learned the mistake.
You need to add a dot at the end, either
docker build -t mytag .
or
docker build -t dragnn-oss:latest-minimal -f docker-devel/Dockerile.min .
see also
docker: "build" requires 1 argument. See 'docker build --help'
While the other answers are all correct and you've found the solution, I want to point you to the documentation for docker build for anyone stumbling upon this. This is what the command is supposed to look like:
$ docker build [OPTIONS] PATH
In your example, you specified two options (-f and -t). But you didn't specify the PATH argument. Citing the documentation:
The PATH specifies where to find the files for the “context” of the build on the Docker daemon.
The context is sent to the Docker daemon when building an image. You can just use . if you want to use the correct directory as Docker's build context, but as others have mentioned, you can also specify a specific directory, e.g. docker-devel.
Specify a directory and in this directory, a Dockerfile :
docker build -t dragnn-oss:latest-minimal -f Dockerile.min docker-devel
You need to add an argument to the end with just the path.
If it's the current directory then . (simple dot) will suffice.
The -f param is just for the filename (Dockerfile being the default)
docker build -t dragnn-oss:latest-minimal -f Dockerile.min docker-devel

How to set image name in Dockerfile?

You can set image name when building a custom image, like this:
docker build -t dude/man:v2 . # Will be named dude/man:v2
Is there a way to define the name of the image in Dockerfile, so I don't have to mention it in the docker build command?
Using -t on invocation
How to build an image with custom name without using yml file:
docker build -t image_name .
How to run a container with custom name:
docker run -d --name container_name image_name
Workaround using docker-compose
Tagging of the image isn't supported inside the Dockerfile. This needs to be done in your build command. As a workaround, you can do the build with a docker-compose.yml that identifies the target image name and then run a docker-compose build. A sample docker-compose.yml would look like
version: '2'
services:
man:
build: .
image: dude/man:v2
That said, there's a push against doing the build with compose since that doesn't work with swarm mode deploys. So you're back to running the command as you've given in your question:
docker build -t dude/man:v2 .
Personally, I tend to build with a small shell script in my folder (build.sh) which passes any args and includes the name of the image there to save typing. And for production, the build is handled by a ci/cd server that has the image name inside the pipeline script.
Workaround using docker-compose
Here is another version if you have to reference a specific docker file:
version: "3"
services:
nginx:
container_name: nginx
build:
context: ../..
dockerfile: ./docker/nginx/Dockerfile
image: my_nginx:latest
Then you just run
docker-compose build
My Dockerfile alone solution is adding a shebang line:
#!/usr/bin/env -S docker build . --tag=dude/man:v2 --network=host --file
FROM ubuntu:22.04
# ...
Then chmod +x Dockerfile and ./Dockerfile is to go.
I even add more docker build command line arguments like specifying a host network.
NOTE: env with -S/--split-string support is only available for newer coreutils versions.
With a specific Dockerfile you could try:
docker build --tag <Docker Image name> --file <specific Dockerfile> .
for example
docker build --tag second --file Dockerfile_Second .
Workaround using Docker (and a Makefile)
Generally in Docker you can't say what you want the image to be tagged as in the Dockerfile. So what you do is
Create a Dockerfile
Create a Makefile
.PHONY: all
all: docker build -t image_name .
Use make instead of invoking docker build directly
Or, use buildah
But here is a better idea... Don't build images with Docker! Instead build them with buildah, the new build tool provided by the podman crew which uses shell (or any language), allows building in the cloud easily (without using a different project like kaniko), and allows rootless building of images! At the end of the build script just save the image inside with buildah commit. Here is what it looks like.
#!/bin/sh
# Create a new offline container from the `alpine:3` image, return the id.
ctr=$(buildah from "alpine:3")
# Create a new mount, return the path on the host.
mnt=$(buildah mount "$ctr")
# Copy files to the mount
cp -Rv files/* "$mnt/"
# Do some things or whatever
buildah config --author "Evan Carroll" --env "FOO=bar" -- "$ctr"
# Run a script inside the container
buildah run "$ctr" -- /bin/sh <<EOF
echo "This is just a regular shell script"
echo "Do all the things."
EOF
# Another one, same layer though
buildah run "$ctr" -- /bin/sh <<EOF
echo "Another one!"
echo "No excess layers created as with RUN."
EOF
# Commit this container as "myImageName"
buildah commit -- "$ctr" "myImageName"
Now you don't have to hack around with a Makefile. You have one shell script that does everything, and is far more powerful than a Dockerfile.
Side note, buildah can also build from Dockerfiles (using buildah bud), but this short coming is with the Dockerfile. So that won't help.

docker: "build" requires 1 argument. See 'docker build --help'

Trying to follow the instructions for building a docker image from the docker website.
https://docs.docker.com/examples/running_redis_service/
this is the error I get will following the instructions on the doc and using this Dockerfile
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y redis-server
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
sudo docker build -t myrepo/redis
docker: "build" requires 1 argument. See 'docker build --help'.
How do resolve?
You need to add a dot, which means to use the Dockerfile in the local directory.
For example:
docker build -t mytag .
It means you use the Dockerfile in the local directory, and if you use docker 1.5 you can specify a Dockerfile elsewhere. Extract from the help output from docker build:
-f, --file="" Name of the Dockerfile(Default is 'Dockerfile' at context root)
In my case this error was happening in a Gitlab CI pipeline when I was passing multiple Gitlab env variables to docker build with --build-arg flags.
Turns out that one of the variables had a space in it which was causing the error. It was difficult to find since the pipeline logs just showed the $VARIABLE_NAME.
Make sure to quote the environment variables so that spaces get handled correctly.
Change from:
--build-arg VARIABLE_NAME=$VARIABLE_NAME
to:
--build-arg VARIABLE_NAME="$VARIABLE_NAME"
Did you copy the build command from somewhere else (webpage or some other file)? Try typing it in from scratch.
I copied a build command from an AWS tutorial and pasted it into my terminal and was getting this error. It was driving me crazy. After typing it in by hand, it worked! Looking closer and my previous failed commands, I noticed the "dash" character was different, it was a thinner, longer dash character than I got if I typed it myself using the "minus/dash" key.
Bad:
sudo docker build –t foo .
Good:
sudo docker build -t foo .
Can you see the difference?.. Cut and paste is hard.
In case anyone is running into this problem when trying to tag -t the image and also build it from a file that is NOT named Dockerfile (i.e. not using simply the . path), you can do it like this:
docker build -t my_image -f my_dockerfile .
Notice that docker expects a directory as the parameter and the filename as an option.
Use the following command
docker build -t mytag .
Note that mytag and dot has a space between them . This dot represents the present working directory .
Just provide dot (.) at the end of command including one space.
example:
command: docker build -t "blink:v1" .
Here you can see "blink:v1" then a space then dot(.)
Thats it.
You Need a DOT at the end...
So for example:
$ docker build -t <your username>/node-web-app .
It's a bit hidden, but if you pay attention to the . at the end...
From the command run:
sudo docker build -t myrepo/redis
there are no "arguments" passed to the docker build command, only a single flag -t and a value for that flag. After docker parses all of the flags for the command, there should be one argument left when you're running a build.
That argument is the build context. The standard command includes a trailing dot for the context:
sudo docker build -t myrepo/redis .
What's the build context?
Every docker build sends a directory to the build server. Docker is a client/server application, and the build runs on the server which isn't necessarily where the docker command is run. Docker uses the build context as the source for files used in COPY and ADD steps. When you are in the current directory to run the build, you would pass a . for the context, aka the current directory. You could pass a completely different directory, even a git repo, and docker will perform the build using that as the context, e.g.:
docker build -t sudobmitch/base:alpine --target alpine-base \
'https://github.com/sudo-bmitch/docker-base.git#main'
For more details on these options to the build command, see the docker build documentation.
What if you included an argument?
If you are including the value for the build context (typically the .) and still see this error message, you have likely passed more than one argument. Typically this is from failing to parse a flag, or passing a string with spaces without quotes. Possible causes for docker to see more than one argument include:
Missing quotes around a path or argument with spaces (take note using variables that may have spaces in them)
Incorrect dashes in the command: make sure to type these manually rather than copy and pasting
Incorrect quotes: smart quotes don't work on the command line, type them manually rather than copy and pasting.
Whitespace that isn't white space, or that doesn't appear to be a space.
Most all of these come from either a typo or copy and pasting from a source that modified the text to look pretty, breaking it for using as a command.
How do you figure out where the CLI error is?
The easiest way I have to debug this, run the command without any other flags:
docker build .
Once that works, add flags back in until you get the error, and then you'll know what flag is broken and needs the quotes to be fixed/added or dashes corrected, etc.
On older versions of Docker it seems you need to use this order:
docker build -t tag .
and not
docker build . -t tag
You can build docker image from a file called docker file and named Dockerfile by default. It has set of command/instruction that you need in your docker container.
Below command creates image with tag latest, Dockerfile should present on that location (. means present direcotry)
docker build . -t <image_name>:latest
You can specify the Dockerfile via -f if the file name in not default (Dockerfile)
Sameple Docker file contents.
FROM busybox
RUN echo "hello world"
Open PowerShelland and follow these istruction.
This type of error is tipically in Windows S.O.
When you use command build need an option and a path.
There is this type of error becouse you have not specified a path whit your Dockerfile.
Try this:
C:\Users\Daniele\app> docker build -t friendlyhello C:\Users\Daniele\app\
friendlyhello is the name who you assign to your conteiner
C:\Users\Daniele\app\ is the path who conteins your Dockerfile
if you want to add a tag
C:\Users\Daniele\app> docker build -t friendlyhello:3.0 C:\Users\Daniele\app\
The following command worked for me. Docker file was placed in my-app-master folder.
docker build -f my-app-master/Dockerfile -t my-app-master .
My problem was the Dockerfile.txt needed to be converted to a Unix executable file. Once I did that that error went away.
You may need to remove the .txt portion before doing this, but on a mac go to terminal and cd into the directory where your Dockerfile is and the type
chmod +x "Dockerfile"
And then it will convert your file to a Unix executable file which can then be executed by the Docker build command.
#Using a file other than Dockerfile instead.
#Supose my file is `Dockerfile-dev`
docker build -t mytag - < Dockerfile-dev
In my case I was using a dash (slightly longer hyphen) symbol – before the t option was the problem.
docker build –t simple-node .
Replace with a hyphen/ minus symbol.
docker build -t simple-node .
I got this error when using Docker with Jenkins pipeline within a pipeline script. The solution was to use this syntax in the pipeline script:
docker.build("[my_docker_image_tag]", "-f ./path/to/my/Dockerfile.jvm .")
Docker Build Command Format
In your powershell :
There is this type of error because you have not specified a path whith your Dockerfile.
Try this:
$ docker build -t friendlyhello:latest -f C:\\TestDockerApp\\Dockerfile.txt
friendlyhello is the name you assign to your container and add the version , just use the :latest
-f C:\TestDockerApp\Dockerfile.txt
- you want to add a tag because the build command needs a parameter or tag
- The DockerFile is a text document so explicitly add the extension .txt
**Try this format :
$ docker build -t friendlyhello:latest -f C:\\TestDockerApp\\Dockerfile.txt .**

Resources