Now enables you to deploy a Dockerfile, seamlessly building and starting up your deployment in seconds. To this end, we first synchronize the files in your project's directory and build it in the nearest datacenter.
To decide what files to include or exclude for Docker deployments, we honor .dockerignore if present, or fall back to .gitignore.
Until today, we treated these two files as if they had the same semantics. As of Now 11.1.15, however, we now feature full support for the .dockerignore specification, which introduces the ability to use it as a whitelist.
We are also introducing a new package on npm: @zeit/dockerignore which makes the newly implemented filtering logic available for everyone to reuse.
On the surface, both files allow for defining what paths are not part of your stage. In other words, most people use them as blacklists. Some differences start to emerge when you start using capabilities that allow to turn them into whitelists, which is a pattern we have begun to use at ZEIT for all our Docker containers.
Here's an example of a .dockerignore file using this technique. Instead of serving as a blacklist of things to ignore, we ignore everything by default and only whitelist the precise requirements we need for our project.
*
!include
!these/things

All files are ignored, except for the ones starting with !.

Consider the many files in your project that exist but aren't important for building or executing your project: Readme.md, the .git folder, the Dockerfile and .dockerignore files themselves, etc. Perhaps without realizing it, every time you invoke docker build, these files are being unnecessarily uploaded to the build stage (a process that can be particularly slow when using Docker for Mac).
There are a few differences between how the same definition above works with .gitignore and .dockerignore:
  • * in .gitignore matches everything, whereas in .dockerignore it only matches things in the current directory (like glob). This difference is important when whitelisting after a * rule.
  • include in .gitignore matches all include files and directories, however deeply nested. In .dockerignore however, include specifically matches on ./include but does not match nested files/directories like ./somedir/include.
  • With .gitignore, when a parent directory is ignored, subdirectories (like these/things) cannot be re-added (using !) since git simply avoids walking through the subtree as an optimization, wheras with .dockerignore a subdirectory can be re-added even if a parent directory has been ignored.
  • For a complete list of differences, check out the gitignore spec and the dockerignore spec.
We forked the existing ignore package and added a few test cases for the changes we made. We also implemented a test suite such that, when run in CI, we make real docker builds with the test case's .dockerignore and compare our output to what docker actually does.
After implementing the comprehensive test suite, the differences between the 2 specs became clear and it was evident that we had to rewrite parts of the parsing logic. In doing so, we ended up making the parser logic much simpler and also ended up mimicking docker's existing logic to do the same.
The API is the same as ignore (Check the README for examples and documentation).
To learn more, here are some heplful links:
As a result of this investigation, we have improved the support for Dockerfile in now-cli and the new support for .dockerignore is already in the Now CLI 11.1.15 release. Head over to get the latest version.
Having a robust .dockerignore parser is important as we continue to focus on Serverless Docker Deployments that are extremely quick to spin up and scale.
As an example, using the whitelisting technique we outlined above will help you avoid deploying images that include unnecessary artifacts or inadvertedly grow in size over time. Not to mention the security benefits associated with preventing accidental leaks.
In addition, the community now has a well-tested dockerignore package for low level access to this capability. If you have any questions, don't hesitate to ask on our community or open an issue on GitHub.