shiplift
shiplift copied to clipboard
Image building should respect .dockerignore
In contrast to the docker build
command provided by the Docker CLI, the build
method on the Images
struct does not respect .dockerignore
files. This is an issue especially for Rust crate build contexts that often have a target
directory of a few GB or more, and are very slow to make it through the tarbell::dir
steps of shiplift
's build process.
A couple of suggested approaches that could solve the problem:
-
Respect
.dockerignore
files by default: this would technically be a breaking change, but would better align with the Docker CLI equivalent command -
Add an option to
BuildOptions
enabling.dockerignore
support: this seems surprising if it's not enabled by default, but this change wouldn't be a breaking change, at least -
Allow users to provide their own
tarball
s to a build command: rather than dealing with the file system directly, users could use their owntarball
-ing scheme and submit that archive directly to a separate build command (build_from_archive
, perhaps?)
If any of those :point_up: sound like good options, I'd be happy to whip up a PR.
You're right. I think 1 sounds like a good default. I don't think there would be many cases to ignore a docker ignore if a docker ignore is present so I'd say you could skip 2. 3 sounds very reasonable but likely a rare case. I don't think I've ever hand built a tar ball and gave that to docker to run.
I believe there's a few off the shelf gitignore parsing crates that you may be able to leverage to managing a docker ignore. I believe it follows the same syntax.
Sounds good, let me tackle option 1 tonight. It won't be quite as simple as dropping in an existing gitignore
crate, since .dockerignore
syntax is based on golang's filepath.Match
, and .gitignore
is its own thing, but I need to support that syntax anyway in my own project.
Speaking of option three: my use case is a command-line tool that templates Dockerfiles and spins up containers for users, so it's pretty convenient to be able to generate my own tarball without writing a Dockerfile (and .dockerignore
, soon) to the file system. This use case could also be addressed more generally by the ability to provide the contents of a Dockerfile
instead of a path to an existing file, like one is able to do with the CLI by providing the contents over STDIN (e.g. echo "FROM rust" | docker build -f - .
). I've implemented the former in my fork of shiplift
, but wasn't sure if that was worthy of its own feature request or inclusion in shiplift
itself.
Was just looking at the docker image build
implementation to figure out how it works. Here's the code that handles tarballing and dockerignore, maybe it's a useful reference if anyone wants to implement this: https://github.com/docker/cli/blob/04dad42c3c82733c3c82b1f859829d62d8608128/cli/command/image/build.go#L293
Random semi-related thought, tarballing the entire context dir seems quite wasteful and requires thoughtfulness around where to put the Dockerfile, does anyone know a good reason why it wouldn't be possible to parse the Dockerfile and include just files that are referenced by ADD
or COPY
commands?