Container Registry long term compatibility strategy
Context
So far the GitLab Container Registry fork has remained 100% API compatible with the upstream reference implementation from Docker.
More recently, we have started to see the need to implement new features and performance improvements that require changes to the registry API that are not part of the upstream reference implementation.
Although adding new features to the registry API isn’t a breaking change, the fact that we need to adopt those new features in GitLab can make GitLab incompatible with other registries.
Example
One of the priorities for 12.8 is to improve the performance of the delete API for the Container Registry front end. To fix this, we will have to port a pending upstream contribution for the registry that includes a new API for tag deletion. This contribution was reviewed in 2017 but never merged.
These changes represent a ~40% performance improvement on tag deletion. However, if they were merged as-is, GitLab wouldn’t be able to delete tags from other registries. Only the GitLab registry fork would be supported, as others don’t have the new tag delete API.
For this particular change, and until a decision is made about the subject of this issue, we can maintain compatibility with other registries by keeping the current delete method and only use the new improved method if the registry is the GitLab registry fork. However, doing something like this for all new features and improvements may not be feasible, maintainable or scalable.
This is just an example, as we have other efforts in progress that may require additional changes as well, like the distinction between Docker images and Helm charts.
Discussion
I believe the strategy and long term compatibility of GitLab with other container registries needs to be discussed.
Generally speaking, I see the following possibilities (no specific order):
-
Only add features/improvements if those don't break compatibility with other registries. All the necessary logic must be implemented in GitLab. No changes to the registry API would be allowed. The possibility of introducing new features and performance improvements would be severely constrained by this approach. The registry development would be limited to backstage changes.
-
Only add features to GitLab and the registry if it’s possible to implement a fallback behaviour for compatibility with other registries. The GitLab application would need to maintain a compatibility layer. As an example, for the tag delete improvements, this would mean keeping the current procedure as default and only use the new one if using the GitLab registry fork. This option would require a considerable effort from the development team to maintain the compatibility layer. Adding new features would be limited as well, as not all changes can be abstracted.
-
Freeze the current GitLab container registry integration/features, which is compatible with all registries that follow the reference implementation. No further changes would be implemented beyond bug and security fixes. In parallel, a new integration would be created to support all new features and performance improvements. New features would only be available when using the GitLab registry fork (thanks @nmezzopera for the suggestion).
-
Limit compatibility to the GitLab registry fork. No compatibility layer would be needed, but other registries wouldn’t be supported at all. Although this would be the most straightforward option in terms of development effort, it would limit the options.
To assess the best strategy, it would be good to have an estimate of the most used container registries.