github.com/slene/docker@v1.8.0-rc1/docs/reference/api/hub_registry_spec.md (about) 1 <!--[metadata]> 2 +++ 3 title = "The Docker Hub and the Registry v1" 4 description = "Documentation for docker Registry and Registry API" 5 keywords = ["docker, registry, api, hub"] 6 [menu.main] 7 parent="smn_hub_ref" 8 +++ 9 <![end-metadata]--> 10 11 # The Docker Hub and the Registry v1 12 13 ## The three roles 14 15 There are three major components playing a role in the Docker ecosystem. 16 17 ### Docker Hub 18 19 The Docker Hub is responsible for centralizing information about: 20 21 - User accounts 22 - Checksums of the images 23 - Public namespaces 24 25 The Docker Hub has different components: 26 27 - Web UI 28 - Meta-data store (comments, stars, list public repositories) 29 - Authentication service 30 - Tokenization 31 32 The Docker Hub is authoritative for that information. 33 34 There is only one instance of the Docker Hub, run and 35 managed by Docker Inc. 36 37 ### Docker Registry 1.0 38 39 The 1.0 registry has the following characteristics: 40 41 - It stores the images and the graph for a set of repositories 42 - It does not have user accounts data 43 - It has no notion of user accounts or authorization 44 - It delegates authentication and authorization to the Docker Hub Auth 45 service using tokens 46 - It supports different storage backends (S3, cloud files, local FS) 47 - It doesn't have a local database 48 - [Source Code](https://github.com/docker/docker-registry) 49 50 We expect that there will be multiple registries out there. To help you 51 grasp the context, here are some examples of registries: 52 53 - **sponsor registry**: such a registry is provided by a third-party 54 hosting infrastructure as a convenience for their customers and the 55 Docker community as a whole. Its costs are supported by the third 56 party, but the management and operation of the registry are 57 supported by Docker, Inc. It features read/write access, and delegates 58 authentication and authorization to the Docker Hub. 59 - **mirror registry**: such a registry is provided by a third-party 60 hosting infrastructure but is targeted at their customers only. Some 61 mechanism (unspecified to date) ensures that public images are 62 pulled from a sponsor registry to the mirror registry, to make sure 63 that the customers of the third-party provider can `docker pull` 64 those images locally. 65 - **vendor registry**: such a registry is provided by a software 66 vendor who wants to distribute docker images. It would be operated 67 and managed by the vendor. Only users authorized by the vendor would 68 be able to get write access. Some images would be public (accessible 69 for anyone), others private (accessible only for authorized users). 70 Authentication and authorization would be delegated to the Docker Hub. 71 The goal of vendor registries is to let someone do `docker pull 72 basho/riak1.3` and automatically push from the vendor registry 73 (instead of a sponsor registry); i.e., vendors get all the convenience of a 74 sponsor registry, while retaining control on the asset distribution. 75 - **private registry**: such a registry is located behind a firewall, 76 or protected by an additional security layer (HTTP authorization, 77 SSL client-side certificates, IP address authorization...). The 78 registry is operated by a private entity, outside of Docker's 79 control. It can optionally delegate additional authorization to the 80 Docker Hub, but it is not mandatory. 81 82 > **Note:** The latter implies that while HTTP is the protocol 83 > of choice for a registry, multiple schemes are possible (and 84 > in some cases, trivial): 85 > 86 > - HTTP with GET (and PUT for read-write registries); 87 > - local mount point; 88 > - remote docker addressed through SSH. 89 90 The latter would only require two new commands in Docker, e.g., 91 `registryget` and `registryput`, 92 wrapping access to the local filesystem (and optionally doing 93 consistency checks). Authentication and authorization are then delegated 94 to SSH (e.g., with public keys). 95 96 ### Docker 97 98 On top of being a runtime for LXC, Docker is the Registry client. It 99 supports: 100 101 - Push / Pull on the registry 102 - Client authentication on the Docker Hub 103 104 ## Workflow 105 106 ### Pull 107 108 ![](/static_files/docker_pull_chart.png) 109 110 1. Contact the Docker Hub to know where I should download “samalba/busybox” 111 2. Docker Hub replies: a. `samalba/busybox` is on Registry A b. here are the 112 checksums for `samalba/busybox` (for all layers) c. token 113 3. Contact Registry A to receive the layers for `samalba/busybox` (all of 114 them to the base image). Registry A is authoritative for “samalba/busybox” 115 but keeps a copy of all inherited layers and serve them all from the same 116 location. 117 4. registry contacts Docker Hub to verify if token/user is allowed to download images 118 5. Docker Hub returns true/false lettings registry know if it should proceed or error 119 out 120 6. Get the payload for all layers 121 122 It's possible to run: 123 124 $ docker pull https://<registry>/repositories/samalba/busybox 125 126 In this case, Docker bypasses the Docker Hub. However the security is not 127 guaranteed (in case Registry A is corrupted) because there won't be any 128 checksum checks. 129 130 Currently registry redirects to s3 urls for downloads, going forward all 131 downloads need to be streamed through the registry. The Registry will 132 then abstract the calls to S3 by a top-level class which implements 133 sub-classes for S3 and local storage. 134 135 Token is only returned when the `X-Docker-Token` 136 header is sent with request. 137 138 Basic Auth is required to pull private repos. Basic auth isn't required 139 for pulling public repos, but if one is provided, it needs to be valid 140 and for an active account. 141 142 **API (pulling repository foo/bar):** 143 144 1. (Docker -> Docker Hub) GET /v1/repositories/foo/bar/images: 145 146 **Headers**: 147 148 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 149 X-Docker-Token: true 150 151 **Action**: 152 153 (looking up the foo/bar in db and gets images and checksums 154 for that repo (all if no tag is specified, if tag, only 155 checksums for those tags) see part 4.4.1) 156 157 2. (Docker Hub -> Docker) HTTP 200 OK 158 159 **Headers**: 160 161 Authorization: Token 162 signature=123abc,repository=”foo/bar”,access=write 163 X-Docker-Endpoints: registry.docker.io [,registry2.docker.io] 164 165 **Body**: 166 167 Jsonified checksums (see part 4.4.1) 168 169 3. (Docker -> Registry) GET /v1/repositories/foo/bar/tags/latest 170 171 **Headers**: 172 173 Authorization: Token 174 signature=123abc,repository=”foo/bar”,access=write 175 176 4. (Registry -> Docker Hub) GET /v1/repositories/foo/bar/images 177 178 **Headers**: 179 180 Authorization: Token 181 signature=123abc,repository=”foo/bar”,access=read 182 183 **Body**: 184 185 <ids and checksums in payload> 186 187 **Action**: 188 189 (Lookup token see if they have access to pull.) 190 191 If good: 192 HTTP 200 OK Docker Hub will invalidate the token 193 194 If bad: 195 HTTP 401 Unauthorized 196 197 5. (Docker -> Registry) GET /v1/images/928374982374/ancestry 198 199 **Action**: 200 201 (for each image id returned in the registry, fetch /json + /layer) 202 203 > **Note**: 204 > If someone makes a second request, then we will always give a new token, 205 > never reuse tokens. 206 207 ### Push 208 209 ![](/static_files/docker_push_chart.png) 210 211 1. Contact the Docker Hub to allocate the repository name “samalba/busybox” 212 (authentication required with user credentials) 213 2. If authentication works and namespace available, “samalba/busybox” 214 is allocated and a temporary token is returned (namespace is marked 215 as initialized in Docker Hub) 216 3. Push the image on the registry (along with the token) 217 4. Registry A contacts the Docker Hub to verify the token (token must 218 corresponds to the repository name) 219 5. Docker Hub validates the token. Registry A starts reading the stream 220 pushed by docker and store the repository (with its images) 221 6. docker contacts the Docker Hub to give checksums for upload images 222 223 > **Note:** 224 > **It's possible not to use the Docker Hub at all!** In this case, a deployed 225 > version of the Registry is deployed to store and serve images. Those 226 > images are not authenticated and the security is not guaranteed. 227 228 > **Note:** 229 > **Docker Hub can be replaced!** For a private Registry deployed, a custom 230 > Docker Hub can be used to serve and validate token according to different 231 > policies. 232 233 Docker computes the checksums and submit them to the Docker Hub at the end of 234 the push. When a repository name does not have checksums on the Docker Hub, 235 it means that the push is in progress (since checksums are submitted at 236 the end). 237 238 **API (pushing repos foo/bar):** 239 240 1. (Docker -> Docker Hub) PUT /v1/repositories/foo/bar/ 241 242 **Headers**: 243 244 Authorization: Basic sdkjfskdjfhsdkjfh== X-Docker-Token: 245 true 246 247 **Action**: 248 249 - in Docker Hub, we allocated a new repository, and set to 250 initialized 251 252 **Body**: 253 254 (The body contains the list of images that are going to be 255 pushed, with empty checksums. The checksums will be set at 256 the end of the push): 257 258 [{“id”: “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”}] 259 260 2. (Docker Hub -> Docker) 200 Created 261 262 **Headers**: 263 264 WWW-Authenticate: Token 265 signature=123abc,repository=”foo/bar”,access=write 266 X-Docker-Endpoints: registry.docker.io [, registry2.docker.io] 267 268 3. (Docker -> Registry) PUT /v1/images/98765432_parent/json 269 270 **Headers**: 271 272 Authorization: Token 273 signature=123abc,repository=”foo/bar”,access=write 274 275 4. (Registry->Docker Hub) GET /v1/repositories/foo/bar/images 276 277 **Headers**: 278 279 Authorization: Token 280 signature=123abc,repository=”foo/bar”,access=write 281 282 **Action**: 283 284 - Docker Hub: 285 will invalidate the token. 286 - Registry: 287 grants a session (if token is approved) and fetches 288 the images id 289 290 5. (Docker -> Registry) PUT /v1/images/98765432_parent/json 291 292 **Headers**: 293 294 Authorization: Token 295 signature=123abc,repository=”foo/bar”,access=write 296 Cookie: (Cookie provided by the Registry) 297 298 6. (Docker -> Registry) PUT /v1/images/98765432/json 299 300 **Headers**: 301 302 Cookie: (Cookie provided by the Registry) 303 304 7. (Docker -> Registry) PUT /v1/images/98765432_parent/layer 305 306 **Headers**: 307 308 Cookie: (Cookie provided by the Registry) 309 310 8. (Docker -> Registry) PUT /v1/images/98765432/layer 311 312 **Headers**: 313 314 X-Docker-Checksum: sha256:436745873465fdjkhdfjkgh 315 316 9. (Docker -> Registry) PUT /v1/repositories/foo/bar/tags/latest 317 318 **Headers**: 319 320 Cookie: (Cookie provided by the Registry) 321 322 **Body**: 323 324 “98765432” 325 326 10. (Docker -> Docker Hub) PUT /v1/repositories/foo/bar/images 327 328 **Headers**: 329 330 Authorization: Basic 123oislifjsldfj== X-Docker-Endpoints: 331 registry1.docker.io (no validation on this right now) 332 333 **Body**: 334 335 (The image, id`s, tags and checksums) 336 [{“id”: 337 “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”, 338 “checksum”: 339 “b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087”}] 340 341 **Return**: 342 343 HTTP 204 344 345 > **Note:** If push fails and they need to start again, what happens in the Docker Hub, 346 > there will already be a record for the namespace/name, but it will be 347 > initialized. Should we allow it, or mark as name already used? One edge 348 > case could be if someone pushes the same thing at the same time with two 349 > different shells. 350 351 If it's a retry on the Registry, Docker has a cookie (provided by the 352 registry after token validation). So the Docker Hub won't have to provide a 353 new token. 354 355 ### Delete 356 357 If you need to delete something from the Docker Hub or registry, we need a 358 nice clean way to do that. Here is the workflow. 359 360 1. Docker contacts the Docker Hub to request a delete of a repository 361 `samalba/busybox` (authentication required with user credentials) 362 2. If authentication works and repository is valid, `samalba/busybox` 363 is marked as deleted and a temporary token is returned 364 3. Send a delete request to the registry for the repository (along with 365 the token) 366 4. Registry A contacts the Docker Hub to verify the token (token must 367 corresponds to the repository name) 368 5. Docker Hub validates the token. Registry A deletes the repository and 369 everything associated to it. 370 6. docker contacts the Docker Hub to let it know it was removed from the 371 registry, the Docker Hub removes all records from the database. 372 373 > **Note**: 374 > The Docker client should present an "Are you sure?" prompt to confirm 375 > the deletion before starting the process. Once it starts it can't be 376 > undone. 377 378 **API (deleting repository foo/bar):** 379 380 1. (Docker -> Docker Hub) DELETE /v1/repositories/foo/bar/ 381 382 **Headers**: 383 384 Authorization: Basic sdkjfskdjfhsdkjfh== X-Docker-Token: 385 true 386 387 **Action**: 388 389 - in Docker Hub, we make sure it is a valid repository, and set 390 to deleted (logically) 391 392 **Body**: 393 394 Empty 395 396 2. (Docker Hub -> Docker) 202 Accepted 397 398 **Headers**: 399 400 WWW-Authenticate: Token 401 signature=123abc,repository=”foo/bar”,access=delete 402 X-Docker-Endpoints: registry.docker.io [, registry2.docker.io] 403 # list of endpoints where this repo lives. 404 405 3. (Docker -> Registry) DELETE /v1/repositories/foo/bar/ 406 407 **Headers**: 408 409 Authorization: Token 410 signature=123abc,repository=”foo/bar”,access=delete 411 412 4. (Registry->Docker Hub) PUT /v1/repositories/foo/bar/auth 413 414 **Headers**: 415 416 Authorization: Token 417 signature=123abc,repository=”foo/bar”,access=delete 418 419 **Action**: 420 421 - Docker Hub: 422 will invalidate the token. 423 - Registry: 424 deletes the repository (if token is approved) 425 426 5. (Registry -> Docker) 200 OK 427 428 200 If success 403 if forbidden 400 if bad request 404 429 if repository isn't found 430 431 6. (Docker -> Docker Hub) DELETE /v1/repositories/foo/bar/ 432 433 **Headers**: 434 435 Authorization: Basic 123oislifjsldfj== X-Docker-Endpoints: 436 registry-1.docker.io (no validation on this right now) 437 438 **Body**: 439 440 Empty 441 442 **Return**: 443 444 HTTP 200 445 446 ## How to use the Registry in standalone mode 447 448 The Docker Hub has two main purposes (along with its fancy social features): 449 450 - Resolve short names (to avoid passing absolute URLs all the time): 451 452 username/projectname -> 453 https://registry.docker.io/users/<username>/repositories/<projectname>/ 454 team/projectname -> 455 https://registry.docker.io/team/<team>/repositories/<projectname>/ 456 457 - Authenticate a user as a repos owner (for a central referenced 458 repository) 459 460 ### Without a Docker Hub 461 462 Using the Registry without the Docker Hub can be useful to store the images 463 on a private network without having to rely on an external entity 464 controlled by Docker Inc. 465 466 In this case, the registry will be launched in a special mode 467 (-standalone? ne? -no-index?). In this mode, the only thing which changes is 468 that Registry will never contact the Docker Hub to verify a token. It will be 469 the Registry owner responsibility to authenticate the user who pushes 470 (or even pulls) an image using any mechanism (HTTP auth, IP based, 471 etc...). 472 473 In this scenario, the Registry is responsible for the security in case 474 of data corruption since the checksums are not delivered by a trusted 475 entity. 476 477 As hinted previously, a standalone registry can also be implemented by 478 any HTTP server handling GET/PUT requests (or even only GET requests if 479 no write access is necessary). 480 481 ### With a Docker Hub 482 483 The Docker Hub data needed by the Registry are simple: 484 485 - Serve the checksums 486 - Provide and authorize a Token 487 488 In the scenario of a Registry running on a private network with the need 489 of centralizing and authorizing, it's easy to use a custom Docker Hub. 490 491 The only challenge will be to tell Docker to contact (and trust) this 492 custom Docker Hub. Docker will be configurable at some point to use a 493 specific Docker Hub, it'll be the private entity responsibility (basically 494 the organization who uses Docker in a private environment) to maintain 495 the Docker Hub and the Docker's configuration among its consumers. 496 497 ## The API 498 499 The first version of the api is available here: 500 [https://github.com/jpetazzo/docker/blob/acd51ecea8f5d3c02b00a08176171c59442df8b3/docs/images-repositories-push-pull.md](https://github.com/jpetazzo/docker/blob/acd51ecea8f5d3c02b00a08176171c59442df8b3/docs/images-repositories-push-pull.md) 501 502 ### Images 503 504 The format returned in the images is not defined here (for layer and 505 JSON), basically because Registry stores exactly the same kind of 506 information as Docker uses to manage them. 507 508 The format of ancestry is a line-separated list of image ids, in age 509 order, i.e. the image's parent is on the last line, the parent of the 510 parent on the next-to-last line, etc.; if the image has no parent, the 511 file is empty. 512 513 GET /v1/images/<image_id>/layer 514 PUT /v1/images/<image_id>/layer 515 GET /v1/images/<image_id>/json 516 PUT /v1/images/<image_id>/json 517 GET /v1/images/<image_id>/ancestry 518 PUT /v1/images/<image_id>/ancestry 519 520 ### Users 521 522 ### Create a user (Docker Hub) 523 524 POST /v1/users: 525 526 **Body**: 527 528 {"email": "[sam@docker.com](mailto:sam%40docker.com)", 529 "password": "toto42", "username": "foobar"`} 530 531 **Validation**: 532 533 - **username**: min 4 character, max 30 characters, must match the 534 regular expression [a-z0-9_]. 535 - **password**: min 5 characters 536 537 **Valid**: 538 539 return HTTP 201 540 541 Errors: HTTP 400 (we should create error codes for possible errors) - 542 invalid json - missing field - wrong format (username, password, email, 543 etc) - forbidden name - name already exists 544 545 > **Note**: 546 > A user account will be valid only if the email has been validated (a 547 > validation link is sent to the email address). 548 549 ### Update a user (Docker Hub) 550 551 PUT /v1/users/<username> 552 553 **Body**: 554 555 {"password": "toto"} 556 557 > **Note**: 558 > We can also update email address, if they do, they will need to reverify 559 > their new email address. 560 561 ### Login (Docker Hub) 562 563 Does nothing else but asking for a user authentication. Can be used to 564 validate credentials. HTTP Basic Auth for now, maybe change in future. 565 566 GET /v1/users 567 568 **Return**: 569 - Valid: HTTP 200 570 - Invalid login: HTTP 401 571 - Account inactive: HTTP 403 Account is not Active 572 573 ### Tags (Registry) 574 575 The Registry does not know anything about users. Even though 576 repositories are under usernames, it's just a namespace for the 577 registry. Allowing us to implement organizations or different namespaces 578 per user later, without modifying the Registry's API. 579 580 The following naming restrictions apply: 581 582 - Namespaces must match the same regular expression as usernames (See 583 4.2.1.) 584 - Repository names must match the regular expression [a-zA-Z0-9-_.] 585 586 ### Get all tags: 587 588 GET /v1/repositories/<namespace>/<repository_name>/tags 589 590 **Return**: HTTP 200 591 [ 592 { 593 "layer": "9e89cc6f", 594 "name": "latest" 595 }, 596 { 597 "layer": "b486531f", 598 "name": "0.1.1", 599 } 600 ] 601 602 **4.3.2 Read the content of a tag (resolve the image id):** 603 604 GET /v1/repositories/<namespace>/<repo_name>/tags/<tag> 605 606 **Return**: 607 608 "9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f" 609 610 **4.3.3 Delete a tag (registry):** 611 612 DELETE /v1/repositories/<namespace>/<repo_name>/tags/<tag> 613 614 ### 4.4 Images (Docker Hub) 615 616 For the Docker Hub to “resolve” the repository name to a Registry location, 617 it uses the X-Docker-Endpoints header. In other terms, this requests 618 always add a `X-Docker-Endpoints` to indicate the 619 location of the registry which hosts this repository. 620 621 **4.4.1 Get the images:** 622 623 GET /v1/repositories/<namespace>/<repo_name>/images 624 625 **Return**: HTTP 200 626 [{“id”: 627 “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”, 628 “checksum”: 629 “[md5:b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087](md5:b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087)”}] 630 631 ### Add/update the images: 632 633 You always add images, you never remove them. 634 635 PUT /v1/repositories/<namespace>/<repo_name>/images 636 637 **Body**: 638 639 [ {“id”: 640 “9e89cc6f0bc3c38722009fe6857087b486531f9a779a0c17e3ed29dae8f12c4f”, 641 “checksum”: 642 “sha256:b486531f9a779a0c17e3ed29dae8f12c4f9e89cc6f0bc3c38722009fe6857087”} 643 ] 644 645 **Return**: 646 647 204 648 649 ### Repositories 650 651 ### Remove a Repository (Registry) 652 653 DELETE /v1/repositories/<namespace>/<repo_name> 654 655 Return 200 OK 656 657 ### Remove a Repository (Docker Hub) 658 659 This starts the delete process. see 2.3 for more details. 660 661 DELETE /v1/repositories/<namespace>/<repo_name> 662 663 Return 202 OK 664 665 ## Chaining Registries 666 667 It's possible to chain Registries server for several reasons: 668 669 - Load balancing 670 - Delegate the next request to another server 671 672 When a Registry is a reference for a repository, it should host the 673 entire images chain in order to avoid breaking the chain during the 674 download. 675 676 The Docker Hub and Registry use this mechanism to redirect on one or the 677 other. 678 679 Example with an image download: 680 681 On every request, a special header can be returned: 682 683 X-Docker-Endpoints: server1,server2 684 685 On the next request, the client will always pick a server from this 686 list. 687 688 ## Authentication and authorization 689 690 ### On the Docker Hub 691 692 The Docker Hub supports both “Basic” and “Token” challenges. Usually when 693 there is a `401 Unauthorized`, the Docker Hub replies 694 this: 695 696 401 Unauthorized 697 WWW-Authenticate: Basic realm="auth required",Token 698 699 You have 3 options: 700 701 1. Provide user credentials and ask for a token 702 703 **Header**: 704 705 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 706 X-Docker-Token: true 707 708 In this case, along with the 200 response, you'll get a new token 709 (if user auth is ok): If authorization isn't correct you get a 401 710 response. If account isn't active you will get a 403 response. 711 712 **Response**: 713 714 200 OK 715 X-Docker-Token: Token 716 signature=123abc,repository=”foo/bar”,access=read 717 718 719 2. Provide user credentials only 720 721 **Header**: 722 723 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 724 725 3. Provide Token 726 727 **Header**: 728 729 Authorization: Token 730 signature=123abc,repository=”foo/bar”,access=read 731 732 ### 6.2 On the Registry 733 734 The Registry only supports the Token challenge: 735 736 401 Unauthorized 737 WWW-Authenticate: Token 738 739 The only way is to provide a token on `401 Unauthorized` 740 responses: 741 742 Authorization: Token signature=123abc,repository="foo/bar",access=read 743 744 Usually, the Registry provides a Cookie when a Token verification 745 succeeded. Every time the Registry passes a Cookie, you have to pass it 746 back the same cookie.: 747 748 200 OK 749 Set-Cookie: session="wD/J7LqL5ctqw8haL10vgfhrb2Q=?foo=UydiYXInCnAxCi4=×tamp=RjEzNjYzMTQ5NDcuNDc0NjQzCi4="; Path=/; HttpOnly 750 751 Next request: 752 753 GET /(...) 754 Cookie: session="wD/J7LqL5ctqw8haL10vgfhrb2Q=?foo=UydiYXInCnAxCi4=×tamp=RjEzNjYzMTQ5NDcuNDc0NjQzCi4=" 755 756 ## Document version 757 758 - 1.0 : May 6th 2013 : initial release 759 - 1.1 : June 1st 2013 : Added Delete Repository and way to handle new 760 source namespace. 761