Reputation: 1768
Is there a command/option to display or list the context which is sent to the Docker daemon for building an image?
$ docker build -t "image-name"
Sending build context to Docker daemon 8.499 MB
...
Files and directories can be excluded from the build context by specifying patterns in a .dockerignore
file. I guess what I'm looking for amounts to testing the .dockerignore
in addition to any other niche rules Docker uses when determined the context.
Upvotes: 103
Views: 61390
Reputation: 266
Here is a script that outputs the context tarball sent by docker build
to the Docker daemon without actually building an image. You can use it like /path/to/script_below | tar -tv
for example.
#!/usr/bin/python3
from http.server import BaseHTTPRequestHandler
from re import match
from socketserver import UnixStreamServer
from subprocess import Popen, DEVNULL
from sys import exit, stdout
from tempfile import TemporaryDirectory
class ContextDumper(BaseHTTPRequestHandler):
def __init__(self, request, client_address, server):
# provide dummy client address for error reporting
super().__init__(request, ('docker_context', 0), server)
def do_HEAD(self):
if self.path != '/_ping':
self.send_error(404, '/_ping only')
do_GET = do_HEAD
def do_POST(self):
if match(r'/v1\.\d+/build\?', self.path) is None:
self.send_error(404, '/v1.X/build only')
exit(1)
total = 0
while True:
chunk_length = int(self.rfile.readline().strip(), 16)
total += chunk_length
chunk = self.rfile.read(chunk_length)
stdout.buffer.write(chunk)
self.rfile.readline()
if chunk_length == 0:
break
padding = (512 - (total % 512)) % 512
stdout.buffer.write(bytes(padding))
exit(0)
with TemporaryDirectory() as tmpdir:
socket_path = tmpdir + '/docker_context.sock'
fake_dockerd = UnixStreamServer(socket_path, ContextDumper)
with Popen(['docker', f'--host=unix://{socket_path}', 'build', '--file=/dev/null', '.'],
stdout=DEVNULL, stderr=DEVNULL) as builder:
fake_dockerd.serve_forever()
Upvotes: 2
Reputation: 189
What worked for me is to do the following (based on this article).
Tell Docker to use the old build kit. In PowerShell that is:
$ENV:DOCKER_BUILDKIT=0
Run Docker build so that it reports ALL the progress it's making:
docker build --progress=plain BLAH
Given those two things you can then do something as simple as this in your Docker file:
RUN ls /app
And that will give you a list out of everything in the /app folder.
Upvotes: 1
Reputation: 391
Starting with version 18.09, Docker has an option to export context data using BuildKit backend.
It's not enabled by default, so you need to set an environment variable DOCKER_BUILDKIT=1
before invoking docker build
command.
The following command can work also if you don't have any Dockerfile in current directory.
printf 'FROM scratch\nCOPY . /' | DOCKER_BUILDKIT=1 docker build -f- -o context .
When you run multiple times remember to delete previous export with rm -r context
.
You can also get context data as archive and then mount with archivemount
command:
printf 'FROM scratch\nCOPY . /' | DOCKER_BUILDKIT=1 docker build -f- -o- . > context.tar
mkdir context
archivemount context.tar context
With both methods, then you can explore the result with ncdu context
.
Upvotes: 37
Reputation: 1219
Answers above are great, but there is a low-tech solution for most cases - ncdu
. This utility will show pretty and interactive tree structure with sizes. It has an option that will take patterns from a file and exclude them from scan. So you can just do ncdu -X .dockerignore
. You will get something like this:
This is pretty close to what you will get in your docker image. One caveat is thou if you add a dot directory (like .yarn
) into an image, it will not show in ncdu
output.
Upvotes: 91
Reputation: 6079
The only way would be to add the current directory to an specific directory and list it.
Try building with this Dockerfile:
FROM busybox
RUN mkdir /tmp/build/
# Add context to /tmp/build/
COPY . /tmp/build/
Build it with:
docker build -t test .
List all the files and directories in /tmp/build:
docker run --rm -it test find /tmp/build
Upvotes: 74
Reputation: 111576
Updated answer: Since 2017, Docker has recommended to use COPY
instead of ADD
and with the comment from @tlrobinson, the simpler Dockerfile looks like so:
# debug and list the docker build context so that you can minimmize it
#
# usage:
# docker build -f docker/context.Dockerfile -t test/buildcontext .
#
######################
FROM busybox
RUN mkdir /tmp/build/
# Add context to /tmp/build/
COPY . /tmp/build
# this last command outputs the list of files added to the build context:
RUN find /tmp/build/
Upvotes: 14