I have a Dockerfile that I use to build the same image but for slightly different purposes. Most of the time I want it to just be an "environment" without a specific entrypoint so that the user just specifies that on the Docker run line:
docker run --rm -it --name ${CONTAINER} ${IMAGE} any_command parameters
But for some applications I want users to download the container and run it without having to set a command.
docker build -t ${IMAGE}:demo (--entrypoint ./demo.sh) <== would be nice to have
Yes, I can have a different Dockerfile for that, or append an entrypoint to the basic Dockerfile during builds, or various other mickey-mouse hacks, but those are all just one more thing that can go wrong, adding complexity, and are workarounds for the essential requirement.
Any ideas? staged builds?
The Dockerfile CMD directive sets the default command. So if your Dockerfile ends with
CMD default_command
then you can run the image in multiple ways
docker run "$IMAGE"
# runs default_command
docker run "$IMAGE" any_command parameters
# runs any_command instead
A container must run a command; you can't "just run a container" with no process in it.
You do not want ENTRYPOINT here since its syntax is noticeably harder to work with at the command line. Your any_command would be passed as arguments to the entrypoint process, rather than replacing the built-in default.
Is there a way to use external volumes during the docker image build ?
I have a situation where I would like to use a configuration inside a external volume during the docker image build time. Is that possible?
(edited to reflect current Docker CLI behavior)
If by 'docker image build' you mean running a single 'docker build ...' command: no, there is no way to do that (at least, not in the most recent documentation that I have read). However, nothing prevents you from performing the step that needs the external volume using direct docker commands and then commit the container and tag it just as 'docker build' would. Assuming this is the last step in your build, put all other commands (that don't need the volume) into a Dockerfile and then do this:
tmp_img=`docker build .`
tmp_container=`docker run -d -v $my_ext_volume:$my_mount_path --entrypoint=(your volume-dependent build command here) $tmp_img`
docker wait "$tmp_container"
docker commit $tmp_container my_repo/image_tag:latest
docker rm "$tmp_container"
This does the same as having a RUN command in the Dockerfile, but with the added volume mount. The commit command in the example also tags the image.
It is a bit more complex if you need to have other Dockerfile commands after the volume-dependent one, but in most cases you can combine run commands and re-arrange your install in a way that leaves the manual run-with-volume command last, to keep things simple.
You can copy the file into the docker image (ADD) and rm as one of the last steps
podman is an alternative to Docker that has an api that is the same BUT also supports mounting volumes at buildtime.
I use this to load data into testdatabases without having to copy the data into the image first.
You can use ADD combined with ARG (build time parameters) to access files or directories during the build without having to hardcode their location.
ARG MAVEN_SETTINGS=settings.xml
ADD $MAVEN_SETTINGS ./
And now you can change the file location during the build with:
docker build --build-arg MAVEN_SETTINGS=someotherfile.xml
We are not restricted to Docker to build OCI images.
With buildah it's possible to mount volumes from the host that won't be persisted in the final image. Useful for configuration and secrets.
buildah bud --volume /home/test:/myvol:ro -t imageName .
I have a Docker container that will have a LARGE (about 100) number of customization settings. I would prefer to have more flexibility than coding the defaults all into the DockerFile. I notice that the docker run command supports this option:
--env-file value Read in a file of environment variables (default [])
Is there any way to have a similar file-driven mechanism used by docker build? Or is there a better way entirely?
Environment files are not supported for builds.
This has been discussed at large and very likely won't be added.
Introducing env in the build command creates host dependent builds.
The ARG command and --build-args are available during builds but do not support a file like you require.
As user2105103 suggests, you can COPY the env file in your build steps and then source it during a RUN.
COPY .env /.env
RUN set -uex; \
. /.env; \
echo $MY_ENV_VAR
You can write a bash script that would dynamically build your custom Dockerfiles .
I have a bunch of Dockerfiles that are build from a common automated place using the same build command:
docker build -t $name:$tag --build-arg BRANCH=$branch .
Some of the Dockerfiles contain this:
ARG BRANCH=master
And that argument is used for some steps of the image build.
But for some Dockerfiles which doesn't need that argument I get this error at the end:
One or more build-args [BRANCH] were not consumed, failing build.
How can I overcome this problem without including the argument to all the Dockerfiles?
Have you considered grepping your Dockerfile for BRANCH and using it result to decide if you should supply your ARG or not?
You could replace your automation build trigger with something like:
if grep BRANCH Dockerfile; then docker build -t $name:$tag --build-arg BRANCH=$branch .; else docker build -t $name:$tag . ; fi
I don't see any documented way to avoid this error without changing your input or your Dockerfile. robertobado already covers changing your input. As a second option, you can include an effectively unused build arg at the end of your Dockerfile which would have a very minor impact on your build.
ARG BRANCH=undefined
RUN echo "Built from branch ${BRANCH}"
Since this doesn't modify the filesystem, I believe the image checksum will be identical.
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 .**