How to avoid transferring everything as build context

Well … you’d use ENV when you want to have a more “dynamic” Dockerfile instead of a hard-wired …
But that’s a different toppic !

Let me show you an example of how I did it:
I have the following structure:

root@deimos:/data/docker/test# ls -R
.:
Dockerfile testdir

./testdir:
dir1 dir2 dir3

./testdir/dir1:
test1.txt test2.txt

./testdir/dir2:
dir2-test.txt

./testdir/dir3:
andnowsomecompletelydifferent myZipfile.zip

And this is my Dockerfile (which resides in /data/docker/test):

FROM ubuntu:20.04
RUN mkdir /var/testdir
COPY testdir/dir3/myZipfile.zip /var/testdir
CMD tail -f /dev/null

Now let’s build it:>

root@deimos:/data/docker/test# docker build -t test .
Sending build context to Docker daemon 9.728kB
Step 1/4 : FROM ubuntu:20.04
—> 1d622ef86b13
Step 2/4 : RUN mkdir /var/testdir
—> Using cache
—> 319ef61748c5
Step 3/4 : COPY testdir/dir3/myZipfile.zip /var/testdir
—> 31b7e2b0004e
Step 4/4 : CMD tail -f /dev/null
—> Running in 3fccbcbb2b3c
Removing intermediate container 3fccbcbb2b3c
—> da63457b11fd
Successfully built da63457b11fd
Successfully tagged test:latest

As you can see only the myZipfile.zip file got copied to the image’s /var/testdir despite the other directories or files.
Let’s check:

root@deimos:/data/docker/test# docker run --rm -d da63457b11fd
4a925bedef0deb223ae31d8d7b30d05aeb4f2cb7dc28fd0577d91c9bc15793c5

root@deimos:/data/docker/test# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4a925bedef0d da63457b11fd “/bin/sh -c 'tail -f…” 5 seconds ago Up 4 seconds affectionate_meninsky

root@deimos:/data/docker/test# docker exec -it 4a925bedef0d /bin/bash
root@4a925bedef0d:/# cd /var/testdir/
root@4a925bedef0d:/var/testdir# ls -la
total 12
drwxr-xr-x 1 root root 4096 May 20 11:19 .
drwxr-xr-x 1 root root 4096 May 13 09:49 …
-rw-r–r-- 1 root root 504 May 20 11:11 myZipfile.zip

You see, only the .zip file is present here - as it is - unpacked.