List of Docker caveats / bugs

Build instances don't allow for debugging with interactive console

This is very likely broken by design. Docker wants Dockerfiles to be reproducible and not changed arbitrarily by convenient user input. However nothing could be more crippling to a developer than being unable to directly inspect a broken environment. In many ways building docker containers feels just as frustrating as building and testing live embedded systems. Imagine only how helpful it would be, if docker simply dropped you into a shell once a command failed. Instead you cannot even run the last layer in a new container if using buildx with foreign architectures. At least not without some major shenanigans. And even then most of the really painful and time-consuming issues you run into are actually entirely exclusive to the build environment.

Luckily you can use this workaround via improvised netcat console:

RUN apk add nmap-ncat && ncat 172.17.0.1 8080 -c 'while true; do read i && echo -en "$($i 2>&1)\n # "; done' && false

Buildx instances are not network-isolated from each other

You might tend to believe that build instances behave like docker containers, but that is not really true. If one build instance starts a daemon that is listening on a certain network port, the other instances will not be able to start that same daemon because the port is in use. Since all instances do exactly the same things instructed by the Dockerfile, the first instance will succeed and all successive instances will fail. Although buildx has an --isolation option, it sadly doesn't change the fact as of this writing.

The only workaround is to plug in a script that checks if the port is in use, before the daemon is started:

while(true); do if netstat -putlan | grep MYPORT; then sleep $((1 + $RANDOM % 60)); else break; fi; done

Port publishing mostly broken for greater numbers

Quite often you need to publish more than just one port. Some RFCs and use cases call for more than 40,000 ports to be available (if counting UDP and TCP seperately like Docker does). By default Docker starts a new "userland proxy" process for every port which consumes time to start and memory to run.  Publishing as little as 100 ports will already cause major slowdowns. But even with userland proxy disabled, I ran into the situation that docker would hit internal limits of maybe 512 ports per port range and 1024 ports total. It would then silently, and without warning, stop publishing ports specified higher and after that limit. End of story: Don't use docker to publish ports, if you need to publish more than 512. Use this iptables workaround instead. Always check twice with netstat.

This page or post was last modified on 2022-09-15 .

Leave a Reply

Your email address will not be published. Required fields are marked *