If it uploads a container image we should make that available via the docker image interface so that you can use GitLab as a private container registry, an alternative to Docker Trusted Registry.
Instead of using the upload build artifacts function it might be easier to use native Docker upload functionality docker push my-registry:5000/my-image.
There is also an open source product from Docker that doesn't have a web interface, only an API https://github.com/docker/distribution and it is missing some functionality, such as deleting old images.
You guys might have a look at Portus, an open-source Docker Registry authentication service and web UI (also a rails app). You pair this up with an official registry:2 and you basically have an open-source Docker Hub. This is what I'm in the process of setting up for my current project.
@dzaporozhets@DouweM@JobV@stanhu@ayufan I believe that a docker registry is essential for a modern CI/CD workflow. We should ship one with GitLab for our on-premises customers.
@JobV please add to direction and schedule for 8.7?
We (@fh1ch@bachp@bufferoverflow) really like that idea and discussed this internally as well. The solution we had in mind is the following:
Use GitLab as an Authorization Service according to Docker distribution auth specification and configure a decoupled Docker Registry using this service, that can be shipped easily via omnibus.
So the main work from our perspective is:
add a JSON Web Token API endpoint to GitLab, e.g. /api/jwt
map group/repo concept and permissions from GitLab 1:1 to Docker, e.g. gitlab-org/gitlab-ce (git repo equals Docker Image name)
map the GitLab permissions roles used within GitLab to Docker Registry permissions, e.g:
I'm currently implementing wrapper for docker registry authentication as gitlab oauth2 application similar to what @bufferoverflow suggested.
I'm missing API call that would tell what access rights user has to a project. I know that user can see the project but not why. Owner is easy to detect others require more API calls (is namespace user or group, project members, group members, use highest access level) to determine push rights.
it requires to check how we should implement authentication,
it would make sense to present a list of images in GitLab interface,
we need to make sure that this will work on shared storage (not sure about that),
I like the concept of 1:1 repository mapping, but is it always true that one repository is exactly one docker image?
we need to think how to reliably delete docker images when project is deleted (we are introducing a separate component not connected with Rails, using external API) (this is important from security perspective),
we need to think how will it be exposed to outside world: should it use separate vhost or should it use separate IP/or/port?
other apps(e.g. npm registry) might use JSON Web Token as well in the future
a dedicated thing doing this simplifies testing and reuse
a Docker Registry client to
push images via GitLab CI e.g.
for tags such as gitlab-org/gitlab-ce:v8.7.1
if configured via UI for each build gitlab-org/gitlab-ce:BUILDNR? => lot of storage...maybe non-sense, but great for debugging things within Eclipse Che or similar thing(#12759 (closed)) at a later step
display Docker images within UI
manage Docker images within UI
delete images
tag images (e.g. gitlab-org/gitlab-ce:v8.7.1 = gitlab-org/gitlab-ce:stable)
The Docker registry shall be fully independent from a distribution point of view and be exposed via dedicated DNS and IP.
I guess many apps might use it without direct relation to GitLab and there will be more consumers than producers.
Some people might use other apps then GitLab CI to build Docker images and might love to use the Docker Registry that uses the GitLab based JSON Web Token Authorization Service for the registry.
@ayufan "I like the concept of 1:1 repository mapping, but is it always true that one repository is exactly one docker image?" => we'll maybe need multiple docker images per repository because the development and production ones are different. One interesting idea is to make add the development code in later stages of the Dockerfile so you can use a previous layer of the same docker image for production
I think that we can start with simple integration: integrated built-in Docker Registry, with 1-1 mapping, this will hold true for fairly long time. We can think later how to allow multiple images.
@bufferoverflow Excellent! Strong support for this!
@sytses@ayufan This is not even a dockerfile problem. How you solve that is secondary. There is one point about fetching and pulling though, that the registry is able to content address and match layers if they are in the same image name space and differ in tags only. so something like:
docker push registry/app:development and a posterior docker push registry/app:production would be ridiculously fast.
In any case, I strongly support flexible naming (it's not only about the image, it's about the tags!), so 1:1 mapping seems oversimplified.
The complicated part is repository vs registry vs image vs tag mapping. I don't believe it will be useful to integrate it into GitLab there is just too many use-cases and 1:1 mapping is just one very limited use-case.
@ayufan I made crude tool for authenticating via GitLab Oauth or private-token (fallback) and 1:1 mapping. No changes to GitLab were necessary. I used xanzy/go-gitlab, oauth2 and docker/distribution.
Mine last problem is how to integrate robot accounts without cluttering GitLab Users with robots.
@bufferoverflow I will make opensource registry authentication/authorization service for GitLab. But I need input on possible ACL use-cases and how to implement them. Our workflows are quite similar.
@mishak87 Do you share your WIP(work in progress) code somewhere?
I have some doubts if a dedicated service written in go is the way to go here, especially for a JSON Web Token based Authorization Service, which might be useful for a lot of other things beside of the the Docker use-case. JSON Web Token is the brother of OAuth and we do not now yet how they develop in the future. On the other side I see api scope and many other things in that area. I still believe that OAuth and JSON Web Token shall be brothers with the same mother(permission logic).
As far as I understand the architecture of GitLab currently(sorry, no deep dive until now), all the api things are handled via ruby within the GitLab core. How does the go app you are writing communicate with the core? Via OAuth api as far as I see, right?
1:1 mapping is a quick win and helps people to think about repo and naming structure. Of course there will be additional use-cases for other Docker Image Names, but as long as you are within your GitLab instance and the related Docker Registry, they should not collide with the repo namespace, otherwise many users might get confused on how things were built and deployed. If you want to push to gitlab/gitlab:stable , just create the group gitlab (or remove it as it is inactive anyway) and the master/owner will be able to push. Hmmm, might be worth to add a GitLab CI permission level as well.
A much more important thing I see is teams, e.g define teams that belong to several groups.
option to allow only specific CI runners to push images
SEMVER agnostic (tag latest, v0, v0.1, v0.1.0 from v0.1.0 git tag if it is the latest)
integration for platforms that pull images ie.: Rancher - could be circumvented by adding (fake)users for each environment.
@bufferoverflow Yes to authenticate accounts I use oauth because project access level is provided in API. I have not implemented anonymous yet since I don't need them and they require different approach.
There is no point in implementing JSON Web Token in Gitlab because it has only one scope api (read root access) and docker registry needs push and pull. So mapping must be done and that requires having an opinion.
I will be working on opensource version this week but first have to extend xanzy/go-gitlab API.
@sytses Basic principle of docker is that you use identical images for dev/prod. If you need something special for dev you should add it as a feature to the image. But this is out of topic. If you want help with that I would suggest asking on #docker IRC channel there is a lot of people that could help.
@mishak87 good to hear that it is best practise to use identical images. I wonder how this works for Rails apps, nice it is best practice not to bundle your testing gems for your production environment. Maybe dev/prod use different layers of the docker container? First do production install and then rebundle the gems for development?
The implementation is similar to the proposal by @bufferoverflow, but utilizes the group visibility of GitLab for determining the access level and maps them to namespaces (like Docker-Hub).
@sytses I am not confident that we will ship it. On the package side omnibus-gitlab#1218 (closed) I am running into issues while testing, basically it has been very unstable for now.
MR by @ayufan gitlab-org/gitlab-ce!3787 is still WIP but I will let Kamil answer about how confident he is about that part of code being ready.