docker build command is something I never gave much thought to as it just works. Run the command and out the other side is your newly built Docker image. That was easy! But it is not all sunshine and green grass in DevOps land.
If you have been wrangling code for a while, then eventually the command you have been using for years will suddenly stop working in a new environment.
docker build is a command that is part of the core functionality of Docker, and you become very intimate with this command when adding Docker commands to CI/CD pipelines. The `docker build` is especially vital, so when it stops working, it halts the entire development process.
Docker Build with GitLab runners
We use GitLab for all of our projects. Why do you ask? Have a look at the article Limit your Tech Toolset to understand our love for GitLab. GitLab uses runners which execute the steps in the build pipeline on a server located in the development or test environments.
The Windows runner is where the problem appeared. When I executed a build on the Windows runner `docker build` ran into an issue not being able to resolve DNS. As it turns out, this is a Windows limitation due to the number of default NAT networks allowed. Elton Stoneman identifies the issue as well as workarounds in his Docker Windows KB
Even with Elton's workaround, this was not solving my issue with DNS resolution on newly created Docker Networks. The other networks on the same host worked just fine. The build network was the problem child. I tried adding DNS to the network, populating the /etc/hosts with the DNS name/IP of the servers I was trying to reach, and much more with no luck.
It wasn't until I reverted to reading the docker build documentation that I stumbled upon the possibility to attach `docker build` to an existing network. It's in the documentation yet somewhat obscure with no examples or clear definition of what it does.
Excerpt from the Docker Build reference:
--network Set the networking mode for the RUN instructions during build
Yup, that's all you get. OK, OK. I explain how this works in the Workaround section.
Docker Build Workaround
The use case I have is I needed to connect
docker build to a network which could resolve DNS. You may have another requirement which you want to connect to a network during Build to communicate to certain services or resources to help with the Build. After using the `--network` flag, I am finding a lot more use cases.
- docker network ls
- Choose a known working network
- docker build --network=<known working network name>
By default, Docker uses the default network for building. Setting the network manually ensures the network can access the internet.
--network flag has fixed my Build and has opened up new use cases for builds.
Docker Build Going Forward
Now, the possibility of `docker build` is growing with every release. DockerCon SF 2019 the experimental feature docker buildx was announced. Buildx introduces the concept of build instances similar to the GitLab runner concept allowing for simultaneous builds to execute in isolated build environments. Build instances will improve performance and decrease build times for large projects. Win!
Another great feature in Buildx is the possibility to Build images for different architectures from the same build machine. Now, it is possible to build ARM, X86, and possibly RISC-V in the future all from the same build instance. We no longer need specialized build servers per CPU architecture, which will save us time and money as well.
The Buildx features still contain the experimental flag, but I predict these features will slowly start working their way into the production release. `docker build` continues to add functionality and will be even more critical going forward.