Should .dockerignore typically be a superset of .gitignore?

I do not think .dockerignore must be a superset of .gitignore. Docker ignore contains files which you want Docker build to ignore and in some cases it could be your source code as well. Take the example of a Java project that you are building with maven.

In this case when you are building the docker container you are probably only interested in the target folder and not any other folder. Whereas the .gitignore will have the target folder since you wont be checking in the compiled binaries (jar / war) to the source repo.

Similarly there could be other files that are generated / downloaded during your build which are required in the container but not in the source repo. So in a nutshell I don't think it is a good idea to enforce the superset rule, at least not in a generic all encompassing way.

It is fairly common to build an application outside of Docker and inject the resulting binary. The most common example I see on SO is with Java-based applications. The Java class file format is designed to be portable across environments and so there aren't a lot of differences if a .jar file is built on a developer's workstation or not. You can run

mvn build
docker build -t myapp .
FROM tomcat:9
COPY target/myapp.war /usr/local/tomcat/apps

In this setup the target directory would be in .gitignore (you do not want build artifacts committed to source control) but it would not be in .dockerignore (it needs to be available to the image).

Some other patterns where this could be useful include:

  • In a compiled language in a developer environment with somewhat long build times, so that you can get a test image out without spending several minutes waiting for make in a multi-stage build
  • When an image needs to contain static assets that are hosted somewhere outside of source control, like Amazon S3
  • If there are data sets that get generated at build time, that are large enough to not want to be checked in but small enough that adding them to the image is still practical (5-500 MB perhaps)

(I mostly ignore .dockerignore but I also try to be explicit about what files I COPY into my images.)