A build system uses Docker to automatically download, create the necessary images and start containers for each of the external systems, such as various databases and services.
The integration tests can then use these services and when the integration tests finish, any containers will automatically stop
When you have few modules that are not written in Java, and so they have to be required on the target operating system. Docker lets our build do this using images with the target operating system(s) and all necessary development tools.
Using Docker has several advantages:
- You don't have to install, configure, and run specific versions of each external services on your local machine, or have access to them on your local network.
- We can test multiple versions of an external service. Each module can start whatever containers it needs, so different modules can easily use different versions of the services.
- Everyone can run complete builds locally. You don't have to rely upon a remote continuous integration server running the build in an environment set up with all the required services.
- All builds are consistent. When multiple developers each build the same codebase, they should see exactly the same results – as long as they're using the same or equivalent JDK, Maven, and Docker versions. That's because the containers will be running the same versions of the services on the same operating systems. Plus, all of the tests are designed to connect to the systems running in the containers, so nobody has to fiddle with connection properties or custom configurations specific to their local environments.
- No need to clean up the services, even if those services modify and store data locally. Docker images are cached, so building them reusing them to start containers is fast and consistent. However, Docker containers are never reused: they always start in their pristine initial state, and are discarded when they are shutdown. Integration tests rely upon containers, and so cleanup is handled automatically.