Docker preserves forced-update state during stack deployment
Docker 18.05 avoids an unintended service rollout when stack deployment resets a force-update counter. It also repairs Compose network merging and reduces the growth of bridge isolation rules.
Deploying an unchanged stack could restart a service after someone had already forced an update. The stack file did not request another rollout, but the CLI submitted a changed task specification anyway. Docker 18.05 includes a fix for that mismatch. The May 9 release notes also describe network merging and bridge isolation improvements, making this a release about how deployment machinery interprets existing state.
The cause appears in Sebastiaan van Stijn's CLI patch 963. A forced service update increments ForceUpdate in the task specification. Stack deployment built a new specification with the field's default value, zero. Resetting that field created a task specification change even when the deployment did not intend to replace tasks.
I expect a repeatable deployment description to avoid changes that its author did not request. Docker's packaging model is useful because the artifact and its construction can be inspected. Deployment needs the same care when an internal field carries operational history that the source configuration does not express.
Preserving a field can prevent a rollout
The patch copies the current service's ForceUpdate value into the task template before calling the service update API. Its code comment states that stack deployment has no --force option. Preserving the value therefore respects the command's actual intent, while allowing explicit changes in the stack configuration to proceed through the ordinary update path.
This is a useful example of why a declaration cannot always be translated into a fresh structure filled with defaults. Some fields describe an operation previously requested through another command. The absence of that field from a stack file does not necessarily mean that resetting it is part of the desired deployment.
The regression test gives the existing service a nonzero counter and checks that deployment preserves it. It covers both an unchanged image reference and a changed image reference. That distinction matters because the counter should survive either case. Preserving it must not depend on whether a particular deployment happens to need a different image.
For an operator, the result is narrower than a promise that repeated deployment never changes anything. Other parts of the submitted service specification can still change. This correction removes the specific unintended change caused by replacing the force-update counter with zero. It makes a later stack deployment compatible with an earlier operational action on the service.
Network definitions need explicit merge behavior
Vincent Demeester's CLI patch 983 addresses errors when merging Compose files containing network definitions. It updates the Mergo dependency and adjusts how the CLI uses it. The patch includes a test in which a base file defines an overlay network with IP address management configuration, while an override file supplies an external network name.
The expected loaded configuration refers to the external network. It does not retain the base file's overlay and address-management definition as competing instructions. That is a concrete merge result, and a more useful description than saying that the loader now combines network configuration correctly in every possible case.
The code also adds explicit override behavior when merging top-level volumes, secrets and configs. Service merging requests slice append behavior alongside the existing transformations. These details show why updating a general merging library is insufficient by itself. Docker's loader still needs to express the intended rules for the configuration objects it handles.
A deployment assembled from several files depends on those rules even when each individual file is valid. The loader must determine what the combination means before the engine can apply it. In this case, the regression test records the intended meaning of an external-network override, so the result can be checked independently of a running cluster.
Bridge isolation uses two filtering stages
The networking update incorporates Libnetwork patch 2117. Its stated improvement reduces bridge isolation rule complexity from quadratic growth to twice the number of networks. The old code installed isolation rules between pairs of bridges. A host with more bridge networks therefore accumulated rules for their pairwise relationships.
The replacement uses DOCKER-ISOLATION-STAGE-1 and DOCKER-ISOLATION-STAGE-2. The first chain matches traffic arriving from a bridge and leaving through a different interface. Matching traffic enters the second chain, which drops it when the destination interface belongs to another bridge network. A nonmatch returns to the parent chain.
This decomposition lets each network contribute rules to the two stages without enumerating every other bridge. The patch's tests consequently check a source-interface rule and a destination drop rule for each network. Their assertions follow the new representation of the isolation policy.
I find the mechanism more informative than a general performance claim. Fewer rules as network count grows is a specific structural improvement, but the patch does not establish a throughput number for an arbitrary host. Its practical effect is that the rules implementing separation between bridge networks no longer require one relationship for every ordered pair. Operators examining the filter table will encounter two isolation chains whose entries correspond to individual bridge interfaces.