Yes that would be great, thank you.
Hi all, the 7/24 deadline is tomorrow. Are there any outstanding blockers to execute “plan A”?
If yes, what are they?
Apologies for the late reply.
Here’s a summary of the main concerns expressed by maintainers at Docker:
- We need to find a URL we’re comfortable advertizing for packages like the API client library (possibly the most used one)
Why is this important before making the repo change?
Even though the repository was renamed to github.com/moby/moby, the import paths were not rewritten to moby/moby.
This is not an issue for contributors developing on the engine since it is done in a container with correct import paths.
However, it is an issue for developers importing our Go packages into their own projects, because they need to know to still use the old github.com/docker/docker URLs, which is not obvious. We can still enforce any import path we want with canonical import paths (Go feature). If we were to execute on the repo rename without solving this issue, it will not have cleared confusion.
- Renaming the Docker API to Moby Core API.
This is somewhat linked to the previous issue.
a) Today, there is an ecosystem around the Docker API, and there is a technical issue
since Docker 17.06 for vendoring docker-ce’s API client library: https://github.com/moby/moby/issues/33989
The point is, there are people who want to interact with the API as it is exposed by
the docker product.
Given that, and if we rename the Docker API to Moby Core API, it seems that we’d need
to ensure, that a released version of the Moby Core API client is compatible with
a released version of Docker. IOW, if there is a bugfix needed in the API types, or client library,
Moby Core maintainers will have to issue a bugfix source release (simply git tag)
before the Docker release can proceed. Otherwise, the API in docker’s product will differ from
the API in Moby Core.
Another possibility is to fork the API, which would bring a lot of confusion and questions
(such as when to use which).
We could also, consider moving the API out again and do git tag releases there.
This caused some pain in the past that could be alleviated with frequent (automated?) vendoring.
In the meantime, a docker.io URL could be used as a smart git proxy for the docker-ce repo (Brian is working on this)
b) There may be a risk of confusing users who look for the Docker API and are given an API called “Moby Core” in search results. Would we move all the API docs from docs.docker.com to a mobyproject URL ?
- Grace period needed to heavily inform the developers
Once we have a plan for the URLs we want to advertize, we should use all our communication tools to spread the word on the
new URLs. If we decide to use canonical import paths (Go feature), the new URLs can be enforced by Go too (it would error out if it’s imported using the wrong URLs).
These are the 3 main blockers. The first two being blockers for even a blogpost.
FWIW, the PR to rename the binaries to moby-core-* was opened https://github.com/moby/moby/pull/34226 and reviews are welcome.
No, because that would conflict with Docker’s use of
I’m a bit confused by the scope of these changes. I agree on moving the
moby/moby repository to
I agree this is something to be resolved, but given that the Moby project is an upstream to the Docker products, I feel that having an URL where people can get the exact version that’s used in the Docker products is something to be resolved outside of the Moby project.
Docker cherry-picks changes into their releases; all this is done outside of the Moby project; providing an URL for those packages would be a responsibiility of Docker.
If the Moby API switches to using SemVer, every change made to the API should result in a Major, Minor, or Patch version bump; Docker releases can pick a specific version (“compatible with Moby API x.y.z”). I don’t think we can always prevent cherry-picks to be needed in Docker’s releases (and not a responsibility of the Moby project); unless the Moby project plans on having a branch for each version of Moby’s API component, and do backports of bugfixes to those branches.
TL;DR for that is that it may not be just Docker using Moby as an upstream, other products may use Moby as an upstream as well, and we won’t be maintaining branches and stable URL’s for each product that uses Moby components (i.e. Moby project cannot keep track of exactly which patches/cherry-picks downstreams have). I think this is what’s described by:
There’s one thing I’m not sure about, and that’s naming the dependencies (
moby-core-containerd). The reason these binaries are currently prefixed is that Docker’s products sometimes cherry-pick changes into those binaries, thus they’re not vanilla upstreams. Without prefixing, the binaries could conflict with a vanilla version of those binaries installed on the same host. There’s two important parts here;
- If Moby-code won’t do releases (I don’t think this was decided yet), it won’t ship binaries, so naming is not important yet; the binaries will only be used in CI and during development.
- Unless Moby core is planning to fork these upstreams; is there actually a reason to have different names for these binaries (and not just
To be clear, this is not a matter of trademark enforcement. It’s a matter of engineering and user experience. It’s our responsibility to make the difference very clear between Moby Core and Docker; otherwise, users will be confused and have a bad experience.
This is equally important for Moby Core users and Docker users. Nobody wants “Dockerfile” to mean different things in different contexts. That would be catastrophically confusing.
I understand the rationale for this proposal, but I disagree with it, because it doesn’t resolve the tight coupling between the build feature in Moby Core and the Docker UX. Therefore it doesn’t resolve the confusion between Docker and Moby Core.
Let’s take things one step at a time, and do the following:
First things first, let’s finalize the split to Moby Core with the code we have today. Then the following statement will be true: “Docker implements a
buildfeature tied to a
Dockerfilespecification is controlled by Docker, but the build feature is currently implemented in Moby Core for historical reasons. This creates a tight coupling between Moby Core and the Docker UX, which is against the goals of the Moby project. In the future, this tight coupling will be removed, but the
docker buildfeature will be preserved.”
Once the split is finalized, Moby Core will gradually remove the dependency on the Docker-controlled
Dockerfilespec. My recommendation is to deprecate
buildin Moby Core altogether, and let higher-level layers implement it the way they want. This would make Moby Core more ecosystem-friendly. Docker would be one of the options for build, but other implementations would become first-class citizens, and would be free to be as compatible or incompatible with
docker buildas they wish. But this will require a debate with the other maintainers.
In parallel, Docker will gradually refactor its
docker buildimplementation to no longer require the
/buildendpoint in Moby Core. This will free Moby Core to remove its dependency on
Dockerfilewithout breaking continuity for Docker users. Note that this helps us respect the Independence Principle: Moby Core should not have its hands tied by the expectations of Docker users when deciding what to do with its build feature.
You are assuming a solution, which is to fork the API (even if slightly, for release purposes).
In that case we have to make it clear when to use which URLs. I understand your concern about separating project and product, hence why the decision is not easy. For instance, one could look at the REST API as being Docker-specific and we could experiment with new grpc APIs on Moby Core. This assumes NOT renaming Docker API to Moby Core API (contrary to plan A). One interesting note is, that deciding the latter does not mean that moving the API out of moby-core is a blocker. All we’d need to do is set up the docker.io URL Brian started and advertize that.
This and the VERSION number (some would prefer 0.x instead of 2.0), I did not consider them blockers. I agree with you on using upstream names without “moby-core” prefix but I realized that we can always change soon after, if we think that’s the right thing. Trying to avoid bikeshedding on names whenever possible.
It is planned for moby-core to do releases, except it’s simply a git tag in the source repo, and not a binary release.
Also, I’m assuming it is not needed to make a moby-core release for the repo name change, so figuring out all the details of a release is not a blocker either. My 2¢: I’m fine with
2.0.0 source releases, no binary releases, and I’m suggesting a flexible timed release (monthly) pretty much like in the early days of Docker.
For now, I will focus on this point which I will call Docker API vs Moby Core API. Once we resolve that, the other two points will be much easier to address.
Before anything, let’s agree on a few definitions:
Docker Engine is an open-source daemon and client formerly hosted at
github.com/docker/docker. It is being split between a daemon called Moby Core and a client called Docker Client or just
docker. As a result of this split, the name Docker Engine is being deprecated.
The Docker Engine API allows applications to interface with the Docker Engine daemon. It is being replaced by the Moby Core API.
Moby Core is the direct successor to the Docker Engine daemon, with a reduced scope (providing a modular base for other platforms to adapt and extend), open governance and emphasis on stability and modularity.
The Moby Core API allows applications to interface with the Moby Core daemon. It is the successor to the Docker Engine API.
The Docker API allows applications to interface with the entire Docker platform. For historical reasons, it is fragmented in several different APIs, including:
- the Docker Engine API (sometimes confusingly referred to as “The Docker API”)
- the Docker Registry API
- the Docker Hub API
- the Docker Cloud API
- the Docker Store API
- the DTR API
- the UCP API
- the Notary API
- the containerd API
- the SwarmKit API
- the Docker Compose Specification
- the Dockerfile specification
Because of this fragmentation, the Docker API is often confused with the Docker Engine API. However, they are very different. The Docker Engine API is defined by the scope of a single component, the Docker Engine. The Docker API is defined by the complete scope of the Docker platform.
Based on these definitions, I propose the following:
As part of the split of Docker Engine into Moby Core and Docker Client, let’s introduce the Moby Core API, and make it a well-documented, well-managed successor to the Docker Engine API. Let’s make sure to do this independently of Docker.
Let’s not maintain any API clients in Moby Core. Instead, let’s invest in making it very easy to generate Moby Core API clients from the Moby Core source code. We already use Swagger so we have a solid foundation to start from.
On the Docker side, let’s introduce a standalone Docker Devkit alongside each Docker CE release, with everything needed to develop against that version of Docker all in one place:
- An aggregate API documentation with sections for each component API in the release: Moby Core API, containerd API, Registry API, etc.
- A Go SDK with client libraries for each component API in the release. The SDK must be exposed at a URL that is stable, location-independent, and developer-friendly.
- SDKs in other languages as we add support for them.
- Other resources like development tools and code examples, tested against the release.
In particular, since Moby Core is a component of Docker CE, each release of the Docker Devkit will include:
- In the API documentation, a section for the Moby Core API, at the version included in the release.
- In the Go SDK, a client library for the Moby Core API that supports (at least) the version included in the release.
Let’s communicate clearly the following:
To the Moby community, that they can now target the Moby Core API in their downstream products without depending on Docker.
To the Docker community, that they can now target the Docker API more easily, and in a less fragmented way, thanks to the brand new Docker Devkit.
To developers importing Go libraries in
- If they’re specifically importing our Go client library for the Docker Engine API, they can now find it in the Docker SDK at a stable address. It will require a one-time change, but we will be careful to give them a smooth transition.
- If they’re importing any other library under
github.com/docker/docker, their application will soon break because of the repository change, and might break again later at any time because they are depending on a private interface of Moby Core. If they are comfortable with the risk, they should import the equivalent library in
github.com/moby/moby-core. If they are not, they should consider contributing the work necessary to make the interface public. The Moby Core maintainers will be happy to assist them.
3. Testing against your questions
Let’s try to answer your questions based on the definitions and actions I propose above:
Here’s what we know about the library and its URL, step by step:
- It will be part of the Docker Devkit, so its URL will be Docker-specific
- A new devkit is released with each Docker release, so the URL schema will include the Docker version
- SDKs must be exposed at a stable and location-independent URL, so it should not include implementation details such as
- SDKs must be exposed at a developer-friendly URL, so it should be short and intuitive
- At the moment the Docker API is really just a collection of component APIs: Moby Core API is the component we are concerned with here, but it will be just one component among others. The URL hierarchy should reflect that.
- My preference would be to optimize the URL
With that in mind, I think the answer is E) other. Here’s a strawman which I’m sure will cause strong bikeshedding reactions:
dockerdevkit.com/17.06-ce/gosdk/docker dockerdevkit.com/17.06-ce/gosdk/docker/mobycore dockerdevkit.com/17.06-ce/gosdk/docker/registry dockerdevkit.com/17.06-ce/gosdk/docker/containerd dockerdevkit.com/17.06-ce/gosdk/docker/hub dockerdevkit.com/17.06-ce/gosdk/docker/cloud
I think this is solved by introducing Docker Devkit, and with my proposed communication to developers importing
Note: @thaJeztah is correct that the responsibility to provide developers with the right client libraries for the rigth Docker release is with Docker, not with Moby Core. Here we are discussing actions needed on both sides to complete the split.
I think this is solved by introducing Docker Devkit, and with my proposed communication to Docker developers.
Yes, once we agree precisely on what to communicate, we need to communicate clearly, loudly and consistently. That is an essential part of the plan.
- Docker CE/EE continues to provide
/buildendpoint even after it is removed on Moby Core side.
- Moby Core (and Docker CE/EE) exposes BuildKit LLB endpoint, so that 3rd parties can develop image builder applications that are compatible with both Moby Core and Docker.
- BuildKit repo may contain Dockerfile->LLB translator as a dev tool. Docker product maintainers don’t need to use this translator (although they can if they like).
Docker will continue to offer the same
docker build feature, invest in improvements (which are sorely needed), and provide continuity for developers already using it. One possible way of providing continuity is by keeping the /build endpoint perfectly unchanged - but I don’t want to specify how to provide continuity, it will be up to the engineers responsible for build to decide that. As long as Docker users get continuity and a great UX, I’m happy.
I am not familiar with the design of BuildKit, and I have no idea what a LLB is, so I don’t have a competent opinion. More importantly, we should not make design and implementation choices at this level of detail right now. It will be up to the Moby Core maintainers to decide how to implement build going forward. It looks like you already have an opinion on that, so you should definitely participate in that design discussion when it takes place.
It looks like the answer is: yes there are still blockers.
So let’s define a new deadline, and try to stick to it. @mavenugo can you take the lead on this?
Yes. All the issues related to the blockers are marked as Priority/P1 (without a defined milestone) under https://github.com/moby/moby/projects/6?card_filter_query=label%3Apriority%2Fp1.
We will define the new deadline once we gain the confidence with the required changes that satisfies the requirements. Pls stay tuned.
Thank you Solomon for the clarifications.
Now let’s tackle the implementation and technical challenges.
Just like for Solomon’s example URLs, the URLs I’ll be using are only for getting specific points across. Please focus on the technical details only.
Version in URL can be inconvenient.
From a Go developer’s perspective, the only version that makes sense in an import path, is the sdk’s major version, which may or may not be the same as the API version, but is definitely not the Docker product’s version.
Here’s why: developer creates a Go library that imports “dockerdevkit.com/v17.06/go/mobycore”, but in v17.07 there is a new feature that they need to make use of, so they now need to change all import paths to v17.07, even in the files where the new feature was not used.
An additional minor annoyance is that their GOPATH will be growing with each client from each Docker release. The only time this is desirable, is if a new SDK is no longer backwards compatible with the previous one, hence why the major version of the SDK does make sense.
If having the SDK version in the URL is not desirable, then we probably should have no version at all in the URL. Instead, we could specify the Docker product’s version as a git tag in the git repo. The fact that Go has shortcomings specifying a git tag in a dependency is being worked on, and the workaround is README + vendoring. Either way, it is a known issue in the Go community.
Dependencies of the client package
The client package has the following dependencies today:
github.com/docker/docker/api github.com/docker/docker/api/types github.com/docker/docker/api/types/* github.com/docker/docker/pkg/ioutils github.com/docker/docker/pkg/mount github.com/docker/docker/pkg/system github.com/docker/docker/pkg/tlsconfig github.com/docker/distribution/digestset github.com/docker/distribution/reference github.com/docker/go-connections/nat github.com/docker/go-connections/sockets github.com/docker/go-connections/tlsconfig github.com/docker/go-units github.com/docker/libtrust github.com/gogo/protobuf/proto github.com/opencontainers/go-digest github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 github.com/pkg/errors golang.org/x/net/context golang.org/x/net/context/ctxhttp golang.org/x/net/proxy golang.org/x/sys/unix
The same Go issue comes up again: how to tell Go developers to use specific versions of these dependencies?
One unconventional way for a Go library, is to use the vendor directory. That’s the behavior the current users of
github.com/docker/docker/client rely on, because that repo also builds binaries.
I suggest, that until Go figures out dependency management, we provide a vendor/ folder in this library repository.
An alternative solution is to ensure that any dependency of the package stays stable, and we have CI in place to guard that assumption. If that’s the preferred solution, we need to evaluate which dependencies from github.com/docker/docker/ can be considered stable in the master branch.
After talking with Tonis, code in moby core can now depend on the session package from moby/buildkit. A PR will be sent to do just that.
Moby Core client package in Devkit vs in Moby Core
Let me call “devkit” the Go package downloadable from a docker URL, used to interact with the Moby Core API, and “client” the Go package that is used in Moby Core to interact with the Moby Core API.
One suggestion is to have devkit have the exact same content as client. The only import paths that may need updating is for dependencies that would be moved to the devkit package, most likely api/types.
Another suggestion is to wrap the client package by inlining the same functions and embedding the types. In that case, the Go developer would still depend on github.com/moby/moby-core/client.
So, do we want to make it a requirement for devkit to not depend on github.com/moby/moby-core ? In that case, what about the pkg/* dependencies? Should we follow up on moving at least those out as detailed in https://github.com/moby/moby/issues/32989 ?
Go get relies solely on VCS
We cannot just put files in an S3 bucket, because go get shells out to git (and other VCSes, but I’ll assume git). Thus we need to serve through whatever transport git supports. The most straightforward answer is a git repo.
One solution is to set up a git proxy that removes the
components/engine folder prefix from the docker-ce repo.
A much simpler solution is to create a git repo that gets updated at each Docker release. Given our current presence on Github, that seems like the most natural place for that git repo. The downside of a Github repo, is we’ll have to have an answer to people who want to contribute there instead of the docker-ce repo.
Should there be one big repo, or one git repo per API? Moby Core, Registry, Cloud, etc.
Either way, we would set up canonical import paths for the Go packages, to use:
dockerdevkit.com/go/mobycore, so that developers who stumble across the git(hub) repo and try to go get it or vendor it directly, have a nice error message prompting them to use the canonical import path.
Solomon suggested we start documenting the Moby Core API and host it on mobyproject.org That’s work to be done: sync with docs team, possibly clone their process, find+replace strings.
There’s also work to be done on the devkit side. Should the Moby Core part of it be a duplicate that’s kept in sync with mobyproject.org or should it simply have the SDK documentations, but link to mobyproject.org for the full HTTP API?
The latter could be interesting, especially if we want some features of the HTTP API to not be exposed by devkit’s mobycore client.
Moby core releases and versioning
I don’t think having Moby Core releases is a blocker for renaming the repo, but it would be great to at least resolve the VERSION issue, because right now it is still
Anybody building moby core should be able to set the version to whatever they like. But for the default, here are the options:
- we set it to
- we decide on an actual version we’d like to release for Moby Core:
This would highlight an evolution
This would highlight a reboot.
I personally don’t have a strong opinion on this.
I’ll update the PR (https://github.com/moby/moby/pull/34226) with changes requested by Akihiro, namely changing the help output to also mention the new binary names.
Please answer with thoughts and concerns, or if you think I forgot to mention something important.
I see 2 issues with this URL naming scheme-
- the relationship between dockerdevkit.com and docker.com is not clear
- finding a new URL is always a challenge as no one knows what to look for
While people are getting familiar with our other properties like mobyproject.org, containerd.io, I suggest we not burden them with remembering another new URL. In line with that, I propose a sub-domain option instead:
Does that work?
After further discussion on this subject, 2 interesting points came to light:
- DevKit = Docker HTTP REST APIs + Docker language specific client libraries
- we have used the kit moniker exclusively for Open Source Projects
Given that DevKit is tied more to the Docker CE/EE product at this time, another suggestion is to just call it the Docker SDK. SDK has the added benefit of being extremely well understood with a clear meaning that’s industry standard.
I’m working on setting up a
golang.docker.io URL to become a Go SDK for Docker (we decided to drop the name DevKit for this), with the usual client package for the Engine API, but also other packages for the entire Docker platform. I’m adding registry, and notary, but we’d like to add UCP, DTR, Store etc. as well in the future.
It will be semver’d starting v1.0.0 for 17.06. Not sure if we should also add a 17.06 tag (or
docker-17.06) in addition to semver.
So packages are becoming something like
golang.docker.io/docker/docker/cli or even
I haven’t really got your point about versioning though.
Are we not adding the usual -ce suffix because it’s already known as open source by the url?
And how people manage to get the “enterprise” client?
I mean, if one wants to write a software which interacts with the enterprise edition she/he will use another client or just the one at
Yes that seems correct, except that I wpuld prefer to see the name
go-docker spelled out in the URL.
The URL is for
go-docker, the official Docker Go SDK. It has only one version, which supports all Docker APIs, including for EE services like DTR. Therefore there is no need for a CE/EE split of the SDK.
Ok makes sense,
at which level do you see the
The second could be trivial in case that the user import the top level package (which doesn’t currently exist)
It would be
go-docker is the client.