The Nasty “Gotcha” in Docker Desktop

A container ship sinking in the ocean

Despite its change in pricing, Docker Desktop remains the de facto container host for macOS and Windows. I pay for a license because good tooling is worth the cost, but others have pursued a Rube Goldberg-esque approach to handling their containers; to each their own.

This post isn’t about the changing pricing model (I touched on that in this article if you’re interested). Instead, it’s about a weird setting that can catch you off guard if you aren’t careful.

Connections Forcibly Terminated after Five Minutes

That’s it – that’s the nasty gotcha. See click-baiters, you can get to the point right away. Anyway, let me get into the details.

The TL;DR is: there is a setting in Docker Desktop called vpnKitMaxPortIdleTime which, by default, is set to 300 seconds (five minutes1Three centiseconds for our wacky metric friends. You know you’d use centiseconds, don’t give me that look.). After 300 seconds of zero traffic on a connection, that connection will be forcibly closed.

This setting can be adjusted in the following locations depending on your operating system. Setting it to zero appears to disable the connection culling.

  • macOS: ~/Library/Group\ Containers/
  • Windows: %APPDATA%\Docker\settings.json

The good thing is that in most cases, this will go unnoticed. Unfortunately, when you notice it, it’s generally a problem. In my case, I had a long-running SQL query and after about five minutes it would just error out with a “Connection reset by peer” error. I seem to remember having a similar problem in the past but just shrugging it off because it wasn’t keeping me from moving forward.

I searched for hours to figure out what part of my network connection was causing the timeout. Was it the application I was working on? The RDBMS driver? The database server? The VPN?

It wasn’t until, for unrelated reasons, I tried running the query outside of a Docker container that I found everything worked fine. Using deduction, I was left with a single suspect – Docker Desktop2dun dun DUNNN.

After further data gathering, I found the connections pretty consistently terminated after about five minutes of inactivity. Armed with this subtle hint, I crafted a Google search query and found some interesting results. I eventually stumbled upon some GitHub issues which were talking about the problem. In several of these issues, it had been identified that vpnKitMaxPortIdleTime was the problem.

Know your Tools

There are other circumstances where an idle connection is required and, more importantly, where you’d expect the behavior to match your local or deployment environment3since that’s one of the promises of containerization. Ultimately, it’s important to understand your tools and how/where they help and hinder.

For the love of all that you cherish, please surface these “helpful” features so other people can more readily find them. In this case, Docker could make the timeout a first-class setting that’s not hidden away in a secret settings file. This way, users can actively decide how they’d prefer the software to behave. Absent that, maybe emit some logs that say, “Hey, just so you know, we cleaned up some connections that we assumed were not in use. Hope that’s ok.”