Trying to copy a folders content, it works when i hard code the path like:
COPY ./my-folder /path/to/location
But need to be able to change this path so i tried using a build argument like this:
COPY ${folderVariable} /path/to/location
and then build with
--build-arg folderVariable=./my-folder
But it copies everything in the same folder as "my-folder", when i only want the contents of "my-folder"
You need to define it with ARG in Dockerfile before using:
FROM alpine:3.3
ARG folderVariable=./my-folder # Optional default value to be `./my-folder`
COPY ${folderVariable} /opt/my-folder
And build it like:
docker build --build-arg folderVariable=./folder-copy -t test .
More details please refer to: https://docs.docker.com/engine/reference/builder/#arg
Expansion still does not work for the COPY --from=$var ... case.
But you can create intermediate image as an alias, like this:
ARG docsBranch=4.5
ARG docsFullPath=registry.myCompany.pro/group/project-docs/docs:$docsBranch
# Lifehack
FROM $docsFullPath as docs
FROM node:10.21.0-buster-slim
WORKDIR /app
# Now we can use docs instead of $docsFullPath
COPY --from=docs /app/html/en ./documentation/en
Related
We have a couple of DockerFiles that runs the same command
COPY --from=/source /dest
Since we will change the /source from time to time, is it possible to extract this into some common util file and use it everywhere?
You could try to pass it as an ARG to docker build.
docker build --build-arg mysourcedir=/source Dockerfile
and in the Dockerfile
# use /source as default if no arg is supplied
ARG mysourcedir=/source
...
COPY --from=$mysourcedir /dest
...
Or if you use docker compose then you could put this as an environment variable into a .env file and pass it with the --env-file flag. Details can be found in the documentation.
I'm a newbie to docker, sorry if my question is too basic. I saw dockerfile like this:
FROM diamol/maven AS builder
WORKDIR /usr/src/iotd
COPY pom.xml .
RUN mvn -B dependency:go-offline
COPY . .
RUN mvn package
FROM diamol/openjdk
WORKDIR /app
COPY --from=builder /usr/src/iotd/target/iotd-service-0.1.0.jar .
EXPOSE 80
ENTRYPOINT ["java", "-jar", "/app/iotd-service-0.1.0.jar"]
I'm confused about COPY . . instruction, what does the first period and second period COPY . . mean?
Also, if I want to copy all files of the current working directory from my host machine into the image, then how can I modify COPY . . so that the first period means currenty directory of my machine?
In the Dockerfile COPY directive, the last argument is the path inside the container, relative to the current WORKDIR. All of the preceding arguments are paths inside the build context, the host directory passed as an argument to docker build.
I want to copy all files of the current working directory from my host machine into the image, then how can I modify COPY . . ...?
You probably don't need to. So long as you docker build . naming the current directory . as the last argument, that's exactly what COPY . . does. That instruction means to copy . – the entirety of the build context, from the original host system – to . – the current directory, inside the image.
WORKDIR /usr/src/iotd # `COPY anything .` will put it here inside the image
COPY pom.xml . # Copy a single file into that WORKDIR
COPY . . # Copy the entire build context into the WORKDIR
I've mentioned "build context" a couple of times. That is the directory argument to docker build
docker build \
-t myname/some-image: tag \
. # <--- the build context directory
or that you specify in a docker-compose.yml file
version: '3.8'
services:
one:
build: ./one # <-- this directory
two:
build:
context: ./two # <-- this directory
except that the files mentioned in a .dockerignore file are removed first.
In the question title you also ask
does dockerfile's instruction execute in order?
They do. The newer BuildKit backend has some capability to execute build stages not necessarily in the order they're written, but it ensures that you get the same results as if all of the COPY and RUN instructions from a previous stage had run before a COPY --from=... in a later stage happens.
From my perspective, one of the best ways to know all the details for COPY and WORKDIR docker commands is to go through following official documentation.
You can either search for COPY and WORKDIR keywords on the home page at below first link or please refer to last two links and find all the details including examples.
https://docs.docker.com/engine/reference/builder/
https://docs.docker.com/engine/reference/builder/#copy
https://docs.docker.com/engine/reference/builder/#workdir
Is it possible to copy from another image inside a dockerfile, using a variable as parameter of the from flag?
What I would achieve is the following
ARG MY_VERSION
COPY --from=my-image:$MY_VERSION /src /dst
But i always get
invalid from flag value my-image:$MY_VERSION: invalid reference format
You can do what you want, but you need to have a FROM statement identifying the image you want to copy from. Something like this
ARG MY_VERSION
FROM my-image:$MY_VERSION as source
FROM scratch as final
COPY --from=source /src /dst
Replace scratch with the base image you want to use for your new image.
Here's an example to show that it works. Dockerfile:
ARG MY_VERSION
FROM ubuntu:$MY_VERSION as source
FROM alpine:latest
COPY --from=source /etc/os-release /
Build and run with
docker build --build-arg MY_VERSION=20.04 -t test .
docker run --rm test cat /os-release
The output shows
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
...
which shows that it has copied a file from the Ubuntu 20.04 image to an Alpine image.
I have a Dockerfile that creates the build image I want to use here: ~/build/Dockerfile then I use a standard image to deploy
The image built from ~/build/Dockerfile is not Published anywhere, I know I can simply copy paste the one Dockerfile into the other, however it would be better if I could simply reference it so..
Is it possible to somehow reference the Dockerfile itself when deploying?
like so:
FROM [insert something that creates an image using ~/build/Dockerfile] as build-env
... build operations ....
FROM some-image
COPY --from=build-env /built .
ENTRYPOINT [blah]
This won't work but is there some other way to accomplish this?
No you can't do it because you have to provide an image to FROM.
Change the COPY line to
COPY --from=step1 /built .
And write a script to build your image:
cd path1
docker build -t step1 .
cd path2
docker build -t final_image .
(if you don't want to hard code step1 in the Dockerfile, replace it with a var and call with ARG)
Generally things in Docker space like the docker run command and the FROM directive will use a local image if it exists; it doesn't need to be pushed to a repository. That means you can build your first image and refer to it in the later Dockerfile by name. (There's no way to refer to the other Dockerfile per se.)
Newer versions of Docker have an extended form of the Dockerfile COPY command which
accepts a flag --from=<name|index>.... In case a build stage with a specified name can’t be found an image with the same name is attempted to be used instead.
So if you ahead of time run
docker build -t build-env ~/build
then the exact syntax you show in your proposed Dockerfile will work
FROM some-image
COPY --from=build-env /built .
and it doesn't matter that the intermediate build image isn't actually pushed anywhere.
COPY/ADD statement requires 2 parameters. How can I add any file to current workdir that has been set in base image?
FROM company/app
COPY local.conf
Sure I can add WORKDIR statement before COPY to explicitly declare it. But that would be problematic if the workdir in company/app changes.
It turns out to be very simple. I just need to use dot to copy to current workdir.
COPY local.conf .
Still cannot figure out if this has some gotchas. But it just work as intended.
But that would be problematic if the workdir in company/app changes.
Then you would need to pass that workdir as build-time parameter in order to be able to change it from one docker build to the next.
See docker build --build-arg
You would need first to docker inspect company/app (inspec the image) to see if there are any changes.