diff --git a/_vendor/github.com/distribution/distribution/docs/README.md b/_vendor/github.com/distribution/distribution/docs/README.md deleted file mode 100644 index b26dc37545a..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# The docs have been moved! - -The documentation for Registry has been merged into -[the general documentation repo](https://github.com/docker/docker.github.io). -Commit history has been preserved. - -The docs for Registry are now here: -https://github.com/docker/docker.github.io/tree/master/registry - -> Note: The definitive [./spec directory](spec/) directory and -[configuration.md](configuration.md) file will be maintained in this repository -and be refreshed periodically in -[the general documentation repo](https://github.com/docker/docker.github.io). - -As always, the docs in the general repo remain open-source and we appreciate -your feedback and pull requests! diff --git a/_vendor/github.com/distribution/distribution/docs/architecture.md b/_vendor/github.com/distribution/distribution/docs/architecture.md deleted file mode 100644 index c2aaa9f2d7a..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/architecture.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -published: false ---- - -# Architecture - -## Design -**TODO(stevvooe):** Discuss the architecture of the registry, internally and externally, in a few different deployment scenarios. - -### Eventual Consistency - -> **NOTE:** This section belongs somewhere, perhaps in a design document. We -> are leaving this here so the information is not lost. - -Running the registry on eventually consistent backends has been part of the -design from the beginning. This section covers some of the approaches to -dealing with this reality. - -There are a few classes of issues that we need to worry about when -implementing something on top of the storage drivers: - -1. Read-After-Write consistency (see this [article on - s3](http://shlomoswidler.com/2009/12/read-after-write-consistency-in-amazon.html)). -2. [Write-Write Conflicts](http://en.wikipedia.org/wiki/Write%E2%80%93write_conflict). - -In reality, the registry must worry about these kinds of errors when doing the -following: - -1. Accepting data into a temporary upload file may not have latest data block - yet (read-after-write). -2. Moving uploaded data into its blob location (write-write race). -3. Modifying the "current" manifest for given tag (write-write race). -4. A whole slew of operations around deletes (read-after-write, delete-write - races, garbage collection, etc.). - -The backend path layout employs a few techniques to avoid these problems: - -1. Large writes are done to private upload directories. This alleviates most - of the corruption potential under multiple writers by avoiding multiple - writers. -2. Constraints in storage driver implementations, such as support for writing - after the end of a file to extend it. -3. Digest verification to avoid data corruption. -4. Manifest files are stored by digest and cannot change. -5. All other non-content files (links, hashes, etc.) are written as an atomic - unit. Anything that requires additions and deletions is broken out into - separate "files". Last writer still wins. - -Unfortunately, one must play this game when trying to build something like -this on top of eventually consistent storage systems. If we run into serious -problems, we can wrap the storagedrivers in a shared consistency layer but -that would increase complexity and hinder registry cluster performance. diff --git a/_vendor/github.com/distribution/distribution/docs/configuration.md b/_vendor/github.com/distribution/distribution/docs/configuration.md deleted file mode 100644 index 75f52deaa1b..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/configuration.md +++ /dev/null @@ -1,1269 +0,0 @@ ---- -title: "Configuring a registry" -description: "Explains how to configure a registry" -keywords: registry, on-prem, images, tags, repository, distribution, configuration ---- - -The Registry configuration is based on a YAML file, detailed below. While it -comes with sane default values out of the box, you should review it exhaustively -before moving your systems to production. - -## Override specific configuration options - -In a typical setup where you run your Registry from the official image, you can -specify a configuration variable from the environment by passing `-e` arguments -to your `docker run` stanza or from within a Dockerfile using the `ENV` -instruction. - -To override a configuration option, create an environment variable named -`REGISTRY_variable` where `variable` is the name of the configuration option -and the `_` (underscore) represents indention levels. For example, you can -configure the `rootdirectory` of the `filesystem` storage backend: - -```none -storage: - filesystem: - rootdirectory: /var/lib/registry -``` - -To override this value, set an environment variable like this: - -```none -REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/somewhere -``` - -This variable overrides the `/var/lib/registry` value to the `/somewhere` -directory. - -> **Note**: Create a base configuration file with environment variables that can -> be configured to tweak individual values. Overriding configuration sections -> with environment variables is not recommended. - -## Overriding the entire configuration file - -If the default configuration is not a sound basis for your usage, or if you are -having issues overriding keys from the environment, you can specify an alternate -YAML configuration file by mounting it as a volume in the container. - -Typically, create a new configuration file from scratch,named `config.yml`, then -specify it in the `docker run` command: - -```bash -$ docker run -d -p 5000:5000 --restart=always --name registry \ - -v `pwd`/config.yml:/etc/docker/registry/config.yml \ - registry:2 -``` - -Use this -[example YAML file](https://github.com/docker/distribution/blob/master/cmd/registry/config-example.yml) -as a starting point. - -## List of configuration options - -These are all configuration options for the registry. Some options in the list -are mutually exclusive. Read the detailed reference information about each -option before finalizing your configuration. - -```none -version: 0.1 -log: - accesslog: - disabled: true - level: debug - formatter: text - fields: - service: registry - environment: staging - hooks: - - type: mail - disabled: true - levels: - - panic - options: - smtp: - addr: mail.example.com:25 - username: mailuser - password: password - insecure: true - from: sender@example.com - to: - - errors@example.com -loglevel: debug # deprecated: use "log" -storage: - filesystem: - rootdirectory: /var/lib/registry - maxthreads: 100 - azure: - accountname: accountname - accountkey: base64encodedaccountkey - container: containername - gcs: - bucket: bucketname - keyfile: /path/to/keyfile - credentials: - type: service_account - project_id: project_id_string - private_key_id: private_key_id_string - private_key: private_key_string - client_email: client@example.com - client_id: client_id_string - auth_uri: http://example.com/auth_uri - token_uri: http://example.com/token_uri - auth_provider_x509_cert_url: http://example.com/provider_cert_url - client_x509_cert_url: http://example.com/client_cert_url - rootdirectory: /gcs/object/name/prefix - chunksize: 5242880 - s3: - accesskey: awsaccesskey - secretkey: awssecretkey - region: us-west-1 - regionendpoint: http://myobjects.local - bucket: bucketname - encrypt: true - keyid: mykeyid - secure: true - v4auth: true - chunksize: 5242880 - multipartcopychunksize: 33554432 - multipartcopymaxconcurrency: 100 - multipartcopythresholdsize: 33554432 - rootdirectory: /s3/object/name/prefix - swift: - username: username - password: password - authurl: https://storage.myprovider.com/auth/v1.0 or https://storage.myprovider.com/v2.0 or https://storage.myprovider.com/v3/auth - tenant: tenantname - tenantid: tenantid - domain: domain name for Openstack Identity v3 API - domainid: domain id for Openstack Identity v3 API - insecureskipverify: true - region: fr - container: containername - rootdirectory: /swift/object/name/prefix - oss: - accesskeyid: accesskeyid - accesskeysecret: accesskeysecret - region: OSS region name - endpoint: optional endpoints - internal: optional internal endpoint - bucket: OSS bucket - encrypt: optional data encryption setting - secure: optional ssl setting - chunksize: optional size valye - rootdirectory: optional root directory - inmemory: # This driver takes no parameters - delete: - enabled: false - redirect: - disable: false - cache: - blobdescriptor: redis - maintenance: - uploadpurging: - enabled: true - age: 168h - interval: 24h - dryrun: false - readonly: - enabled: false -auth: - silly: - realm: silly-realm - service: silly-service - token: - autoredirect: true - realm: token-realm - service: token-service - issuer: registry-token-issuer - rootcertbundle: /root/certs/bundle - htpasswd: - realm: basic-realm - path: /path/to/htpasswd -middleware: - registry: - - name: ARegistryMiddleware - options: - foo: bar - repository: - - name: ARepositoryMiddleware - options: - foo: bar - storage: - - name: cloudfront - options: - baseurl: https://my.cloudfronted.domain.com/ - privatekey: /path/to/pem - keypairid: cloudfrontkeypairid - duration: 3000s - ipfilteredby: awsregion - awsregion: us-east-1, use-east-2 - updatefrenquency: 12h - iprangesurl: https://ip-ranges.amazonaws.com/ip-ranges.json - storage: - - name: redirect - options: - baseurl: https://example.com/ -reporting: - bugsnag: - apikey: bugsnagapikey - releasestage: bugsnagreleasestage - endpoint: bugsnagendpoint - newrelic: - licensekey: newreliclicensekey - name: newrelicname - verbose: true -http: - addr: localhost:5000 - prefix: /my/nested/registry/ - host: https://myregistryaddress.org:5000 - secret: asecretforlocaldevelopment - relativeurls: false - draintimeout: 60s - tls: - certificate: /path/to/x509/public - key: /path/to/x509/private - clientcas: - - /path/to/ca.pem - - /path/to/another/ca.pem - letsencrypt: - cachefile: /path/to/cache-file - email: emailused@letsencrypt.com - hosts: [myregistryaddress.org] - debug: - addr: localhost:5001 - prometheus: - enabled: true - path: /metrics - headers: - X-Content-Type-Options: [nosniff] - http2: - disabled: false -notifications: - events: - includereferences: true - endpoints: - - name: alistener - disabled: false - url: https://my.listener.com/event - headers: - timeout: 1s - threshold: 10 - backoff: 1s - ignoredmediatypes: - - application/octet-stream - ignore: - mediatypes: - - application/octet-stream - actions: - - pull -redis: - addr: localhost:6379 - password: asecret - db: 0 - dialtimeout: 10ms - readtimeout: 10ms - writetimeout: 10ms - pool: - maxidle: 16 - maxactive: 64 - idletimeout: 300s -health: - storagedriver: - enabled: true - interval: 10s - threshold: 3 - file: - - file: /path/to/checked/file - interval: 10s - http: - - uri: http://server.to.check/must/return/200 - headers: - Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==] - statuscode: 200 - timeout: 3s - interval: 10s - threshold: 3 - tcp: - - addr: redis-server.domain.com:6379 - timeout: 3s - interval: 10s - threshold: 3 -proxy: - remoteurl: https://registry-1.docker.io - username: [username] - password: [password] -compatibility: - schema1: - signingkeyfile: /etc/registry/key.json - enabled: true -validation: - manifests: - urls: - allow: - - ^https?://([^/]+\.)*example\.com/ - deny: - - ^https?://www\.example\.com/ -``` - -In some instances a configuration option is **optional** but it contains child -options marked as **required**. In these cases, you can omit the parent with -all its children. However, if the parent is included, you must also include all -the children marked **required**. - -## `version` - -```none -version: 0.1 -``` - -The `version` option is **required**. It specifies the configuration's version. -It is expected to remain a top-level field, to allow for a consistent version -check before parsing the remainder of the configuration file. - -## `log` - -The `log` subsection configures the behavior of the logging system. The logging -system outputs everything to stdout. You can adjust the granularity and format -with this configuration section. - -```none -log: - accesslog: - disabled: true - level: debug - formatter: text - fields: - service: registry - environment: staging -``` - -| Parameter | Required | Description | -|-------------|----------|-------------| -| `level` | no | Sets the sensitivity of logging output. Permitted values are `error`, `warn`, `info`, and `debug`. The default is `info`. | -| `formatter` | no | This selects the format of logging output. The format primarily affects how keyed attributes for a log line are encoded. Options are `text`, `json`, and `logstash`. The default is `text`. | -| `fields` | no | A map of field names to values. These are added to every log line for the context. This is useful for identifying log messages source after being mixed in other systems. | - -### `accesslog` - -```none -accesslog: - disabled: true -``` - -Within `log`, `accesslog` configures the behavior of the access logging -system. By default, the access logging system outputs to stdout in -[Combined Log Format](https://httpd.apache.org/docs/2.4/logs.html#combined). -Access logging can be disabled by setting the boolean flag `disabled` to `true`. - -## `hooks` - -```none -hooks: - - type: mail - levels: - - panic - options: - smtp: - addr: smtp.sendhost.com:25 - username: sendername - password: password - insecure: true - from: name@sendhost.com - to: - - name@receivehost.com -``` - -The `hooks` subsection configures the logging hooks' behavior. This subsection -includes a sequence handler which you can use for sending mail, for example. -Refer to `loglevel` to configure the level of messages printed. - -## `loglevel` - -> **DEPRECATED:** Please use [log](#log) instead. - -```none -loglevel: debug -``` - -Permitted values are `error`, `warn`, `info` and `debug`. The default is -`info`. - -## `storage` - -```none -storage: - filesystem: - rootdirectory: /var/lib/registry - azure: - accountname: accountname - accountkey: base64encodedaccountkey - container: containername - gcs: - bucket: bucketname - keyfile: /path/to/keyfile - credentials: - type: service_account - project_id: project_id_string - private_key_id: private_key_id_string - private_key: private_key_string - client_email: client@example.com - client_id: client_id_string - auth_uri: http://example.com/auth_uri - token_uri: http://example.com/token_uri - auth_provider_x509_cert_url: http://example.com/provider_cert_url - client_x509_cert_url: http://example.com/client_cert_url - rootdirectory: /gcs/object/name/prefix - s3: - accesskey: awsaccesskey - secretkey: awssecretkey - region: us-west-1 - regionendpoint: http://myobjects.local - bucket: bucketname - encrypt: true - keyid: mykeyid - secure: true - v4auth: true - chunksize: 5242880 - multipartcopychunksize: 33554432 - multipartcopymaxconcurrency: 100 - multipartcopythresholdsize: 33554432 - rootdirectory: /s3/object/name/prefix - swift: - username: username - password: password - authurl: https://storage.myprovider.com/auth/v1.0 or https://storage.myprovider.com/v2.0 or https://storage.myprovider.com/v3/auth - tenant: tenantname - tenantid: tenantid - domain: domain name for Openstack Identity v3 API - domainid: domain id for Openstack Identity v3 API - insecureskipverify: true - region: fr - container: containername - rootdirectory: /swift/object/name/prefix - oss: - accesskeyid: accesskeyid - accesskeysecret: accesskeysecret - region: OSS region name - endpoint: optional endpoints - internal: optional internal endpoint - bucket: OSS bucket - encrypt: optional data encryption setting - secure: optional ssl setting - chunksize: optional size valye - rootdirectory: optional root directory - inmemory: - delete: - enabled: false - cache: - blobdescriptor: inmemory - maintenance: - uploadpurging: - enabled: true - age: 168h - interval: 24h - dryrun: false - readonly: - enabled: false - redirect: - disable: false -``` - -The `storage` option is **required** and defines which storage backend is in -use. You must configure exactly one backend. If you configure more, the registry -returns an error. You can choose any of these backend storage drivers: - -| Storage driver | Description | -|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `filesystem` | Uses the local disk to store registry files. It is ideal for development and may be appropriate for some small-scale production applications. See the [driver's reference documentation](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/filesystem.md). | -| `azure` | Uses Microsoft Azure Blob Storage. See the [driver's reference documentation](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/azure.md). | -| `gcs` | Uses Google Cloud Storage. See the [driver's reference documentation](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/gcs.md). | -| `s3` | Uses Amazon Simple Storage Service (S3) and compatible Storage Services. See the [driver's reference documentation](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/s3.md). | -| `swift` | Uses Openstack Swift object storage. See the [driver's reference documentation](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/swift.md). | -| `oss` | Uses Aliyun OSS for object storage. See the [driver's reference documentation](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/oss.md). | - -For testing only, you can use the [`inmemory` storage -driver](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/inmemory.md). -If you would like to run a registry from volatile memory, use the -[`filesystem` driver](https://github.com/docker/docker.github.io/tree/master/registry/storage-drivers/filesystem.md) -on a ramdisk. - -If you are deploying a registry on Windows, a Windows volume mounted from the -host is not recommended. Instead, you can use a S3 or Azure backing -data-store. If you do use a Windows volume, the length of the `PATH` to -the mount point must be within the `MAX_PATH` limits (typically 255 characters), -or this error will occur: - -```none -mkdir /XXX protocol error and your registry will not function properly. -``` - -### `maintenance` - -Currently, upload purging and read-only mode are the only `maintenance` -functions available. - -### `uploadpurging` - -Upload purging is a background process that periodically removes orphaned files -from the upload directories of the registry. Upload purging is enabled by -default. To configure upload directory purging, the following parameters must -be set. - - -| Parameter | Required | Description | -|------------|----------|----------------------------------------------------------------------------------------------------| -| `enabled` | yes | Set to `true` to enable upload purging. Defaults to `true`. | -| `age` | yes | Upload directories which are older than this age will be deleted.Defaults to `168h` (1 week). | -| `interval` | yes | The interval between upload directory purging. Defaults to `24h`. | -| `dryrun` | yes | Set `dryrun` to `true` to obtain a summary of what directories will be deleted. Defaults to `false`.| - -> **Note**: `age` and `interval` are strings containing a number with optional -fraction and a unit suffix. Some examples: `45m`, `2h10m`, `168h`. - -### `readonly` - -If the `readonly` section under `maintenance` has `enabled` set to `true`, -clients will not be allowed to write to the registry. This mode is useful to -temporarily prevent writes to the backend storage so a garbage collection pass -can be run. Before running garbage collection, the registry should be -restarted with readonly's `enabled` set to true. After the garbage collection -pass finishes, the registry may be restarted again, this time with `readonly` -removed from the configuration (or set to false). - -### `delete` - -Use the `delete` structure to enable the deletion of image blobs and manifests -by digest. It defaults to false, but it can be enabled by writing the following -on the configuration file: - -```none -delete: - enabled: true -``` - -### `cache` - -Use the `cache` structure to enable caching of data accessed in the storage -backend. Currently, the only available cache provides fast access to layer -metadata, which uses the `blobdescriptor` field if configured. - -You can set `blobdescriptor` field to `redis` or `inmemory`. If set to `redis`,a -Redis pool caches layer metadata. If set to `inmemory`, an in-memory map caches -layer metadata. - -> **NOTE**: Formerly, `blobdescriptor` was known as `layerinfo`. While these -> are equivalent, `layerinfo` has been deprecated. - -### `redirect` - -The `redirect` subsection provides configuration for managing redirects from -content backends. For backends that support it, redirecting is enabled by -default. In certain deployment scenarios, you may decide to route all data -through the Registry, rather than redirecting to the backend. This may be more -efficient when using a backend that is not co-located or when a registry -instance is aggressively caching. - -To disable redirects, add a single flag `disable`, set to `true` -under the `redirect` section: - -```none -redirect: - disable: true -``` - -## `auth` - -```none -auth: - silly: - realm: silly-realm - service: silly-service - token: - realm: token-realm - service: token-service - issuer: registry-token-issuer - rootcertbundle: /root/certs/bundle - htpasswd: - realm: basic-realm - path: /path/to/htpasswd -``` - -The `auth` option is **optional**. Possible auth providers include: - -- [`silly`](#silly) -- [`token`](#token) -- [`htpasswd`](#htpasswd) -- [`none`] - -You can configure only one authentication provider. - -### `silly` - -The `silly` authentication provider is only appropriate for development. It simply checks -for the existence of the `Authorization` header in the HTTP request. It does not -check the header's value. If the header does not exist, the `silly` auth -responds with a challenge response, echoing back the realm, service, and scope -for which access was denied. - -The following values are used to configure the response: - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `realm` | yes | The realm in which the registry server authenticates. | -| `service` | yes | The service being authenticated. | - -### `token` - -Token-based authentication allows you to decouple the authentication system from -the registry. It is an established authentication paradigm with a high degree of -security. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `realm` | yes | The realm in which the registry server authenticates. | -| `service` | yes | The service being authenticated. | -| `issuer` | yes | The name of the token issuer. The issuer inserts this into the token so it must match the value configured for the issuer. | -| `rootcertbundle` | yes | The absolute path to the root certificate bundle. This bundle contains the public part of the certificates used to sign authentication tokens. | -| `autoredirect` | no | When set to `true`, `realm` will automatically be set using the Host header of the request as the domain and a path of `/auth/token/`| - - -For more information about Token based authentication configuration, see the -[specification](spec/auth/token.md). - -### `htpasswd` - -The _htpasswd_ authentication backed allows you to configure basic -authentication using an -[Apache htpasswd file](https://httpd.apache.org/docs/2.4/programs/htpasswd.html). -The only supported password format is -[`bcrypt`](http://en.wikipedia.org/wiki/Bcrypt). Entries with other hash types -are ignored. The `htpasswd` file is loaded once, at startup. If the file is -invalid, the registry will display an error and will not start. - -> **Warning**: If the `htpasswd` file is missing, the file will be created and provisioned with a default user and automatically generated password. -> The password will be printed to stdout. - -> **Warning**: Only use the `htpasswd` authentication scheme with TLS -> configured, since basic authentication sends passwords as part of the HTTP -> header. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `realm` | yes | The realm in which the registry server authenticates. | -| `path` | yes | The path to the `htpasswd` file to load at startup. | - -## `middleware` - -The `middleware` structure is **optional**. Use this option to inject middleware at -named hook points. Each middleware must implement the same interface as the -object it is wrapping. For instance, a registry middleware must implement the -`distribution.Namespace` interface, while a repository middleware must implement -`distribution.Repository`, and a storage middleware must implement -`driver.StorageDriver`. - -This is an example configuration of the `cloudfront` middleware, a storage -middleware: - -```none -middleware: - registry: - - name: ARegistryMiddleware - options: - foo: bar - repository: - - name: ARepositoryMiddleware - options: - foo: bar - storage: - - name: cloudfront - options: - baseurl: https://my.cloudfronted.domain.com/ - privatekey: /path/to/pem - keypairid: cloudfrontkeypairid - duration: 3000s - ipfilteredby: awsregion - awsregion: us-east-1, use-east-2 - updatefrenquency: 12h - iprangesurl: https://ip-ranges.amazonaws.com/ip-ranges.json -``` - -Each middleware entry has `name` and `options` entries. The `name` must -correspond to the name under which the middleware registers itself. The -`options` field is a map that details custom configuration required to -initialize the middleware. It is treated as a `map[string]interface{}`. As such, -it supports any interesting structures desired, leaving it up to the middleware -initialization function to best determine how to handle the specific -interpretation of the options. - -### `cloudfront` - - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `baseurl` | yes | The `SCHEME://HOST[/PATH]` at which Cloudfront is served. | -| `privatekey` | yes | The private key for Cloudfront, provided by AWS. | -| `keypairid` | yes | The key pair ID provided by AWS. | -| `duration` | no | An integer and unit for the duration of the Cloudfront session. Valid time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, or `h`. For example, `3000s` is valid, but `3000 s` is not. If you do not specify a `duration` or you specify an integer without a time unit, the duration defaults to `20m` (20 minutes). | -| `ipfilteredby` | no | A string with the following value `none`, `aws` or `awsregion`. | -| `awsregion` | no | A comma separated string of AWS regions, only available when `ipfilteredby` is `awsregion`. For example, `us-east-1, us-west-2` | -| `updatefrenquency` | no | The frequency to update AWS IP regions, default: `12h` | -| `iprangesurl` | no | The URL contains the AWS IP ranges information, default: `https://ip-ranges.amazonaws.com/ip-ranges.json` | - - -Value of `ipfilteredby` can be: - -| Value | Description | -|-------------|------------------------------------| -| `none` | default, do not filter by IP | -| `aws` | IP from AWS goes to S3 directly | -| `awsregion` | IP from certain AWS regions goes to S3 directly, use together with `awsregion`. | - -### `redirect` - -You can use the `redirect` storage middleware to specify a custom URL to a -location of a proxy for the layer stored by the S3 storage driver. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------------------------------------------------------------| -| `baseurl` | yes | `SCHEME://HOST` at which layers are served. Can also contain port. For example, `https://example.com:5443`. | - -## `reporting` - -``` -reporting: - bugsnag: - apikey: bugsnagapikey - releasestage: bugsnagreleasestage - endpoint: bugsnagendpoint - newrelic: - licensekey: newreliclicensekey - name: newrelicname - verbose: true -``` - -The `reporting` option is **optional** and configures error and metrics -reporting tools. At the moment only two services are supported: - -- [Bugsnag](#bugsnag) -- [New Relic](#new-relic) - -A valid configuration may contain both. - -### `bugsnag` - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `apikey` | yes | The API Key provided by Bugsnag. | -| `releasestage` | no | Tracks where the registry is deployed, using a string like `production`, `staging`, or `development`.| -| `endpoint`| no | The enterprise Bugsnag endpoint. | - -### `newrelic` - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `licensekey` | yes | License key provided by New Relic. | -| `name` | no | New Relic application name. | -| `verbose`| no | Set to `true` to enable New Relic debugging output on `stdout`. | - -## `http` - -```none -http: - addr: localhost:5000 - net: tcp - prefix: /my/nested/registry/ - host: https://myregistryaddress.org:5000 - secret: asecretforlocaldevelopment - relativeurls: false - draintimeout: 60s - tls: - certificate: /path/to/x509/public - key: /path/to/x509/private - clientcas: - - /path/to/ca.pem - - /path/to/another/ca.pem - minimumtls: tls1.2 - ciphersuites: - - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - letsencrypt: - cachefile: /path/to/cache-file - email: emailused@letsencrypt.com - hosts: [myregistryaddress.org] - debug: - addr: localhost:5001 - headers: - X-Content-Type-Options: [nosniff] - http2: - disabled: false -``` - -The `http` option details the configuration for the HTTP server that hosts the -registry. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `addr` | yes | The address for which the server should accept connections. The form depends on a network type (see the `net` option). Use `HOST:PORT` for TCP and `FILE` for a UNIX socket. | -| `net` | no | The network used to create a listening socket. Known networks are `unix` and `tcp`. | -| `prefix` | no | If the server does not run at the root path, set this to the value of the prefix. The root path is the section before `v2`. It requires both preceding and trailing slashes, such as in the example `/path/`. | -| `host` | no | A fully-qualified URL for an externally-reachable address for the registry. If present, it is used when creating generated URLs. Otherwise, these URLs are derived from client requests. | -| `secret` | no | A random piece of data used to sign state that may be stored with the client to protect against tampering. For production environments you should generate a random piece of data using a cryptographically secure random generator. If you omit the secret, the registry will automatically generate a secret when it starts. **If you are building a cluster of registries behind a load balancer, you MUST ensure the secret is the same for all registries.**| -| `relativeurls`| no | If `true`, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. **This option is not compatible with Docker 1.7 and earlier.**| -| `draintimeout`| no | Amount of time to wait for HTTP connections to drain before shutting down after registry receives SIGTERM signal| - - -### `tls` - -The `tls` structure within `http` is **optional**. Use this to configure TLS -for the server. If you already have a web server running on -the same host as the registry, you may prefer to configure TLS on that web server -and proxy connections to the registry server. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `certificate` | yes | Absolute path to the x509 certificate file. | -| `key` | yes | Absolute path to the x509 private key file. | -| `clientcas` | no | An array of absolute paths to x509 CA files. | -| `minimumtls` | no | Minimum TLS version allowed (tls1.0, tls1.1, tls1.2, tls1.3). Defaults to tls1.2 | -| `ciphersuites` | no | Cipher suites allowed. Please see below for allowed values and default. | - -Available cipher suites: -- TLS_RSA_WITH_RC4_128_SHA -- TLS_RSA_WITH_3DES_EDE_CBC_SHA -- TLS_RSA_WITH_AES_128_CBC_SHA -- TLS_RSA_WITH_AES_256_CBC_SHA -- TLS_RSA_WITH_AES_128_CBC_SHA256 -- TLS_RSA_WITH_AES_128_GCM_SHA256 -- TLS_RSA_WITH_AES_256_GCM_SHA384 -- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA -- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA -- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA -- TLS_ECDHE_RSA_WITH_RC4_128_SHA -- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA -- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA -- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA -- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 -- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 -- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 -- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 -- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 -- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -- TLS_AES_128_GCM_SHA256 -- TLS_AES_256_GCM_SHA384 -- TLS_CHACHA20_POLY1305_SHA256 - -Default cipher suites: -- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 -- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 -- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 -- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -- TLS_AES_128_GCM_SHA256 -- TLS_CHACHA20_POLY1305_SHA256 -- TLS_AES_256_GCM_SHA384 - -### `letsencrypt` - -The `letsencrypt` structure within `tls` is **optional**. Use this to configure -TLS certificates provided by -[Let's Encrypt](https://letsencrypt.org/how-it-works/). - ->**NOTE**: When using Let's Encrypt, ensure that the outward-facing address is -> accessible on port `443`. The registry defaults to listening on port `5000`. -> If you run the registry as a container, consider adding the flag `-p 443:5000` -> to the `docker run` command or using a similar setting in a cloud -> configuration. You should also set the `hosts` option to the list of hostnames -> that are valid for this registry to avoid trying to get certificates for random -> hostnames due to malicious clients connecting with bogus SNI hostnames. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `cachefile` | yes | Absolute path to a file where the Let's Encrypt agent can cache data. | -| `email` | yes | The email address used to register with Let's Encrypt. | -| `hosts` | no | The hostnames allowed for Let's Encrypt certificates. | - -### `debug` - -The `debug` option is **optional** . Use it to configure a debug server that -can be helpful in diagnosing problems. The debug endpoint can be used for -monitoring registry metrics and health, as well as profiling. Sensitive -information may be available via the debug endpoint. Please be certain that -access to the debug endpoint is locked down in a production environment. - -The `debug` section takes a single required `addr` parameter, which specifies -the `HOST:PORT` on which the debug server should accept connections. - -## `prometheus` - -The `prometheus` option defines whether the prometheus metrics is enable, as well -as the path to access the metrics. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `enabled` | no | Set `true` to enable the prometheus server | -| `path` | no | The path to access the metrics, `/metrics` by default | - -The url to access the metrics is `HOST:PORT/path`, where `HOST:PORT` is defined -in `addr` under `debug`. - -### `headers` - -The `headers` option is **optional** . Use it to specify headers that the HTTP -server should include in responses. This can be used for security headers such -as `Strict-Transport-Security`. - -The `headers` option should contain an option for each header to include, where -the parameter name is the header's name, and the parameter value a list of the -header's payload values. - -Including `X-Content-Type-Options: [nosniff]` is recommended, so that browsers -will not interpret content as HTML if they are directed to load a page from the -registry. This header is included in the example configuration file. - -### `http2` - -The `http2` structure within `http` is **optional**. Use this to control http2 -settings for the registry. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `disabled` | no | If `true`, then `http2` support is disabled. | - -## `notifications` - -```none -notifications: - events: - includereferences: true - endpoints: - - name: alistener - disabled: false - url: https://my.listener.com/event - headers: - timeout: 1s - threshold: 10 - backoff: 1s - ignoredmediatypes: - - application/octet-stream - ignore: - mediatypes: - - application/octet-stream - actions: - - pull -``` - -The notifications option is **optional** and currently may contain a single -option, `endpoints`. - -### `endpoints` - -The `endpoints` structure contains a list of named services (URLs) that can -accept event notifications. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `name` | yes | A human-readable name for the service. | -| `disabled` | no | If `true`, notifications are disabled for the service.| -| `url` | yes | The URL to which events should be published. | -| `headers` | yes | A list of static headers to add to each request. Each header's name is a key beneath `headers`, and each value is a list of payloads for that header name. Values must always be lists. | -| `timeout` | yes | A value for the HTTP timeout. A positive integer and an optional suffix indicating the unit of time, which may be `ns`, `us`, `ms`, `s`, `m`, or `h`. If you omit the unit of time, `ns` is used. | -| `threshold` | yes | An integer specifying how long to wait before backing off a failure. | -| `backoff` | yes | How long the system backs off before retrying after a failure. A positive integer and an optional suffix indicating the unit of time, which may be `ns`, `us`, `ms`, `s`, `m`, or `h`. If you omit the unit of time, `ns` is used. | -| `ignoredmediatypes`|no| A list of target media types to ignore. Events with these target media types are not published to the endpoint. | -| `ignore` |no| Events with these mediatypes or actions are not published to the endpoint. | - -#### `ignore` -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `mediatypes`|no| A list of target media types to ignore. Events with these target media types are not published to the endpoint. | -| `actions` |no| A list of actions to ignore. Events with these actions are not published to the endpoint. | - -### `events` - -The `events` structure configures the information provided in event notifications. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `includereferences` | no | If `true`, include reference information in manifest events. | - -## `redis` - -```none -redis: - addr: localhost:6379 - password: asecret - db: 0 - dialtimeout: 10ms - readtimeout: 10ms - writetimeout: 10ms - pool: - maxidle: 16 - maxactive: 64 - idletimeout: 300s -``` - -Declare parameters for constructing the `redis` connections. Registry instances -may use the Redis instance for several applications. Currently, it caches -information about immutable blobs. Most of the `redis` options control -how the registry connects to the `redis` instance. You can control the pool's -behavior with the [pool](#pool) subsection. - -You should configure Redis with the **allkeys-lru** eviction policy, because the -registry does not set an expiration value on keys. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `addr` | yes | The address (host and port) of the Redis instance. | -| `password`| no | A password used to authenticate to the Redis instance.| -| `db` | no | The name of the database to use for each connection. | -| `dialtimeout` | no | The timeout for connecting to the Redis instance. | -| `readtimeout` | no | The timeout for reading from the Redis instance. | -| `writetimeout` | no | The timeout for writing to the Redis instance. | - -### `pool` - -```none -pool: - maxidle: 16 - maxactive: 64 - idletimeout: 300s -``` - -Use these settings to configure the behavior of the Redis connection pool. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `maxidle` | no | The maximum number of idle connections in the pool. | -| `maxactive`| no | The maximum number of connections which can be open before blocking a connection request. | -| `idletimeout`| no | How long to wait before closing inactive connections. | - -## `health` - -```none -health: - storagedriver: - enabled: true - interval: 10s - threshold: 3 - file: - - file: /path/to/checked/file - interval: 10s - http: - - uri: http://server.to.check/must/return/200 - headers: - Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==] - statuscode: 200 - timeout: 3s - interval: 10s - threshold: 3 - tcp: - - addr: redis-server.domain.com:6379 - timeout: 3s - interval: 10s - threshold: 3 -``` - -The health option is **optional**, and contains preferences for a periodic -health check on the storage driver's backend storage, as well as optional -periodic checks on local files, HTTP URIs, and/or TCP servers. The results of -the health checks are available at the `/debug/health` endpoint on the debug -HTTP server if the debug HTTP server is enabled (see http section). - -### `storagedriver` - -The `storagedriver` structure contains options for a health check on the -configured storage driver's backend storage. The health check is only active -when `enabled` is set to `true`. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `enabled` | yes | Set to `true` to enable storage driver health checks or `false` to disable them. | -| `interval`| no | How long to wait between repetitions of the storage driver health check. A positive integer and an optional suffix indicating the unit of time. The suffix is one of `ns`, `us`, `ms`, `s`, `m`, or `h`. Defaults to `10s` if the value is omitted. If you specify a value but omit the suffix, the value is interpreted as a number of nanoseconds. | -| `threshold`| no | A positive integer which represents the number of times the check must fail before the state is marked as unhealthy. If not specified, a single failure marks the state as unhealthy. | - -### `file` - -The `file` structure includes a list of paths to be periodically checked for the\ -existence of a file. If a file exists at the given path, the health check will -fail. You can use this mechanism to bring a registry out of rotation by creating -a file. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `file` | yes | The path to check for existence of a file. | -| `interval`| no | How long to wait before repeating the check. A positive integer and an optional suffix indicating the unit of time. The suffix is one of `ns`, `us`, `ms`, `s`, `m`, or `h`. Defaults to `10s` if the value is omitted. If you specify a value but omit the suffix, the value is interpreted as a number of nanoseconds. | - -### `http` - -The `http` structure includes a list of HTTP URIs to periodically check with -`HEAD` requests. If a `HEAD` request does not complete or returns an unexpected -status code, the health check will fail. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `uri` | yes | The URI to check. | -| `headers` | no | Static headers to add to each request. Each header's name is a key beneath `headers`, and each value is a list of payloads for that header name. Values must always be lists. | -| `statuscode` | no | The expected status code from the HTTP URI. Defaults to `200`. | -| `timeout` | no | How long to wait before timing out the HTTP request. A positive integer and an optional suffix indicating the unit of time. The suffix is one of `ns`, `us`, `ms`, `s`, `m`, or `h`. If you specify a value but omit the suffix, the value is interpreted as a number of nanoseconds. | -| `interval`| no | How long to wait before repeating the check. A positive integer and an optional suffix indicating the unit of time. The suffix is one of `ns`, `us`, `ms`, `s`, `m`, or `h`. Defaults to `10s` if the value is omitted. If you specify a value but omit the suffix, the value is interpreted as a number of nanoseconds. | -| `threshold`| no | The number of times the check must fail before the state is marked as unhealthy. If this field is not specified, a single failure marks the state as unhealthy. | - -### `tcp` - -The `tcp` structure includes a list of TCP addresses to periodically check using -TCP connection attempts. Addresses must include port numbers. If a connection -attempt fails, the health check will fail. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `addr` | yes | The TCP address and port to connect to. | -| `timeout` | no | How long to wait before timing out the TCP connection. A positive integer and an optional suffix indicating the unit of time. The suffix is one of `ns`, `us`, `ms`, `s`, `m`, or `h`. If you specify a value but omit the suffix, the value is interpreted as a number of nanoseconds. | -| `interval`| no | How long to wait between repetitions of the check. A positive integer and an optional suffix indicating the unit of time. The suffix is one of `ns`, `us`, `ms`, `s`, `m`, or `h`. Defaults to `10s` if the value is omitted. If you specify a value but omit the suffix, the value is interpreted as a number of nanoseconds. | -| `threshold`| no | The number of times the check must fail before the state is marked as unhealthy. If this field is not specified, a single failure marks the state as unhealthy. | - - -## `proxy` - -``` -proxy: - remoteurl: https://registry-1.docker.io - username: [username] - password: [password] -``` - -The `proxy` structure allows a registry to be configured as a pull-through cache -to Docker Hub. See -[mirror](https://github.com/docker/docker.github.io/tree/master/registry/recipes/mirror.md) -for more information. Pushing to a registry configured as a pull-through cache -is unsupported. - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `remoteurl`| yes | The URL for the repository on Docker Hub. | -| `username` | no | The username registered with Docker Hub which has access to the repository. | -| `password` | no | The password used to authenticate to Docker Hub using the username specified in `username`. | - - -To enable pulling private repositories (e.g. `batman/robin`) specify the -username (such as `batman`) and the password for that username. - -> **Note**: These private repositories are stored in the proxy cache's storage. -> Take appropriate measures to protect access to the proxy cache. - -## `compatibility` - -```none -compatibility: - schema1: - signingkeyfile: /etc/registry/key.json - enabled: true -``` - -Use the `compatibility` structure to configure handling of older and deprecated -features. Each subsection defines such a feature with configurable behavior. - -### `schema1` - -| Parameter | Required | Description | -|-----------|----------|-------------------------------------------------------| -| `signingkeyfile` | no | The signing private key used to add signatures to `schema1` manifests. If no signing key is provided, a new ECDSA key is generated when the registry starts. | -| `enabled` | no | If this is not set to true, `schema1` manifests cannot be pushed. | - -## `validation` - -```none -validation: - manifests: - urls: - allow: - - ^https?://([^/]+\.)*example\.com/ - deny: - - ^https?://www\.example\.com/ -``` - -### `disabled` - -The `disabled` flag disables the other options in the `validation` -section. They are enabled by default. This option deprecates the `enabled` flag. - -### `manifests` - -Use the `manifests` subsection to configure validation of manifests. If -`disabled` is `false`, the validation allows nothing. - -#### `urls` - -The `allow` and `deny` options are each a list of -[regular expressions](https://godoc.org/regexp/syntax) that restrict the URLs in -pushed manifests. - -If `allow` is unset, pushing a manifest containing URLs fails. - -If `allow` is set, pushing a manifest succeeds only if all URLs match -one of the `allow` regular expressions **and** one of the following holds: - -1. `deny` is unset. -2. `deny` is set but no URLs within the manifest match any of the `deny` regular - expressions. - -## Example: Development configuration - -You can use this simple example for local development: - -```none -version: 0.1 -log: - level: debug -storage: - filesystem: - rootdirectory: /var/lib/registry -http: - addr: localhost:5000 - secret: asecretforlocaldevelopment - debug: - addr: localhost:5001 -``` - -This example configures the registry instance to run on port `5000`, binding to -`localhost`, with the `debug` server enabled. Registry data is stored in the -`/var/lib/registry` directory. Logging is set to `debug` mode, which is the most -verbose. - -See -[config-example.yml](https://github.com/docker/distribution/blob/master/cmd/registry/config-example.yml) -for another simple configuration. Both examples are generally useful for local -development. - - -## Example: Middleware configuration - -This example configures [Amazon Cloudfront](http://aws.amazon.com/cloudfront/) -as the storage middleware in a registry. Middleware allows the registry to serve -layers via a content delivery network (CDN). This reduces requests to the -storage layer. - -Cloudfront requires the S3 storage driver. - -This is the configuration expressed in YAML: - -```none -middleware: - storage: - - name: cloudfront - disabled: false - options: - baseurl: http://d111111abcdef8.cloudfront.net - privatekey: /path/to/asecret.pem - keypairid: asecret - duration: 60s -``` - -See the configuration reference for [Cloudfront](#cloudfront) for more -information about configuration options. - -> **Note**: Cloudfront keys exist separately from other AWS keys. See -> [the documentation on AWS credentials](http://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html) -> for more information. diff --git a/_vendor/github.com/distribution/distribution/docs/spec/api.md b/_vendor/github.com/distribution/distribution/docs/spec/api.md deleted file mode 100644 index e088ad94618..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/api.md +++ /dev/null @@ -1,5487 +0,0 @@ ---- -title: "HTTP API V2" -description: "Specification for the Registry API." -keywords: registry, on-prem, images, tags, repository, distribution, api, advanced -redirect_from: - - /reference/api/registry_api/ ---- - -# Docker Registry HTTP API V2 - -## Introduction - -The _Docker Registry HTTP API_ is the protocol to facilitate distribution of -images to the docker engine. It interacts with instances of the docker -registry, which is a service to manage information about docker images and -enable their distribution. The specification covers the operation of version 2 -of this API, known as _Docker Registry HTTP API V2_. - -While the V1 registry protocol is usable, there are several problems with the -architecture that have led to this new version. The main driver of this -specification is a set of changes to the Docker image format, covered in -[docker/docker#8093](https://github.com/docker/docker/issues/8093). -The new, self-contained image manifest simplifies image definition and improves -security. This specification will build on that work, leveraging new properties -of the manifest format to improve performance, reduce bandwidth usage and -decrease the likelihood of backend corruption. - -For relevant details and history leading up to this specification, please see -the following issues: - -- [docker/docker#8093](https://github.com/docker/docker/issues/8093) -- [docker/docker#9015](https://github.com/docker/docker/issues/9015) -- [docker/docker-registry#612](https://github.com/docker/docker-registry/issues/612) - -### Scope - -This specification covers the URL layout and protocols of the interaction -between docker registry and docker core. This will affect the docker core -registry API and the rewrite of docker-registry. Docker registry -implementations may implement other API endpoints, but they are not covered by -this specification. - -This includes the following features: - -- Namespace-oriented URI Layout -- PUSH/PULL registry server for V2 image manifest format -- Resumable layer PUSH support -- V2 Client library implementation - -While authentication and authorization support will influence this -specification, details of the protocol will be left to a future specification. -Relevant header definitions and error codes are present to provide an -indication of what a client may encounter. - -#### Future - -There are features that have been discussed during the process of cutting this -specification. The following is an incomplete list: - -- Immutable image references -- Multiple architecture support -- Migration from v2compatibility representation - -These may represent features that are either out of the scope of this -specification, the purview of another specification or have been deferred to a -future version. - -### Use Cases - -For the most part, the use cases of the former registry API apply to the new -version. Differentiating use cases are covered below. - -#### Image Verification - -A docker engine instance would like to run verified image named -"library/ubuntu", with the tag "latest". The engine contacts the registry, -requesting the manifest for "library/ubuntu:latest". An untrusted registry -returns a manifest. Before proceeding to download the individual layers, the -engine verifies the manifest's signature, ensuring that the content was -produced from a trusted source and no tampering has occurred. After each layer -is downloaded, the engine verifies the digest of the layer, ensuring that the -content matches that specified by the manifest. - -#### Resumable Push - -Company X's build servers lose connectivity to docker registry before -completing an image layer transfer. After connectivity returns, the build -server attempts to re-upload the image. The registry notifies the build server -that the upload has already been partially attempted. The build server -responds by only sending the remaining data to complete the image file. - -#### Resumable Pull - -Company X is having more connectivity problems but this time in their -deployment datacenter. When downloading an image, the connection is -interrupted before completion. The client keeps the partial data and uses http -`Range` requests to avoid downloading repeated data. - -#### Layer Upload De-duplication - -Company Y's build system creates two identical docker layers from build -processes A and B. Build process A completes uploading the layer before B. -When process B attempts to upload the layer, the registry indicates that its -not necessary because the layer is already known. - -If process A and B upload the same layer at the same time, both operations -will proceed and the first to complete will be stored in the registry (Note: -we may modify this to prevent dogpile with some locking mechanism). - -### Changes - -The V2 specification has been written to work as a living document, specifying -only what is certain and leaving what is not specified open or to future -changes. Only non-conflicting additions should be made to the API and accepted -changes should avoid preventing future changes from happening. - -This section should be updated when changes are made to the specification, -indicating what is different. Optionally, we may start marking parts of the -specification to correspond with the versions enumerated here. - -Each set of changes is given a letter corresponding to a set of modifications -that were applied to the baseline specification. These are merely for -reference and shouldn't be used outside the specification other than to -identify a set of modifications. - -
-
l
-
-
    -
  • Document TOOMANYREQUESTS error code.
  • -
-
- -
k
-
-
    -
  • Document use of Accept and Content-Type headers in manifests endpoint.
  • -
-
- -
j
-
-
    -
  • Add ability to mount blobs across repositories.
  • -
-
- -
i
-
-
    -
  • Clarified expected behavior response to manifest HEAD request.
  • -
-
- -
h
-
-
    -
  • All mention of tarsum removed.
  • -
-
- -
g
-
-
    -
  • Clarify behavior of pagination behavior with unspecified parameters.
  • -
-
- -
f
-
-
    -
  • Specify the delete API for layers and manifests.
  • -
-
- -
e
-
-
    -
  • Added support for listing registry contents.
  • -
  • Added pagination to tags API.
  • -
  • Added common approach to support pagination.
  • -
-
- -
d
-
-
    -
  • Allow repository name components to be one character.
  • -
  • Clarified that single component names are allowed.
  • -
-
- -
c
-
-
    -
  • Added section covering digest format.
  • -
  • Added more clarification that manifest cannot be deleted by tag.
  • -
-
- -
b
-
-
    -
  • Added capability of doing streaming upload to PATCH blob upload.
  • -
  • Updated PUT blob upload to no longer take final chunk, now requires entire data or no data.
  • -
  • Removed `416 Requested Range Not Satisfiable` response status from PUT blob upload.
  • -
-
- -
a
-
-
    -
  • Added support for immutable manifest references in manifest endpoints.
  • -
  • Deleting a manifest by tag has been deprecated.
  • -
  • Specified `Docker-Content-Digest` header for appropriate entities.
  • -
  • Added error code for unsupported operations.
  • -
-
-
- -## Overview - -This section covers client flows and details of the API endpoints. The URI -layout of the new API is structured to support a rich authentication and -authorization model by leveraging namespaces. All endpoints will be prefixed -by the API version and the repository name: - - /v2// - -For example, an API endpoint that will work with the `library/ubuntu` -repository, the URI prefix will be: - - /v2/library/ubuntu/ - -This scheme provides rich access control over various operations and methods -using the URI prefix and http methods that can be controlled in variety of -ways. - -Classically, repository names have always been two path components where each -path component is less than 30 characters. The V2 registry API does not -enforce this. The rules for a repository name are as follows: - -1. A repository name is broken up into _path components_. A component of a - repository name must be at least one lowercase, alpha-numeric characters, - optionally separated by periods, dashes or underscores. More strictly, it - must match the regular expression `[a-z0-9]+(?:[._-][a-z0-9]+)*`. -2. If a repository name has two or more path components, they must be - separated by a forward slash ("/"). -3. The total length of a repository name, including slashes, must be less than - 256 characters. - -These name requirements _only_ apply to the registry API and should accept a -superset of what is supported by other docker ecosystem components. - -All endpoints should support aggressive http caching, compression and range -headers, where appropriate. The new API attempts to leverage HTTP semantics -where possible but may break from standards to implement targeted features. - -For detail on individual endpoints, please see the [_Detail_](#detail) -section. - -### Errors - -Actionable failure conditions, covered in detail in their relevant sections, -are reported as part of 4xx responses, in a json response body. One or more -errors will be returned in the following format: - - { - "errors:" [{ - "code": , - "message": , - "detail": - }, - ... - ] - } - -The `code` field will be a unique identifier, all caps with underscores by -convention. The `message` field will be a human readable string. The optional -`detail` field may contain arbitrary json data providing information the -client can use to resolve the issue. - -While the client can take action on certain error codes, the registry may add -new error codes over time. All client implementations should treat unknown -error codes as `UNKNOWN`, allowing future error codes to be added without -breaking API compatibility. For the purposes of the specification error codes -will only be added and never removed. - -For a complete account of all error codes, please see the [_Errors_](#errors-2) -section. - -### API Version Check - -A minimal endpoint, mounted at `/v2/` will provide version support information -based on its response statuses. The request format is as follows: - - GET /v2/ - -If a `200 OK` response is returned, the registry implements the V2(.1) -registry API and the client may proceed safely with other V2 operations. -Optionally, the response may contain information about the supported paths in -the response body. The client should be prepared to ignore this data. - -If a `401 Unauthorized` response is returned, the client should take action -based on the contents of the "WWW-Authenticate" header and try the endpoint -again. Depending on access control setup, the client may still have to -authenticate against different resources, even if this check succeeds. - -If `404 Not Found` response status, or other unexpected status, is returned, -the client should proceed with the assumption that the registry does not -implement V2 of the API. - -When a `200 OK` or `401 Unauthorized` response is returned, the -"Docker-Distribution-API-Version" header should be set to "registry/2.0". -Clients may require this header value to determine if the endpoint serves this -API. When this header is omitted, clients may fallback to an older API version. - -### Content Digests - -This API design is driven heavily by [content addressability](http://en.wikipedia.org/wiki/Content-addressable_storage). -The core of this design is the concept of a content addressable identifier. It -uniquely identifies content by taking a collision-resistant hash of the bytes. -Such an identifier can be independently calculated and verified by selection -of a common _algorithm_. If such an identifier can be communicated in a secure -manner, one can retrieve the content from an insecure source, calculate it -independently and be certain that the correct content was obtained. Put simply, -the identifier is a property of the content. - -To disambiguate from other concepts, we call this identifier a _digest_. A -_digest_ is a serialized hash result, consisting of a _algorithm_ and _hex_ -portion. The _algorithm_ identifies the methodology used to calculate the -digest. The _hex_ portion is the hex-encoded result of the hash. - -We define a _digest_ string to match the following grammar: -``` -digest := algorithm ":" hex -algorithm := /[A-Fa-f0-9_+.-]+/ -hex := /[A-Fa-f0-9]+/ -``` - -Some examples of _digests_ include the following: - -digest | description | -----------------------------------------------------------------------------------|------------------------------------------------ -sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b | Common sha256 based digest | - -While the _algorithm_ does allow one to implement a wide variety of -algorithms, compliant implementations should use sha256. Heavy processing of -input before calculating a hash is discouraged to avoid degrading the -uniqueness of the _digest_ but some canonicalization may be performed to -ensure consistent identifiers. - -Let's use a simple example in pseudo-code to demonstrate a digest calculation: -``` -let C = 'a small string' -let B = sha256(C) -let D = 'sha256:' + EncodeHex(B) -let ID(C) = D -``` - -Above, we have bytestring `C` passed into a function, `SHA256`, that returns a -bytestring `B`, which is the hash of `C`. `D` gets the algorithm concatenated -with the hex encoding of `B`. We then define the identifier of `C` to `ID(C)` -as equal to `D`. A digest can be verified by independently calculating `D` and -comparing it with identifier `ID(C)`. - -#### Digest Header - -To provide verification of http content, any response may include a -`Docker-Content-Digest` header. This will include the digest of the target -entity returned in the response. For blobs, this is the entire blob content. For -manifests, this is the manifest body without the signature content, also known -as the JWS payload. Note that the commonly used canonicalization for digest -calculation may be dependent on the mediatype of the content, such as with -manifests. - -The client may choose to ignore the header or may verify it to ensure content -integrity and transport security. This is most important when fetching by a -digest. To ensure security, the content should be verified against the digest -used to fetch the content. At times, the returned digest may differ from that -used to initiate a request. Such digests are considered to be from different -_domains_, meaning they have different values for _algorithm_. In such a case, -the client may choose to verify the digests in both domains or ignore the -server's digest. To maintain security, the client _must_ always verify the -content against the _digest_ used to fetch the content. - -> __IMPORTANT:__ If a _digest_ is used to fetch content, the client should use -> the same digest used to fetch the content to verify it. The header -> `Docker-Content-Digest` should not be trusted over the "local" digest. - -### Pulling An Image - -An "image" is a combination of a JSON manifest and individual layer files. The -process of pulling an image centers around retrieving these two components. - -The first step in pulling an image is to retrieve the manifest. For reference, -the relevant manifest fields for the registry are the following: - - field | description | -----------|------------------------------------------------| -name | The name of the image. | -tag | The tag for this version of the image. | -fsLayers | A list of layer descriptors (including digest) | -signature | A JWS used to verify the manifest content | - -For more information about the manifest format, please see -[docker/docker#8093](https://github.com/docker/docker/issues/8093). - -When the manifest is in hand, the client must verify the signature to ensure -the names and layers are valid. Once confirmed, the client will then use the -digests to download the individual layers. Layers are stored in as blobs in -the V2 registry API, keyed by their digest. - -#### Pulling an Image Manifest - -The image manifest can be fetched with the following url: - -``` -GET /v2//manifests/ -``` - -The `name` and `reference` parameter identify the image and are required. The -reference may include a tag or digest. - -The client should include an Accept header indicating which manifest content -types it supports. For more details on the manifest formats and their content -types, see [manifest-v2-1.md](manifest-v2-1.md) and -[manifest-v2-2.md](manifest-v2-2.md). In a successful response, the Content-Type -header will indicate which manifest type is being returned. - -A `404 Not Found` response will be returned if the image is unknown to the -registry. If the image exists and the response is successful, the image -manifest will be returned, with the following format (see -[docker/docker#8093](https://github.com/docker/docker/issues/8093) for details): - - { - "name": , - "tag": , - "fsLayers": [ - { - "blobSum": - }, - ... - ] - ], - "history": , - "signature": - } - -The client should verify the returned manifest signature for authenticity -before fetching layers. - -##### Existing Manifests - -The image manifest can be checked for existence with the following url: - -``` -HEAD /v2//manifests/ -``` - -The `name` and `reference` parameter identify the image and are required. The -reference may include a tag or digest. - -A `404 Not Found` response will be returned if the image is unknown to the -registry. If the image exists and the response is successful the response will -be as follows: - -``` -200 OK -Content-Length: -Docker-Content-Digest: -``` - - -#### Pulling a Layer - -Layers are stored in the blob portion of the registry, keyed by digest. -Pulling a layer is carried out by a standard http request. The URL is as -follows: - - GET /v2//blobs/ - -Access to a layer will be gated by the `name` of the repository but is -identified uniquely in the registry by `digest`. - -This endpoint may issue a 307 (302 for /blobs/uploads/ -``` - -The parameters of this request are the image namespace under which the layer -will be linked. Responses to this request are covered below. - -##### Existing Layers - -The existence of a layer can be checked via a `HEAD` request to the blob store -API. The request should be formatted as follows: - -``` -HEAD /v2//blobs/ -``` - -If the layer with the digest specified in `digest` is available, a 200 OK -response will be received, with no actual body content (this is according to -http specification). The response will look as follows: - -``` -200 OK -Content-Length: -Docker-Content-Digest: -``` - -When this response is received, the client can assume that the layer is -already available in the registry under the given name and should take no -further action to upload the layer. Note that the binary digests may differ -for the existing registry layer, but the digests will be guaranteed to match. - -##### Uploading the Layer - -If the POST request is successful, a `202 Accepted` response will be returned -with the upload URL in the `Location` header: - -``` -202 Accepted -Location: /v2//blobs/uploads/ -Range: bytes=0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -The rest of the upload process can be carried out with the returned url, -called the "Upload URL" from the `Location` header. All responses to the -upload url, whether sending data or getting status, will be in this format. -Though the URI format (`/v2//blobs/uploads/`) for the `Location` -header is specified, clients should treat it as an opaque url and should never -try to assemble it. While the `uuid` parameter may be an actual UUID, this -proposal imposes no constraints on the format and clients should never impose -any. - -If clients need to correlate local upload state with remote upload state, the -contents of the `Docker-Upload-UUID` header should be used. Such an id can be -used to key the last used location header when implementing resumable uploads. - -##### Upload Progress - -The progress and chunk coordination of the upload process will be coordinated -through the `Range` header. While this is a non-standard use of the `Range` -header, there are examples of [similar approaches](https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol) in APIs with heavy use. -For an upload that just started, for an example with a 1000 byte layer file, -the `Range` header would be as follows: - -``` -Range: bytes=0-0 -``` - -To get the status of an upload, issue a GET request to the upload URL: - -``` -GET /v2//blobs/uploads/ -Host: -``` - -The response will be similar to the above, except will return 204 status: - -``` -204 No Content -Location: /v2//blobs/uploads/ -Range: bytes=0- -Docker-Upload-UUID: -``` - -Note that the HTTP `Range` header byte ranges are inclusive and that will be -honored, even in non-standard use cases. - -##### Monolithic Upload - -A monolithic upload is simply a chunked upload with a single chunk and may be -favored by clients that would like to avoided the complexity of chunking. To -carry out a "monolithic" upload, one can simply put the entire content blob to -the provided URL: - -``` -PUT /v2//blobs/uploads/?digest= -Content-Length: -Content-Type: application/octet-stream - - -``` - -The "digest" parameter must be included with the PUT request. Please see the -[_Completed Upload_](#completed-upload) section for details on the parameters -and expected responses. - -##### Chunked Upload - -To carry out an upload of a chunk, the client can specify a range header and -only include that part of the layer file: - -``` -PATCH /v2//blobs/uploads/ -Content-Length: -Content-Range: - -Content-Type: application/octet-stream - - -``` - -There is no enforcement on layer chunk splits other than that the server must -receive them in order. The server may enforce a minimum chunk size. If the -server cannot accept the chunk, a `416 Requested Range Not Satisfiable` -response will be returned and will include a `Range` header indicating the -current status: - -``` -416 Requested Range Not Satisfiable -Location: /v2//blobs/uploads/ -Range: 0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -If this response is received, the client should resume from the "last valid -range" and upload the subsequent chunk. A 416 will be returned under the -following conditions: - -- Invalid Content-Range header format -- Out of order chunk: the range of the next chunk must start immediately after - the "last valid range" from the previous response. - -When a chunk is accepted as part of the upload, a `202 Accepted` response will -be returned, including a `Range` header with the current upload status: - -``` -202 Accepted -Location: /v2//blobs/uploads/ -Range: bytes=0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -##### Completed Upload - -For an upload to be considered complete, the client must submit a `PUT` -request on the upload endpoint with a digest parameter. If it is not provided, -the upload will not be considered complete. The format for the final chunk -will be as follows: - -``` -PUT /v2//blobs/uploads/?digest= -Content-Length: -Content-Range: - -Content-Type: application/octet-stream - - -``` - -Optionally, if all chunks have already been uploaded, a `PUT` request with a -`digest` parameter and zero-length body may be sent to complete and validate -the upload. Multiple "digest" parameters may be provided with different -digests. The server may verify none or all of them but _must_ notify the -client if the content is rejected. - -When the last chunk is received and the layer has been validated, the client -will receive a `201 Created` response: - -``` -201 Created -Location: /v2//blobs/ -Content-Length: 0 -Docker-Content-Digest: -``` - -The `Location` header will contain the registry URL to access the accepted -layer file. The `Docker-Content-Digest` header returns the canonical digest of -the uploaded blob which may differ from the provided digest. Most clients may -ignore the value but if it is used, the client should verify the value against -the uploaded blob data. - -###### Digest Parameter - -The "digest" parameter is designed as an opaque parameter to support -verification of a successful transfer. For example, an HTTP URI parameter -might be as follows: - -``` -sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b -``` - -Given this parameter, the registry will verify that the provided content does -match this digest. - -##### Canceling an Upload - -An upload can be cancelled by issuing a DELETE request to the upload endpoint. -The format will be as follows: - -``` -DELETE /v2//blobs/uploads/ -``` - -After this request is issued, the upload uuid will no longer be valid and the -registry server will dump all intermediate data. While uploads will time out -if not completed, clients should issue this request if they encounter a fatal -error but still have the ability to issue an http request. - -##### Cross Repository Blob Mount - -A blob may be mounted from another repository that the client has read access -to, removing the need to upload a blob already known to the registry. To issue -a blob mount instead of an upload, a POST request should be issued in the -following format: - -``` -POST /v2//blobs/uploads/?mount=&from= -Content-Length: 0 -``` - -If the blob is successfully mounted, the client will receive a `201 Created` -response: - -``` -201 Created -Location: /v2//blobs/ -Content-Length: 0 -Docker-Content-Digest: -``` - -The `Location` header will contain the registry URL to access the accepted -layer file. The `Docker-Content-Digest` header returns the canonical digest of -the uploaded blob which may differ from the provided digest. Most clients may -ignore the value but if it is used, the client should verify the value against -the uploaded blob data. - -If a mount fails due to invalid repository or digest arguments, the registry -will fall back to the standard upload behavior and return a `202 Accepted` with -the upload URL in the `Location` header: - -``` -202 Accepted -Location: /v2//blobs/uploads/ -Range: bytes=0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -This behavior is consistent with older versions of the registry, which do not -recognize the repository mount query parameters. - -Note: a client may issue a HEAD request to check existence of a blob in a source -repository to distinguish between the registry not supporting blob mounts and -the blob not existing in the expected repository. - -##### Errors - -If an 502, 503 or 504 error is received, the client should assume that the -download can proceed due to a temporary condition, honoring the appropriate -retry mechanism. Other 5xx errors should be treated as terminal. - -If there is a problem with the upload, a 4xx error will be returned indicating -the problem. After receiving a 4xx response (except 416, as called out above), -the upload will be considered failed and the client should take appropriate -action. - -Note that the upload url will not be available forever. If the upload uuid is -unknown to the registry, a `404 Not Found` response will be returned and the -client must restart the upload process. - -#### Deleting a Layer - -A layer may be deleted from the registry via its `name` and `digest`. A -delete may be issued with the following request format: - - DELETE /v2//blobs/ - -If the blob exists and has been successfully deleted, the following response -will be issued: - - 202 Accepted - Content-Length: None - -If the blob had already been deleted or did not exist, a `404 Not Found` -response will be issued instead. - -If a layer is deleted which is referenced by a manifest in the registry, -then the complete images will not be resolvable. - -#### Pushing an Image Manifest - -Once all of the layers for an image are uploaded, the client can upload the -image manifest. An image can be pushed using the following request format: - - PUT /v2//manifests/ - Content-Type: - - { - "name": , - "tag": , - "fsLayers": [ - { - "blobSum": - }, - ... - ] - ], - "history": , - "signature": , - ... - } - -The `name` and `reference` fields of the response body must match those -specified in the URL. The `reference` field may be a "tag" or a "digest". The -content type should match the type of the manifest being uploaded, as specified -in [manifest-v2-1.md](manifest-v2-1.md) and [manifest-v2-2.md](manifest-v2-2.md). - -If there is a problem with pushing the manifest, a relevant 4xx response will -be returned with a JSON error message. Please see the -[_PUT Manifest_](#put-manifest) section for details on possible error codes that -may be returned. - -If one or more layers are unknown to the registry, `BLOB_UNKNOWN` errors are -returned. The `detail` field of the error response will have a `digest` field -identifying the missing blob. An error is returned for each unknown blob. The -response format is as follows: - - { - "errors:" [{ - "code": "BLOB_UNKNOWN", - "message": "blob unknown to registry", - "detail": { - "digest": - } - }, - ... - ] - } - -### Listing Repositories - -Images are stored in collections, known as a _repository_, which is keyed by a -`name`, as seen throughout the API specification. A registry instance may -contain several repositories. The list of available repositories is made -available through the _catalog_. - -The catalog for a given registry can be retrieved with the following request: - -``` -GET /v2/_catalog -``` - -The response will be in the following format: - -``` -200 OK -Content-Type: application/json - -{ - "repositories": [ - , - ... - ] -} -``` - -Note that the contents of the response are specific to the registry -implementation. Some registries may opt to provide a full catalog output, -limit it based on the user's access level or omit upstream results, if -providing mirroring functionality. Subsequently, the presence of a repository -in the catalog listing only means that the registry *may* provide access to -the repository at the time of the request. Conversely, a missing entry does -*not* mean that the registry does not have the repository. More succinctly, -the presence of a repository only guarantees that it is there but not that it -is _not_ there. - -For registries with a large number of repositories, this response may be quite -large. If such a response is expected, one should use pagination. A registry -may also limit the amount of responses returned even if pagination was not -explicitly requested. In this case the `Link` header will be returned along -with the results, and subsequent results can be obtained by following the link -as if pagination had been initially requested. - -For details of the `Link` header, please see the [_Pagination_](#pagination) -section. - -#### Pagination - -Paginated catalog results can be retrieved by adding an `n` parameter to the -request URL, declaring that the response should be limited to `n` results. -Starting a paginated flow begins as follows: - -``` -GET /v2/_catalog?n= -``` - -The above specifies that a catalog response should be returned, from the start of -the result set, ordered lexically, limiting the number of results to `n`. The -response to such a request would look as follows: - -``` -200 OK -Content-Type: application/json -Link: <?n=&last=>; rel="next" - -{ - "repositories": [ - , - ... - ] -} -``` - -The above includes the _first_ `n` entries from the result set. To get the -_next_ `n` entries, one can create a URL where the argument `last` has the -value from `repositories[len(repositories)-1]`. If there are indeed more -results, the URL for the next block is encoded in an -[RFC5988](https://tools.ietf.org/html/rfc5988) `Link` header, as a "next" -relation. The presence of the `Link` header communicates to the client that -the entire result set has not been returned and another request must be -issued. If the header is not present, the client can assume that all results -have been received. - -> __NOTE:__ In the request template above, note that the brackets -> are required. For example, if the url is -> `http://example.com/v2/_catalog?n=20&last=b`, the value of the header would -> be `; rel="next"`. Please see -> [RFC5988](https://tools.ietf.org/html/rfc5988) for details. - -Compliant client implementations should always use the `Link` header -value when proceeding through results linearly. The client may construct URLs -to skip forward in the catalog. - -To get the next result set, a client would issue the request as follows, using -the URL encoded in the described `Link` header: - -``` -GET /v2/_catalog?n=&last= -``` - -The above process should then be repeated until the `Link` header is no longer -set. - -The catalog result set is represented abstractly as a lexically sorted list, -where the position in that list can be specified by the query term `last`. The -entries in the response start _after_ the term specified by `last`, up to `n` -entries. - -The behavior of `last` is quite simple when demonstrated with an example. Let -us say the registry has the following repositories: - -``` -a -b -c -d -``` - -If the value of `n` is 2, _a_ and _b_ will be returned on the first response. -The `Link` header returned on the response will have `n` set to 2 and last set -to _b_: - -``` -Link: <?n=2&last=b>; rel="next" -``` - -The client can then issue the request with the above value from the `Link` -header, receiving the values _c_ and _d_. Note that `n` may change on the second -to last response or be fully omitted, depending on the server implementation. - -### Listing Image Tags - -It may be necessary to list all of the tags under a given repository. The tags -for an image repository can be retrieved with the following request: - - GET /v2//tags/list - -The response will be in the following format: - - 200 OK - Content-Type: application/json - - { - "name": , - "tags": [ - , - ... - ] - } - -For repositories with a large number of tags, this response may be quite -large. If such a response is expected, one should use the pagination. - -#### Pagination - -Paginated tag results can be retrieved by adding the appropriate parameters to -the request URL described above. The behavior of tag pagination is identical -to that specified for catalog pagination. We cover a simple flow to highlight -any differences. - -Starting a paginated flow may begin as follows: - -``` -GET /v2//tags/list?n= -``` - -The above specifies that a tags response should be returned, from the start of -the result set, ordered lexically, limiting the number of results to `n`. The -response to such a request would look as follows: - -``` -200 OK -Content-Type: application/json -Link: <?n=&last=>; rel="next" - -{ - "name": , - "tags": [ - , - ... - ] -} -``` - -To get the next result set, a client would issue the request as follows, using -the value encoded in the [RFC5988](https://tools.ietf.org/html/rfc5988) `Link` -header: - -``` -GET /v2//tags/list?n=&last= -``` - -The above process should then be repeated until the `Link` header is no longer -set in the response. The behavior of the `last` parameter, the provided -response result, lexical ordering and encoding of the `Link` header are -identical to that of catalog pagination. - -### Deleting an Image - -An image may be deleted from the registry via its `name` and `reference`. A -delete may be issued with the following request format: - - DELETE /v2//manifests/ - -For deletes, `reference` *must* be a digest or the delete will fail. If the -image exists and has been successfully deleted, the following response will be -issued: - - 202 Accepted - Content-Length: None - -If the image had already been deleted or did not exist, a `404 Not Found` -response will be issued instead. - -> **Note** When deleting a manifest from a registry version 2.3 or later, the -> following header must be used when `HEAD` or `GET`-ing the manifest to obtain -> the correct digest to delete: - - Accept: application/vnd.docker.distribution.manifest.v2+json - -> for more details, see: [compatibility.md](../compatibility.md#content-addressable-storage-cas) - -## Detail - -> **Note**: This section is still under construction. For the purposes of -> implementation, if any details below differ from the described request flows -> above, the section below should be corrected. When they match, this note -> should be removed. - -The behavior of the endpoints are covered in detail in this section, organized -by route and entity. All aspects of the request and responses are covered, -including headers, parameters and body formats. Examples of requests and their -corresponding responses, with success and failure, are enumerated. - -> **Note**: The sections on endpoint detail are arranged with an example -> request, a description of the request, followed by information about that -> request. - -A list of methods and URIs are covered in the table below: - -|Method|Path|Entity|Description| -|------|----|------|-----------| -| GET | `/v2/` | Base | Check that the endpoint implements Docker Registry API V2. | -| GET | `/v2//tags/list` | Tags | Fetch the tags under the repository identified by `name`. | -| GET | `/v2//manifests/` | Manifest | Fetch the manifest identified by `name` and `reference` where `reference` can be a tag or digest. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data. | -| PUT | `/v2//manifests/` | Manifest | Put the manifest identified by `name` and `reference` where `reference` can be a tag or digest. | -| DELETE | `/v2//manifests/` | Manifest | Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted by `digest`. | -| GET | `/v2//blobs/` | Blob | Retrieve the blob from the registry identified by `digest`. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data. | -| DELETE | `/v2//blobs/` | Blob | Delete the blob identified by `name` and `digest` | -| POST | `/v2//blobs/uploads/` | Initiate Blob Upload | Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the `digest` parameter is present, the request body will be used to complete the upload in a single request. | -| GET | `/v2//blobs/uploads/` | Blob Upload | Retrieve status of upload identified by `uuid`. The primary purpose of this endpoint is to resolve the current status of a resumable upload. | -| PATCH | `/v2//blobs/uploads/` | Blob Upload | Upload a chunk of data for the specified upload. | -| PUT | `/v2//blobs/uploads/` | Blob Upload | Complete the upload specified by `uuid`, optionally appending the body as the final chunk. | -| DELETE | `/v2//blobs/uploads/` | Blob Upload | Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout. | -| GET | `/v2/_catalog` | Catalog | Retrieve a sorted, json list of repositories available in the registry. | - - -The detail for each endpoint is covered in the following sections. - -### Errors - -The error codes encountered via the API are enumerated in the following table: - -|Code|Message|Description| -|----|-------|-----------| - `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. - `BLOB_UPLOAD_INVALID` | blob upload invalid | The blob upload encountered an error and can no longer proceed. - `BLOB_UPLOAD_UNKNOWN` | blob upload unknown to registry | If a blob upload has been cancelled or was never started, this error code may be returned. - `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. - `MANIFEST_BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a manifest blob is unknown to the registry. - `MANIFEST_INVALID` | manifest invalid | During upload, manifests undergo several checks ensuring validity. If those checks fail, this error may be returned, unless a more specific error is included. The detail will contain information the failed validation. - `MANIFEST_UNKNOWN` | manifest unknown | This error is returned when the manifest, identified by name and tag is unknown to the repository. - `MANIFEST_UNVERIFIED` | manifest failed signature verification | During manifest upload, if the manifest fails signature verification, this error will be returned. - `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. - `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. - `SIZE_INVALID` | provided length did not match content length | When a layer is uploaded, the provided size will be checked against the uploaded content. If they do not match, this error will be returned. - `TAG_INVALID` | manifest tag did not match URI | During a manifest upload, if the tag in the manifest does not match the uri tag, this error will be returned. - `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. - `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. - `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. - - - -### Base - -Base V2 API route. Typically, this can be used for lightweight version checks and to validate registry authentication. - - - -#### GET Base - -Check that the endpoint implements Docker Registry API V2. - - - -``` -GET /v2/ -Host: -Authorization: -``` - - - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| - - - - -###### On Success: OK - -``` -200 OK -``` - -The API implements V2 protocol and is accessible. - - - - -###### On Failure: Not Found - -``` -404 Not Found -``` - -The registry does not implement the V2 API. - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - - -### Tags - -Retrieve information about tags. - - - -#### GET Tags - -Fetch the tags under the repository identified by `name`. - - -##### Tags - -``` -GET /v2//tags/list -Host: -Authorization: -``` - -Return all tags for the repository - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| - - - - -###### On Success: OK - -``` -200 OK -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "name": , - "tags": [ - , - ... - ] -} -``` - -A list of tags for the named repository. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -##### Tags Paginated - -``` -GET /v2//tags/list?n=&last= -``` - -Return a portion of the tags for the specified repository. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`name`|path|Name of the target repository.| -|`n`|query|Limit the number of entries in each response. It not present, all entries will be returned.| -|`last`|query|Result set will include values lexically after last.| - - - - -###### On Success: OK - -``` -200 OK -Content-Length: -Link: <?n=&last=>; rel="next" -Content-Type: application/json; charset=utf-8 - -{ - "name": , - "tags": [ - , - ... - ], -} -``` - -A list of tags for the named repository. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| -|`Link`|RFC5988 compliant rel='next' with URL to next result set, if available| - - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - - -### Manifest - -Create, update, delete and retrieve manifests. - - - -#### GET Manifest - -Fetch the manifest identified by `name` and `reference` where `reference` can be a tag or digest. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data. - - - -``` -GET /v2//manifests/ -Host: -Authorization: -``` - - - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`reference`|path|Tag or digest of the target manifest.| - - - - -###### On Success: OK - -``` -200 OK -Docker-Content-Digest: -Content-Type: - -{ - "name": , - "tag": , - "fsLayers": [ - { - "blobSum": "" - }, - ... - ] - ], - "history": , - "signature": -} -``` - -The manifest identified by `name` and `reference`. The contents can be used to identify and resolve resources required to run the specified image. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Docker-Content-Digest`|Digest of the targeted content for the request.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The name or reference was invalid. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `TAG_INVALID` | manifest tag did not match URI | During a manifest upload, if the tag in the manifest does not match the uri tag, this error will be returned. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - -#### PUT Manifest - -Put the manifest identified by `name` and `reference` where `reference` can be a tag or digest. - - - -``` -PUT /v2//manifests/ -Host: -Authorization: -Content-Type: - -{ - "name": , - "tag": , - "fsLayers": [ - { - "blobSum": "" - }, - ... - ] - ], - "history": , - "signature": -} -``` - - - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`reference`|path|Tag or digest of the target manifest.| - - - - -###### On Success: Created - -``` -201 Created -Location: -Content-Length: 0 -Docker-Content-Digest: -``` - -The manifest has been accepted by the registry and is stored under the specified `name` and `tag`. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|The canonical location url of the uploaded manifest.| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Content-Digest`|Digest of the targeted content for the request.| - - - - -###### On Failure: Invalid Manifest - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The received manifest was invalid in some way, as described by the error codes. The client should resolve the issue and retry the request. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `TAG_INVALID` | manifest tag did not match URI | During a manifest upload, if the tag in the manifest does not match the uri tag, this error will be returned. | -| `MANIFEST_INVALID` | manifest invalid | During upload, manifests undergo several checks ensuring validity. If those checks fail, this error may be returned, unless a more specific error is included. The detail will contain information the failed validation. | -| `MANIFEST_UNVERIFIED` | manifest failed signature verification | During manifest upload, if the manifest fails signature verification, this error will be returned. | -| `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -###### On Failure: Missing Layer(s) - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [{ - "code": "BLOB_UNKNOWN", - "message": "blob unknown to registry", - "detail": { - "digest": "" - } - }, - ... - ] -} -``` - -One or more layers may be missing during a manifest upload. If so, the missing layers will be enumerated in the error response. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. | - - - -###### On Failure: Not allowed - -``` -405 Method Not Allowed -``` - -Manifest put is not allowed because the registry is configured as a pull-through cache or for some other reason - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. | - - - - -#### DELETE Manifest - -Delete the manifest identified by `name` and `reference`. Note that a manifest can _only_ be deleted by `digest`. - - - -``` -DELETE /v2//manifests/ -Host: -Authorization: -``` - - - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`reference`|path|Tag or digest of the target manifest.| - - - - -###### On Success: Accepted - -``` -202 Accepted -``` - - - - - - -###### On Failure: Invalid Name or Reference - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The specified `name` or `reference` were invalid and the delete was unable to proceed. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `TAG_INVALID` | manifest tag did not match URI | During a manifest upload, if the tag in the manifest does not match the uri tag, this error will be returned. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -###### On Failure: Unknown Manifest - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The specified `name` or `reference` are unknown to the registry and the delete was unable to proceed. Clients can assume the manifest was already deleted if this response is returned. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | -| `MANIFEST_UNKNOWN` | manifest unknown | This error is returned when the manifest, identified by name and tag is unknown to the repository. | - - - -###### On Failure: Not allowed - -``` -405 Method Not Allowed -``` - -Manifest delete is not allowed because the registry is configured as a pull-through cache or `delete` has been disabled. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. | - - - - - -### Blob - -Operations on blobs identified by `name` and `digest`. Used to fetch or delete layers by digest. - - - -#### GET Blob - -Retrieve the blob from the registry identified by `digest`. A `HEAD` request can also be issued to this endpoint to obtain resource information without receiving all data. - - -##### Fetch Blob - -``` -GET /v2//blobs/ -Host: -Authorization: -``` - - - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`digest`|path|Digest of desired blob.| - - - - -###### On Success: OK - -``` -200 OK -Content-Length: -Docker-Content-Digest: -Content-Type: application/octet-stream - - -``` - -The blob identified by `digest` is available. The blob content will be present in the body of the request. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|The length of the requested blob content.| -|`Docker-Content-Digest`|Digest of the targeted content for the request.| - -###### On Success: Temporary Redirect - -``` -307 Temporary Redirect -Location: -Docker-Content-Digest: -``` - -The blob identified by `digest` is available at the provided location. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|The location where the layer should be accessible.| -|`Docker-Content-Digest`|Digest of the targeted content for the request.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -There was a problem with the request that needs to be addressed by the client, such as an invalid `name` or `tag`. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The blob, identified by `name` and `digest`, is unknown to the registry. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | -| `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -##### Fetch Blob Part - -``` -GET /v2//blobs/ -Host: -Authorization: -Range: bytes=- -``` - -This endpoint may also support RFC7233 compliant range requests. Support can be detected by issuing a HEAD request. If the header `Accept-Range: bytes` is returned, range requests can be used to fetch partial content. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Range`|header|HTTP Range header specifying blob chunk.| -|`name`|path|Name of the target repository.| -|`digest`|path|Digest of desired blob.| - - - - -###### On Success: Partial Content - -``` -206 Partial Content -Content-Length: -Content-Range: bytes -/ -Content-Type: application/octet-stream - - -``` - -The blob identified by `digest` is available. The specified chunk of blob content will be present in the body of the request. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|The length of the requested blob chunk.| -|`Content-Range`|Content range of blob chunk.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -There was a problem with the request that needs to be addressed by the client, such as an invalid `name` or `tag`. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - - - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | -| `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. | - - - -###### On Failure: Requested Range Not Satisfiable - -``` -416 Requested Range Not Satisfiable -``` - -The range specification cannot be satisfied for the requested content. This can happen when the range is not formatted correctly or if the range is outside of the valid size of the content. - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - -#### DELETE Blob - -Delete the blob identified by `name` and `digest` - - - -``` -DELETE /v2//blobs/ -Host: -Authorization: -``` - - - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`digest`|path|Digest of desired blob.| - - - - -###### On Success: Accepted - -``` -202 Accepted -Content-Length: 0 -Docker-Content-Digest: -``` - - - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|0| -|`Docker-Content-Digest`|Digest of the targeted content for the request.| - - - - -###### On Failure: Invalid Name or Digest - -``` -400 Bad Request -``` - - - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The blob, identified by `name` and `digest`, is unknown to the registry. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | -| `BLOB_UNKNOWN` | blob unknown to registry | This error may be returned when a blob is unknown to the registry in a specified repository. This can be returned with a standard get or if a manifest references an unknown layer during upload. | - - - -###### On Failure: Method Not Allowed - -``` -405 Method Not Allowed -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -Blob delete is not allowed because the registry is configured as a pull-through cache or `delete` has been disabled - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - - -### Initiate Blob Upload - -Initiate a blob upload. This endpoint can be used to create resumable uploads or monolithic uploads. - - - -#### POST Initiate Blob Upload - -Initiate a resumable blob upload. If successful, an upload location will be provided to complete the upload. Optionally, if the `digest` parameter is present, the request body will be used to complete the upload in a single request. - - -##### Initiate Monolithic Blob Upload - -``` -POST /v2//blobs/uploads/?digest= -Host: -Authorization: -Content-Length: -Content-Type: application/octect-stream - - -``` - -Upload a blob identified by the `digest` parameter in single request. This upload will not be resumable unless a recoverable error is returned. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Content-Length`|header|| -|`name`|path|Name of the target repository.| -|`digest`|query|Digest of uploaded blob. If present, the upload will be completed, in a single request, with contents of the request body as the resulting blob.| - - - - -###### On Success: Created - -``` -201 Created -Location: -Content-Length: 0 -Docker-Upload-UUID: -``` - -The blob has been created in the registry and is available at the provided location. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Upload-UUID`|Identifies the docker upload uuid for the current request.| - - - - -###### On Failure: Invalid Name or Digest - -``` -400 Bad Request -``` - - - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | - - - -###### On Failure: Not allowed - -``` -405 Method Not Allowed -``` - -Blob upload is not allowed because the registry is configured as a pull-through cache or for some other reason - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -##### Initiate Resumable Blob Upload - -``` -POST /v2//blobs/uploads/ -Host: -Authorization: -Content-Length: 0 -``` - -Initiate a resumable blob upload with an empty request body. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Content-Length`|header|The `Content-Length` header must be zero and the body must be empty.| -|`name`|path|Name of the target repository.| - - - - -###### On Success: Accepted - -``` -202 Accepted -Content-Length: 0 -Location: /v2//blobs/uploads/ -Range: 0-0 -Docker-Upload-UUID: -``` - -The upload has been created. The `Location` header must be used to complete the upload. The response should be identical to a `GET` request on the contents of the returned `Location` header. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Location`|The location of the created upload. Clients should use the contents verbatim to complete the upload, adding parameters where required.| -|`Range`|Range header indicating the progress of the upload. When starting an upload, it will return an empty range, since no content has been received.| -|`Docker-Upload-UUID`|Identifies the docker upload uuid for the current request.| - - - - -###### On Failure: Invalid Name or Digest - -``` -400 Bad Request -``` - - - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -##### Mount Blob - -``` -POST /v2//blobs/uploads/?mount=&from= -Host: -Authorization: -Content-Length: 0 -``` - -Mount a blob identified by the `mount` parameter from another repository. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Content-Length`|header|The `Content-Length` header must be zero and the body must be empty.| -|`name`|path|Name of the target repository.| -|`mount`|query|Digest of blob to mount from the source repository.| -|`from`|query|Name of the source repository.| - - - - -###### On Success: Created - -``` -201 Created -Location: -Content-Length: 0 -Docker-Upload-UUID: -``` - -The blob has been mounted in the repository and is available at the provided location. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Upload-UUID`|Identifies the docker upload uuid for the current request.| - - - - -###### On Failure: Invalid Name or Digest - -``` -400 Bad Request -``` - - - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | - - - -###### On Failure: Not allowed - -``` -405 Method Not Allowed -``` - -Blob mount is not allowed because the registry is configured as a pull-through cache or for some other reason - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - - -### Blob Upload - -Interact with blob uploads. Clients should never assemble URLs for this endpoint and should only take it through the `Location` header on related API requests. The `Location` header and its parameters should be preserved by clients, using the latest value returned via upload related API calls. - - - -#### GET Blob Upload - -Retrieve status of upload identified by `uuid`. The primary purpose of this endpoint is to resolve the current status of a resumable upload. - - - -``` -GET /v2//blobs/uploads/ -Host: -Authorization: -``` - -Retrieve the progress of the current upload, as reported by the `Range` header. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.| - - - - -###### On Success: Upload Progress - -``` -204 No Content -Range: 0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -The upload is known and in progress. The last received offset is available in the `Range` header. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Range`|Range indicating the current progress of the upload.| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Upload-UUID`|Identifies the docker upload uuid for the current request.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -There was an error processing the upload and it must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `BLOB_UPLOAD_INVALID` | blob upload invalid | The blob upload encountered an error and can no longer proceed. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The upload is unknown to the registry. The upload must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `BLOB_UPLOAD_UNKNOWN` | blob upload unknown to registry | If a blob upload has been cancelled or was never started, this error code may be returned. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - -#### PATCH Blob Upload - -Upload a chunk of data for the specified upload. - - -##### Stream upload - -``` -PATCH /v2//blobs/uploads/ -Host: -Authorization: -Content-Type: application/octet-stream - - -``` - -Upload a stream of data to upload without completing the upload. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`name`|path|Name of the target repository.| -|`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.| - - - - -###### On Success: Data Accepted - -``` -204 No Content -Location: /v2//blobs/uploads/ -Range: 0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -The stream of data has been accepted and the current progress is available in the range header. The updated upload location is available in the `Location` header. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|The location of the upload. Clients should assume this changes after each request. Clients should use the contents verbatim to complete the upload, adding parameters where required.| -|`Range`|Range indicating the current progress of the upload.| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Upload-UUID`|Identifies the docker upload uuid for the current request.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -There was an error processing the upload and it must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `BLOB_UPLOAD_INVALID` | blob upload invalid | The blob upload encountered an error and can no longer proceed. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The upload is unknown to the registry. The upload must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `BLOB_UPLOAD_UNKNOWN` | blob upload unknown to registry | If a blob upload has been cancelled or was never started, this error code may be returned. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - -##### Chunked upload - -``` -PATCH /v2//blobs/uploads/ -Host: -Authorization: -Content-Range: - -Content-Length: -Content-Type: application/octet-stream - - -``` - -Upload a chunk of data to specified upload without completing the upload. The data will be uploaded to the specified Content Range. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Content-Range`|header|Range of bytes identifying the desired block of content represented by the body. Start must the end offset retrieved via status check plus one. Note that this is a non-standard use of the `Content-Range` header.| -|`Content-Length`|header|Length of the chunk being uploaded, corresponding the length of the request body.| -|`name`|path|Name of the target repository.| -|`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.| - - - - -###### On Success: Chunk Accepted - -``` -204 No Content -Location: /v2//blobs/uploads/ -Range: 0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -The chunk of data has been accepted and the current progress is available in the range header. The updated upload location is available in the `Location` header. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|The location of the upload. Clients should assume this changes after each request. Clients should use the contents verbatim to complete the upload, adding parameters where required.| -|`Range`|Range indicating the current progress of the upload.| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Upload-UUID`|Identifies the docker upload uuid for the current request.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -There was an error processing the upload and it must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `BLOB_UPLOAD_INVALID` | blob upload invalid | The blob upload encountered an error and can no longer proceed. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The upload is unknown to the registry. The upload must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `BLOB_UPLOAD_UNKNOWN` | blob upload unknown to registry | If a blob upload has been cancelled or was never started, this error code may be returned. | - - - -###### On Failure: Requested Range Not Satisfiable - -``` -416 Requested Range Not Satisfiable -``` - -The `Content-Range` specification cannot be accepted, either because it does not overlap with the current progress or it is invalid. - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - -#### PUT Blob Upload - -Complete the upload specified by `uuid`, optionally appending the body as the final chunk. - - - -``` -PUT /v2//blobs/uploads/?digest= -Host: -Authorization: -Content-Length: -Content-Type: application/octet-stream - - -``` - -Complete the upload, providing all the data in the body, if necessary. A request without a body will just complete the upload with previously uploaded content. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Content-Length`|header|Length of the data being uploaded, corresponding to the length of the request body. May be zero if no data is provided.| -|`name`|path|Name of the target repository.| -|`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.| -|`digest`|query|Digest of uploaded blob.| - - - - -###### On Success: Upload Complete - -``` -204 No Content -Location: -Content-Range: - -Content-Length: 0 -Docker-Content-Digest: -``` - -The upload has been completed and accepted by the registry. The canonical location will be available in the `Location` header. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Location`|The canonical location of the blob for retrieval| -|`Content-Range`|Range of bytes identifying the desired block of content represented by the body. Start must match the end of offset retrieved via status check. Note that this is a non-standard use of the `Content-Range` header.| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| -|`Docker-Content-Digest`|Digest of the targeted content for the request.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -There was an error processing the upload and it must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DIGEST_INVALID` | provided digest did not match uploaded content | When a blob is uploaded, the registry will check that the content matches the digest provided by the client. The error may include a detail structure with the key "digest", including the invalid digest string. This error may also be returned when a manifest includes an invalid layer digest. | -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `BLOB_UPLOAD_INVALID` | blob upload invalid | The blob upload encountered an error and can no longer proceed. | -| `UNSUPPORTED` | The operation is unsupported. | The operation was unsupported due to a missing implementation or invalid set of parameters. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The upload is unknown to the registry. The upload must be restarted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `BLOB_UPLOAD_UNKNOWN` | blob upload unknown to registry | If a blob upload has been cancelled or was never started, this error code may be returned. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - -#### DELETE Blob Upload - -Cancel outstanding upload processes, releasing associated resources. If this is not called, the unfinished uploads will eventually timeout. - - - -``` -DELETE /v2//blobs/uploads/ -Host: -Authorization: -Content-Length: 0 -``` - -Cancel the upload specified by `uuid`. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`Host`|header|Standard HTTP Host Header. Should be set to the registry host.| -|`Authorization`|header|An RFC7235 compliant authorization header.| -|`Content-Length`|header|The `Content-Length` header must be zero and the body must be empty.| -|`name`|path|Name of the target repository.| -|`uuid`|path|A uuid identifying the upload. This field can accept characters that match `[a-zA-Z0-9-_.=]+`.| - - - - -###### On Success: Upload Deleted - -``` -204 No Content -Content-Length: 0 -``` - -The upload has been successfully deleted. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|The `Content-Length` header must be zero and the body must be empty.| - - - - -###### On Failure: Bad Request - -``` -400 Bad Request -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -An error was encountered processing the delete. The client may ignore this error. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_INVALID` | invalid repository name | Invalid repository name encountered either during manifest validation or any API operation. | -| `BLOB_UPLOAD_INVALID` | blob upload invalid | The blob upload encountered an error and can no longer proceed. | - - - -###### On Failure: Not Found - -``` -404 Not Found -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The upload is unknown to the registry. The client may ignore this error and assume the upload has been deleted. - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `BLOB_UPLOAD_UNKNOWN` | blob upload unknown to registry | If a blob upload has been cancelled or was never started, this error code may be returned. | - - - -###### On Failure: Authentication Required - -``` -401 Unauthorized -WWW-Authenticate: realm="", ..." -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client is not authenticated. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`WWW-Authenticate`|An RFC7235 compliant authentication challenge header.| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `UNAUTHORIZED` | authentication required | The access controller was unable to authenticate the client. Often this will be accompanied by a Www-Authenticate HTTP response header indicating how to authenticate. | - - - -###### On Failure: No Such Repository Error - -``` -404 Not Found -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The repository is not known to the registry. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `NAME_UNKNOWN` | repository name not known to registry | This is returned if the name used during an operation is unknown to the registry. | - - - -###### On Failure: Access Denied - -``` -403 Forbidden -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client does not have required access to the repository. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `DENIED` | requested access to the resource is denied | The access controller denied access for the operation on a resource. | - - - -###### On Failure: Too Many Requests - -``` -429 Too Many Requests -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "errors:" [ - { - "code": , - "message": "", - "detail": ... - }, - ... - ] -} -``` - -The client made too many requests within a time interval. - -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times | - - - - - -### Catalog - -List a set of available repositories in the local registry cluster. Does not provide any indication of what may be available upstream. Applications can only determine if a repository is available but not if it is not available. - - - -#### GET Catalog - -Retrieve a sorted, json list of repositories available in the registry. - - -##### Catalog Fetch - -``` -GET /v2/_catalog -``` - -Request an unabridged list of repositories available. The implementation may impose a maximum limit and return a partial set with pagination links. - - - - - -###### On Success: OK - -``` -200 OK -Content-Length: -Content-Type: application/json; charset=utf-8 - -{ - "repositories": [ - , - ... - ] -} -``` - -Returns the unabridged list of repositories as a json response. - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| - - - -##### Catalog Fetch Paginated - -``` -GET /v2/_catalog?n=&last= -``` - -Return the specified portion of repositories. - - -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -|`n`|query|Limit the number of entries in each response. It not present, all entries will be returned.| -|`last`|query|Result set will include values lexically after last.| - - - - -###### On Success: OK - -``` -200 OK -Content-Length: -Link: <?n=&last=>; rel="next" -Content-Type: application/json; charset=utf-8 - -{ - "repositories": [ - , - ... - ] - "next": "?last=&n=" -} -``` - - - -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -|`Content-Length`|Length of the JSON response body.| -|`Link`|RFC5988 compliant rel='next' with URL to next result set, if available| - - - - - diff --git a/_vendor/github.com/distribution/distribution/docs/spec/api.md.tmpl b/_vendor/github.com/distribution/distribution/docs/spec/api.md.tmpl deleted file mode 100644 index 9dce5f5b8c9..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/api.md.tmpl +++ /dev/null @@ -1,1217 +0,0 @@ ---- -title: "HTTP API V2" -description: "Specification for the Registry API." -keywords: registry, on-prem, images, tags, repository, distribution, api, advanced -redirect_from: - - /reference/api/registry_api/ ---- - -# Docker Registry HTTP API V2 - -## Introduction - -The _Docker Registry HTTP API_ is the protocol to facilitate distribution of -images to the docker engine. It interacts with instances of the docker -registry, which is a service to manage information about docker images and -enable their distribution. The specification covers the operation of version 2 -of this API, known as _Docker Registry HTTP API V2_. - -While the V1 registry protocol is usable, there are several problems with the -architecture that have led to this new version. The main driver of this -specification is a set of changes to the Docker image format, covered in -[docker/docker#8093](https://github.com/docker/docker/issues/8093). -The new, self-contained image manifest simplifies image definition and improves -security. This specification will build on that work, leveraging new properties -of the manifest format to improve performance, reduce bandwidth usage and -decrease the likelihood of backend corruption. - -For relevant details and history leading up to this specification, please see -the following issues: - -- [docker/docker#8093](https://github.com/docker/docker/issues/8093) -- [docker/docker#9015](https://github.com/docker/docker/issues/9015) -- [docker/docker-registry#612](https://github.com/docker/docker-registry/issues/612) - -### Scope - -This specification covers the URL layout and protocols of the interaction -between docker registry and docker core. This will affect the docker core -registry API and the rewrite of docker-registry. Docker registry -implementations may implement other API endpoints, but they are not covered by -this specification. - -This includes the following features: - -- Namespace-oriented URI Layout -- PUSH/PULL registry server for V2 image manifest format -- Resumable layer PUSH support -- V2 Client library implementation - -While authentication and authorization support will influence this -specification, details of the protocol will be left to a future specification. -Relevant header definitions and error codes are present to provide an -indication of what a client may encounter. - -#### Future - -There are features that have been discussed during the process of cutting this -specification. The following is an incomplete list: - -- Immutable image references -- Multiple architecture support -- Migration from v2compatibility representation - -These may represent features that are either out of the scope of this -specification, the purview of another specification or have been deferred to a -future version. - -### Use Cases - -For the most part, the use cases of the former registry API apply to the new -version. Differentiating use cases are covered below. - -#### Image Verification - -A docker engine instance would like to run verified image named -"library/ubuntu", with the tag "latest". The engine contacts the registry, -requesting the manifest for "library/ubuntu:latest". An untrusted registry -returns a manifest. Before proceeding to download the individual layers, the -engine verifies the manifest's signature, ensuring that the content was -produced from a trusted source and no tampering has occurred. After each layer -is downloaded, the engine verifies the digest of the layer, ensuring that the -content matches that specified by the manifest. - -#### Resumable Push - -Company X's build servers lose connectivity to docker registry before -completing an image layer transfer. After connectivity returns, the build -server attempts to re-upload the image. The registry notifies the build server -that the upload has already been partially attempted. The build server -responds by only sending the remaining data to complete the image file. - -#### Resumable Pull - -Company X is having more connectivity problems but this time in their -deployment datacenter. When downloading an image, the connection is -interrupted before completion. The client keeps the partial data and uses http -`Range` requests to avoid downloading repeated data. - -#### Layer Upload De-duplication - -Company Y's build system creates two identical docker layers from build -processes A and B. Build process A completes uploading the layer before B. -When process B attempts to upload the layer, the registry indicates that its -not necessary because the layer is already known. - -If process A and B upload the same layer at the same time, both operations -will proceed and the first to complete will be stored in the registry (Note: -we may modify this to prevent dogpile with some locking mechanism). - -### Changes - -The V2 specification has been written to work as a living document, specifying -only what is certain and leaving what is not specified open or to future -changes. Only non-conflicting additions should be made to the API and accepted -changes should avoid preventing future changes from happening. - -This section should be updated when changes are made to the specification, -indicating what is different. Optionally, we may start marking parts of the -specification to correspond with the versions enumerated here. - -Each set of changes is given a letter corresponding to a set of modifications -that were applied to the baseline specification. These are merely for -reference and shouldn't be used outside the specification other than to -identify a set of modifications. - -
-
l
-
-
    -
  • Document TOOMANYREQUESTS error code.
  • -
-
- -
k
-
-
    -
  • Document use of Accept and Content-Type headers in manifests endpoint.
  • -
-
- -
j
-
-
    -
  • Add ability to mount blobs across repositories.
  • -
-
- -
i
-
-
    -
  • Clarified expected behavior response to manifest HEAD request.
  • -
-
- -
h
-
-
    -
  • All mention of tarsum removed.
  • -
-
- -
g
-
-
    -
  • Clarify behavior of pagination behavior with unspecified parameters.
  • -
-
- -
f
-
-
    -
  • Specify the delete API for layers and manifests.
  • -
-
- -
e
-
-
    -
  • Added support for listing registry contents.
  • -
  • Added pagination to tags API.
  • -
  • Added common approach to support pagination.
  • -
-
- -
d
-
-
    -
  • Allow repository name components to be one character.
  • -
  • Clarified that single component names are allowed.
  • -
-
- -
c
-
-
    -
  • Added section covering digest format.
  • -
  • Added more clarification that manifest cannot be deleted by tag.
  • -
-
- -
b
-
-
    -
  • Added capability of doing streaming upload to PATCH blob upload.
  • -
  • Updated PUT blob upload to no longer take final chunk, now requires entire data or no data.
  • -
  • Removed `416 Requested Range Not Satisfiable` response status from PUT blob upload.
  • -
-
- -
a
-
-
    -
  • Added support for immutable manifest references in manifest endpoints.
  • -
  • Deleting a manifest by tag has been deprecated.
  • -
  • Specified `Docker-Content-Digest` header for appropriate entities.
  • -
  • Added error code for unsupported operations.
  • -
-
-
- -## Overview - -This section covers client flows and details of the API endpoints. The URI -layout of the new API is structured to support a rich authentication and -authorization model by leveraging namespaces. All endpoints will be prefixed -by the API version and the repository name: - - /v2// - -For example, an API endpoint that will work with the `library/ubuntu` -repository, the URI prefix will be: - - /v2/library/ubuntu/ - -This scheme provides rich access control over various operations and methods -using the URI prefix and http methods that can be controlled in variety of -ways. - -Classically, repository names have always been two path components where each -path component is less than 30 characters. The V2 registry API does not -enforce this. The rules for a repository name are as follows: - -1. A repository name is broken up into _path components_. A component of a - repository name must be at least one lowercase, alpha-numeric characters, - optionally separated by periods, dashes or underscores. More strictly, it - must match the regular expression `[a-z0-9]+(?:[._-][a-z0-9]+)*`. -2. If a repository name has two or more path components, they must be - separated by a forward slash ("/"). -3. The total length of a repository name, including slashes, must be less than - 256 characters. - -These name requirements _only_ apply to the registry API and should accept a -superset of what is supported by other docker ecosystem components. - -All endpoints should support aggressive http caching, compression and range -headers, where appropriate. The new API attempts to leverage HTTP semantics -where possible but may break from standards to implement targeted features. - -For detail on individual endpoints, please see the [_Detail_](#detail) -section. - -### Errors - -Actionable failure conditions, covered in detail in their relevant sections, -are reported as part of 4xx responses, in a json response body. One or more -errors will be returned in the following format: - - { - "errors:" [{ - "code": , - "message": , - "detail": - }, - ... - ] - } - -The `code` field will be a unique identifier, all caps with underscores by -convention. The `message` field will be a human readable string. The optional -`detail` field may contain arbitrary json data providing information the -client can use to resolve the issue. - -While the client can take action on certain error codes, the registry may add -new error codes over time. All client implementations should treat unknown -error codes as `UNKNOWN`, allowing future error codes to be added without -breaking API compatibility. For the purposes of the specification error codes -will only be added and never removed. - -For a complete account of all error codes, please see the [_Errors_](#errors-2) -section. - -### API Version Check - -A minimal endpoint, mounted at `/v2/` will provide version support information -based on its response statuses. The request format is as follows: - - GET /v2/ - -If a `200 OK` response is returned, the registry implements the V2(.1) -registry API and the client may proceed safely with other V2 operations. -Optionally, the response may contain information about the supported paths in -the response body. The client should be prepared to ignore this data. - -If a `401 Unauthorized` response is returned, the client should take action -based on the contents of the "WWW-Authenticate" header and try the endpoint -again. Depending on access control setup, the client may still have to -authenticate against different resources, even if this check succeeds. - -If `404 Not Found` response status, or other unexpected status, is returned, -the client should proceed with the assumption that the registry does not -implement V2 of the API. - -When a `200 OK` or `401 Unauthorized` response is returned, the -"Docker-Distribution-API-Version" header should be set to "registry/2.0". -Clients may require this header value to determine if the endpoint serves this -API. When this header is omitted, clients may fallback to an older API version. - -### Content Digests - -This API design is driven heavily by [content addressability](http://en.wikipedia.org/wiki/Content-addressable_storage). -The core of this design is the concept of a content addressable identifier. It -uniquely identifies content by taking a collision-resistant hash of the bytes. -Such an identifier can be independently calculated and verified by selection -of a common _algorithm_. If such an identifier can be communicated in a secure -manner, one can retrieve the content from an insecure source, calculate it -independently and be certain that the correct content was obtained. Put simply, -the identifier is a property of the content. - -To disambiguate from other concepts, we call this identifier a _digest_. A -_digest_ is a serialized hash result, consisting of a _algorithm_ and _hex_ -portion. The _algorithm_ identifies the methodology used to calculate the -digest. The _hex_ portion is the hex-encoded result of the hash. - -We define a _digest_ string to match the following grammar: -``` -digest := algorithm ":" hex -algorithm := /[A-Fa-f0-9_+.-]+/ -hex := /[A-Fa-f0-9]+/ -``` - -Some examples of _digests_ include the following: - -digest | description | -----------------------------------------------------------------------------------|------------------------------------------------ -sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b | Common sha256 based digest | - -While the _algorithm_ does allow one to implement a wide variety of -algorithms, compliant implementations should use sha256. Heavy processing of -input before calculating a hash is discouraged to avoid degrading the -uniqueness of the _digest_ but some canonicalization may be performed to -ensure consistent identifiers. - -Let's use a simple example in pseudo-code to demonstrate a digest calculation: -``` -let C = 'a small string' -let B = sha256(C) -let D = 'sha256:' + EncodeHex(B) -let ID(C) = D -``` - -Above, we have bytestring `C` passed into a function, `SHA256`, that returns a -bytestring `B`, which is the hash of `C`. `D` gets the algorithm concatenated -with the hex encoding of `B`. We then define the identifier of `C` to `ID(C)` -as equal to `D`. A digest can be verified by independently calculating `D` and -comparing it with identifier `ID(C)`. - -#### Digest Header - -To provide verification of http content, any response may include a -`Docker-Content-Digest` header. This will include the digest of the target -entity returned in the response. For blobs, this is the entire blob content. For -manifests, this is the manifest body without the signature content, also known -as the JWS payload. Note that the commonly used canonicalization for digest -calculation may be dependent on the mediatype of the content, such as with -manifests. - -The client may choose to ignore the header or may verify it to ensure content -integrity and transport security. This is most important when fetching by a -digest. To ensure security, the content should be verified against the digest -used to fetch the content. At times, the returned digest may differ from that -used to initiate a request. Such digests are considered to be from different -_domains_, meaning they have different values for _algorithm_. In such a case, -the client may choose to verify the digests in both domains or ignore the -server's digest. To maintain security, the client _must_ always verify the -content against the _digest_ used to fetch the content. - -> __IMPORTANT:__ If a _digest_ is used to fetch content, the client should use -> the same digest used to fetch the content to verify it. The header -> `Docker-Content-Digest` should not be trusted over the "local" digest. - -### Pulling An Image - -An "image" is a combination of a JSON manifest and individual layer files. The -process of pulling an image centers around retrieving these two components. - -The first step in pulling an image is to retrieve the manifest. For reference, -the relevant manifest fields for the registry are the following: - - field | description | -----------|------------------------------------------------| -name | The name of the image. | -tag | The tag for this version of the image. | -fsLayers | A list of layer descriptors (including digest) | -signature | A JWS used to verify the manifest content | - -For more information about the manifest format, please see -[docker/docker#8093](https://github.com/docker/docker/issues/8093). - -When the manifest is in hand, the client must verify the signature to ensure -the names and layers are valid. Once confirmed, the client will then use the -digests to download the individual layers. Layers are stored in as blobs in -the V2 registry API, keyed by their digest. - -#### Pulling an Image Manifest - -The image manifest can be fetched with the following url: - -``` -GET /v2//manifests/ -``` - -The `name` and `reference` parameter identify the image and are required. The -reference may include a tag or digest. - -The client should include an Accept header indicating which manifest content -types it supports. For more details on the manifest formats and their content -types, see [manifest-v2-1.md](manifest-v2-1.md) and -[manifest-v2-2.md](manifest-v2-2.md). In a successful response, the Content-Type -header will indicate which manifest type is being returned. - -A `404 Not Found` response will be returned if the image is unknown to the -registry. If the image exists and the response is successful, the image -manifest will be returned, with the following format (see -[docker/docker#8093](https://github.com/docker/docker/issues/8093) for details): - - { - "name": , - "tag": , - "fsLayers": [ - { - "blobSum": - }, - ... - ] - ], - "history": , - "signature": - } - -The client should verify the returned manifest signature for authenticity -before fetching layers. - -##### Existing Manifests - -The image manifest can be checked for existence with the following url: - -``` -HEAD /v2//manifests/ -``` - -The `name` and `reference` parameter identify the image and are required. The -reference may include a tag or digest. - -A `404 Not Found` response will be returned if the image is unknown to the -registry. If the image exists and the response is successful the response will -be as follows: - -``` -200 OK -Content-Length: -Docker-Content-Digest: -``` - - -#### Pulling a Layer - -Layers are stored in the blob portion of the registry, keyed by digest. -Pulling a layer is carried out by a standard http request. The URL is as -follows: - - GET /v2//blobs/ - -Access to a layer will be gated by the `name` of the repository but is -identified uniquely in the registry by `digest`. - -This endpoint may issue a 307 (302 for /blobs/uploads/ -``` - -The parameters of this request are the image namespace under which the layer -will be linked. Responses to this request are covered below. - -##### Existing Layers - -The existence of a layer can be checked via a `HEAD` request to the blob store -API. The request should be formatted as follows: - -``` -HEAD /v2//blobs/ -``` - -If the layer with the digest specified in `digest` is available, a 200 OK -response will be received, with no actual body content (this is according to -http specification). The response will look as follows: - -``` -200 OK -Content-Length: -Docker-Content-Digest: -``` - -When this response is received, the client can assume that the layer is -already available in the registry under the given name and should take no -further action to upload the layer. Note that the binary digests may differ -for the existing registry layer, but the digests will be guaranteed to match. - -##### Uploading the Layer - -If the POST request is successful, a `202 Accepted` response will be returned -with the upload URL in the `Location` header: - -``` -202 Accepted -Location: /v2//blobs/uploads/ -Range: bytes=0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -The rest of the upload process can be carried out with the returned url, -called the "Upload URL" from the `Location` header. All responses to the -upload url, whether sending data or getting status, will be in this format. -Though the URI format (`/v2//blobs/uploads/`) for the `Location` -header is specified, clients should treat it as an opaque url and should never -try to assemble it. While the `uuid` parameter may be an actual UUID, this -proposal imposes no constraints on the format and clients should never impose -any. - -If clients need to correlate local upload state with remote upload state, the -contents of the `Docker-Upload-UUID` header should be used. Such an id can be -used to key the last used location header when implementing resumable uploads. - -##### Upload Progress - -The progress and chunk coordination of the upload process will be coordinated -through the `Range` header. While this is a non-standard use of the `Range` -header, there are examples of [similar approaches](https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol) in APIs with heavy use. -For an upload that just started, for an example with a 1000 byte layer file, -the `Range` header would be as follows: - -``` -Range: bytes=0-0 -``` - -To get the status of an upload, issue a GET request to the upload URL: - -``` -GET /v2//blobs/uploads/ -Host: -``` - -The response will be similar to the above, except will return 204 status: - -``` -204 No Content -Location: /v2//blobs/uploads/ -Range: bytes=0- -Docker-Upload-UUID: -``` - -Note that the HTTP `Range` header byte ranges are inclusive and that will be -honored, even in non-standard use cases. - -##### Monolithic Upload - -A monolithic upload is simply a chunked upload with a single chunk and may be -favored by clients that would like to avoided the complexity of chunking. To -carry out a "monolithic" upload, one can simply put the entire content blob to -the provided URL: - -``` -PUT /v2//blobs/uploads/?digest= -Content-Length: -Content-Type: application/octet-stream - - -``` - -The "digest" parameter must be included with the PUT request. Please see the -[_Completed Upload_](#completed-upload) section for details on the parameters -and expected responses. - -##### Chunked Upload - -To carry out an upload of a chunk, the client can specify a range header and -only include that part of the layer file: - -``` -PATCH /v2//blobs/uploads/ -Content-Length: -Content-Range: - -Content-Type: application/octet-stream - - -``` - -There is no enforcement on layer chunk splits other than that the server must -receive them in order. The server may enforce a minimum chunk size. If the -server cannot accept the chunk, a `416 Requested Range Not Satisfiable` -response will be returned and will include a `Range` header indicating the -current status: - -``` -416 Requested Range Not Satisfiable -Location: /v2//blobs/uploads/ -Range: 0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -If this response is received, the client should resume from the "last valid -range" and upload the subsequent chunk. A 416 will be returned under the -following conditions: - -- Invalid Content-Range header format -- Out of order chunk: the range of the next chunk must start immediately after - the "last valid range" from the previous response. - -When a chunk is accepted as part of the upload, a `202 Accepted` response will -be returned, including a `Range` header with the current upload status: - -``` -202 Accepted -Location: /v2//blobs/uploads/ -Range: bytes=0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -##### Completed Upload - -For an upload to be considered complete, the client must submit a `PUT` -request on the upload endpoint with a digest parameter. If it is not provided, -the upload will not be considered complete. The format for the final chunk -will be as follows: - -``` -PUT /v2//blobs/uploads/?digest= -Content-Length: -Content-Range: - -Content-Type: application/octet-stream - - -``` - -Optionally, if all chunks have already been uploaded, a `PUT` request with a -`digest` parameter and zero-length body may be sent to complete and validate -the upload. Multiple "digest" parameters may be provided with different -digests. The server may verify none or all of them but _must_ notify the -client if the content is rejected. - -When the last chunk is received and the layer has been validated, the client -will receive a `201 Created` response: - -``` -201 Created -Location: /v2//blobs/ -Content-Length: 0 -Docker-Content-Digest: -``` - -The `Location` header will contain the registry URL to access the accepted -layer file. The `Docker-Content-Digest` header returns the canonical digest of -the uploaded blob which may differ from the provided digest. Most clients may -ignore the value but if it is used, the client should verify the value against -the uploaded blob data. - -###### Digest Parameter - -The "digest" parameter is designed as an opaque parameter to support -verification of a successful transfer. For example, an HTTP URI parameter -might be as follows: - -``` -sha256:6c3c624b58dbbcd3c0dd82b4c53f04194d1247c6eebdaab7c610cf7d66709b3b -``` - -Given this parameter, the registry will verify that the provided content does -match this digest. - -##### Canceling an Upload - -An upload can be cancelled by issuing a DELETE request to the upload endpoint. -The format will be as follows: - -``` -DELETE /v2//blobs/uploads/ -``` - -After this request is issued, the upload uuid will no longer be valid and the -registry server will dump all intermediate data. While uploads will time out -if not completed, clients should issue this request if they encounter a fatal -error but still have the ability to issue an http request. - -##### Cross Repository Blob Mount - -A blob may be mounted from another repository that the client has read access -to, removing the need to upload a blob already known to the registry. To issue -a blob mount instead of an upload, a POST request should be issued in the -following format: - -``` -POST /v2//blobs/uploads/?mount=&from= -Content-Length: 0 -``` - -If the blob is successfully mounted, the client will receive a `201 Created` -response: - -``` -201 Created -Location: /v2//blobs/ -Content-Length: 0 -Docker-Content-Digest: -``` - -The `Location` header will contain the registry URL to access the accepted -layer file. The `Docker-Content-Digest` header returns the canonical digest of -the uploaded blob which may differ from the provided digest. Most clients may -ignore the value but if it is used, the client should verify the value against -the uploaded blob data. - -If a mount fails due to invalid repository or digest arguments, the registry -will fall back to the standard upload behavior and return a `202 Accepted` with -the upload URL in the `Location` header: - -``` -202 Accepted -Location: /v2//blobs/uploads/ -Range: bytes=0- -Content-Length: 0 -Docker-Upload-UUID: -``` - -This behavior is consistent with older versions of the registry, which do not -recognize the repository mount query parameters. - -Note: a client may issue a HEAD request to check existence of a blob in a source -repository to distinguish between the registry not supporting blob mounts and -the blob not existing in the expected repository. - -##### Errors - -If an 502, 503 or 504 error is received, the client should assume that the -download can proceed due to a temporary condition, honoring the appropriate -retry mechanism. Other 5xx errors should be treated as terminal. - -If there is a problem with the upload, a 4xx error will be returned indicating -the problem. After receiving a 4xx response (except 416, as called out above), -the upload will be considered failed and the client should take appropriate -action. - -Note that the upload url will not be available forever. If the upload uuid is -unknown to the registry, a `404 Not Found` response will be returned and the -client must restart the upload process. - -#### Deleting a Layer - -A layer may be deleted from the registry via its `name` and `digest`. A -delete may be issued with the following request format: - - DELETE /v2//blobs/ - -If the blob exists and has been successfully deleted, the following response -will be issued: - - 202 Accepted - Content-Length: None - -If the blob had already been deleted or did not exist, a `404 Not Found` -response will be issued instead. - -If a layer is deleted which is referenced by a manifest in the registry, -then the complete images will not be resolvable. - -#### Pushing an Image Manifest - -Once all of the layers for an image are uploaded, the client can upload the -image manifest. An image can be pushed using the following request format: - - PUT /v2//manifests/ - Content-Type: - - { - "name": , - "tag": , - "fsLayers": [ - { - "blobSum": - }, - ... - ] - ], - "history": , - "signature": , - ... - } - -The `name` and `reference` fields of the response body must match those -specified in the URL. The `reference` field may be a "tag" or a "digest". The -content type should match the type of the manifest being uploaded, as specified -in [manifest-v2-1.md](manifest-v2-1.md) and [manifest-v2-2.md](manifest-v2-2.md). - -If there is a problem with pushing the manifest, a relevant 4xx response will -be returned with a JSON error message. Please see the -[_PUT Manifest_](#put-manifest) section for details on possible error codes that -may be returned. - -If one or more layers are unknown to the registry, `BLOB_UNKNOWN` errors are -returned. The `detail` field of the error response will have a `digest` field -identifying the missing blob. An error is returned for each unknown blob. The -response format is as follows: - - { - "errors:" [{ - "code": "BLOB_UNKNOWN", - "message": "blob unknown to registry", - "detail": { - "digest": - } - }, - ... - ] - } - -### Listing Repositories - -Images are stored in collections, known as a _repository_, which is keyed by a -`name`, as seen throughout the API specification. A registry instance may -contain several repositories. The list of available repositories is made -available through the _catalog_. - -The catalog for a given registry can be retrieved with the following request: - -``` -GET /v2/_catalog -``` - -The response will be in the following format: - -``` -200 OK -Content-Type: application/json - -{ - "repositories": [ - , - ... - ] -} -``` - -Note that the contents of the response are specific to the registry -implementation. Some registries may opt to provide a full catalog output, -limit it based on the user's access level or omit upstream results, if -providing mirroring functionality. Subsequently, the presence of a repository -in the catalog listing only means that the registry *may* provide access to -the repository at the time of the request. Conversely, a missing entry does -*not* mean that the registry does not have the repository. More succinctly, -the presence of a repository only guarantees that it is there but not that it -is _not_ there. - -For registries with a large number of repositories, this response may be quite -large. If such a response is expected, one should use pagination. A registry -may also limit the amount of responses returned even if pagination was not -explicitly requested. In this case the `Link` header will be returned along -with the results, and subsequent results can be obtained by following the link -as if pagination had been initially requested. - -For details of the `Link` header, please see the [_Pagination_](#pagination) -section. - -#### Pagination - -Paginated catalog results can be retrieved by adding an `n` parameter to the -request URL, declaring that the response should be limited to `n` results. -Starting a paginated flow begins as follows: - -``` -GET /v2/_catalog?n= -``` - -The above specifies that a catalog response should be returned, from the start of -the result set, ordered lexically, limiting the number of results to `n`. The -response to such a request would look as follows: - -``` -200 OK -Content-Type: application/json -Link: <?n=&last=>; rel="next" - -{ - "repositories": [ - , - ... - ] -} -``` - -The above includes the _first_ `n` entries from the result set. To get the -_next_ `n` entries, one can create a URL where the argument `last` has the -value from `repositories[len(repositories)-1]`. If there are indeed more -results, the URL for the next block is encoded in an -[RFC5988](https://tools.ietf.org/html/rfc5988) `Link` header, as a "next" -relation. The presence of the `Link` header communicates to the client that -the entire result set has not been returned and another request must be -issued. If the header is not present, the client can assume that all results -have been received. - -> __NOTE:__ In the request template above, note that the brackets -> are required. For example, if the url is -> `http://example.com/v2/_catalog?n=20&last=b`, the value of the header would -> be `; rel="next"`. Please see -> [RFC5988](https://tools.ietf.org/html/rfc5988) for details. - -Compliant client implementations should always use the `Link` header -value when proceeding through results linearly. The client may construct URLs -to skip forward in the catalog. - -To get the next result set, a client would issue the request as follows, using -the URL encoded in the described `Link` header: - -``` -GET /v2/_catalog?n=&last= -``` - -The above process should then be repeated until the `Link` header is no longer -set. - -The catalog result set is represented abstractly as a lexically sorted list, -where the position in that list can be specified by the query term `last`. The -entries in the response start _after_ the term specified by `last`, up to `n` -entries. - -The behavior of `last` is quite simple when demonstrated with an example. Let -us say the registry has the following repositories: - -``` -a -b -c -d -``` - -If the value of `n` is 2, _a_ and _b_ will be returned on the first response. -The `Link` header returned on the response will have `n` set to 2 and last set -to _b_: - -``` -Link: <?n=2&last=b>; rel="next" -``` - -The client can then issue the request with the above value from the `Link` -header, receiving the values _c_ and _d_. Note that `n` may change on the second -to last response or be fully omitted, depending on the server implementation. - -### Listing Image Tags - -It may be necessary to list all of the tags under a given repository. The tags -for an image repository can be retrieved with the following request: - - GET /v2//tags/list - -The response will be in the following format: - - 200 OK - Content-Type: application/json - - { - "name": , - "tags": [ - , - ... - ] - } - -For repositories with a large number of tags, this response may be quite -large. If such a response is expected, one should use the pagination. - -#### Pagination - -Paginated tag results can be retrieved by adding the appropriate parameters to -the request URL described above. The behavior of tag pagination is identical -to that specified for catalog pagination. We cover a simple flow to highlight -any differences. - -Starting a paginated flow may begin as follows: - -``` -GET /v2//tags/list?n= -``` - -The above specifies that a tags response should be returned, from the start of -the result set, ordered lexically, limiting the number of results to `n`. The -response to such a request would look as follows: - -``` -200 OK -Content-Type: application/json -Link: <?n=&last=>; rel="next" - -{ - "name": , - "tags": [ - , - ... - ] -} -``` - -To get the next result set, a client would issue the request as follows, using -the value encoded in the [RFC5988](https://tools.ietf.org/html/rfc5988) `Link` -header: - -``` -GET /v2//tags/list?n=&last= -``` - -The above process should then be repeated until the `Link` header is no longer -set in the response. The behavior of the `last` parameter, the provided -response result, lexical ordering and encoding of the `Link` header are -identical to that of catalog pagination. - -### Deleting an Image - -An image may be deleted from the registry via its `name` and `reference`. A -delete may be issued with the following request format: - - DELETE /v2//manifests/ - -For deletes, `reference` *must* be a digest or the delete will fail. If the -image exists and has been successfully deleted, the following response will be -issued: - - 202 Accepted - Content-Length: None - -If the image had already been deleted or did not exist, a `404 Not Found` -response will be issued instead. - -> **Note** When deleting a manifest from a registry version 2.3 or later, the -> following header must be used when `HEAD` or `GET`-ing the manifest to obtain -> the correct digest to delete: - - Accept: application/vnd.docker.distribution.manifest.v2+json - -> for more details, see: [compatibility.md](../compatibility.md#content-addressable-storage-cas) - -## Detail - -> **Note**: This section is still under construction. For the purposes of -> implementation, if any details below differ from the described request flows -> above, the section below should be corrected. When they match, this note -> should be removed. - -The behavior of the endpoints are covered in detail in this section, organized -by route and entity. All aspects of the request and responses are covered, -including headers, parameters and body formats. Examples of requests and their -corresponding responses, with success and failure, are enumerated. - -> **Note**: The sections on endpoint detail are arranged with an example -> request, a description of the request, followed by information about that -> request. - -A list of methods and URIs are covered in the table below: - -|Method|Path|Entity|Description| -|------|----|------|-----------| -{{range $route := .RouteDescriptors}}{{range $method := .Methods}}| {{$method.Method}} | `{{$route.Path|prettygorilla}}` | {{$route.Entity}} | {{$method.Description}} | -{{end}}{{end}} - -The detail for each endpoint is covered in the following sections. - -### Errors - -The error codes encountered via the API are enumerated in the following table: - -|Code|Message|Description| -|----|-------|-----------| -{{range $err := .ErrorDescriptors}} `{{$err.Value}}` | {{$err.Message}} | {{$err.Description|removenewlines}} -{{end}} - -{{range $route := .RouteDescriptors}} -### {{.Entity}} - -{{.Description}} - -{{range $method := $route.Methods}} - -#### {{.Method}} {{$route.Entity}} - -{{.Description}} - -{{if .Requests}}{{range .Requests}}{{if .Name}} -##### {{.Name}}{{end}} - -``` -{{$method.Method}} {{$route.Path|prettygorilla}}{{range $i, $param := .QueryParameters}}{{if eq $i 0}}?{{else}}&{{end}}{{$param.Name}}={{$param.Format}}{{end}}{{range .Headers}} -{{.Name}}: {{.Format}}{{end}}{{if .Body.ContentType}} -Content-Type: {{.Body.ContentType}}{{end}}{{if .Body.Format}} - -{{.Body.Format}}{{end}} -``` - -{{.Description}} - -{{if or .Headers .PathParameters .QueryParameters}} -The following parameters should be specified on the request: - -|Name|Kind|Description| -|----|----|-----------| -{{range .Headers}}|`{{.Name}}`|header|{{.Description}}| -{{end}}{{range .PathParameters}}|`{{.Name}}`|path|{{.Description}}| -{{end}}{{range .QueryParameters}}|`{{.Name}}`|query|{{.Description}}| -{{end}}{{end}} - -{{if .Successes}} -{{range .Successes}} -###### On Success: {{if .Name}}{{.Name}}{{else}}{{.StatusCode | statustext}}{{end}} - -``` -{{.StatusCode}} {{.StatusCode | statustext}}{{range .Headers}} -{{.Name}}: {{.Format}}{{end}}{{if .Body.ContentType}} -Content-Type: {{.Body.ContentType}}{{end}}{{if .Body.Format}} - -{{.Body.Format}}{{end}} -``` - -{{.Description}} -{{if .Fields}}The following fields may be returned in the response body: - -|Name|Description| -|----|-----------| -{{range .Fields}}|`{{.Name}}`|{{.Description}}| -{{end}}{{end}}{{if .Headers}} -The following headers will be returned with the response: - -|Name|Description| -|----|-----------| -{{range .Headers}}|`{{.Name}}`|{{.Description}}| -{{end}}{{end}}{{end}}{{end}} - -{{if .Failures}} -{{range .Failures}} -###### On Failure: {{if .Name}}{{.Name}}{{else}}{{.StatusCode | statustext}}{{end}} - -``` -{{.StatusCode}} {{.StatusCode | statustext}}{{range .Headers}} -{{.Name}}: {{.Format}}{{end}}{{if .Body.ContentType}} -Content-Type: {{.Body.ContentType}}{{end}}{{if .Body.Format}} - -{{.Body.Format}}{{end}} -``` - -{{.Description}} -{{if .Headers}} -The following headers will be returned on the response: - -|Name|Description| -|----|-----------| -{{range .Headers}}|`{{.Name}}`|{{.Description}}| -{{end}}{{end}} - -{{if .ErrorCodes}} -The error codes that may be included in the response body are enumerated below: - -|Code|Message|Description| -|----|-------|-----------| -{{range $err := .ErrorCodes}}| `{{$err.Descriptor.Value}}` | {{$err.Descriptor.Message}} | {{$err.Descriptor.Description|removenewlines}} | -{{end}} - -{{end}}{{end}}{{end}}{{end}}{{end}}{{end}} - -{{end}} diff --git a/_vendor/github.com/distribution/distribution/docs/spec/auth/index.md b/_vendor/github.com/distribution/distribution/docs/spec/auth/index.md deleted file mode 100644 index 8c4bf5e2cdb..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/auth/index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Docker Registry Token Authentication" -description: "Docker Registry v2 authentication schema" -keywords: registry, on-prem, images, tags, repository, distribution, authentication, advanced ---- - -# Docker Registry v2 authentication - -See the [Token Authentication Specification](token.md), -[Token Authentication Implementation](jwt.md), -[Token Scope Documentation](scope.md), -[OAuth2 Token Authentication](oauth.md) for more information. diff --git a/_vendor/github.com/distribution/distribution/docs/spec/auth/jwt.md b/_vendor/github.com/distribution/distribution/docs/spec/auth/jwt.md deleted file mode 100644 index 0538d8e19b6..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/auth/jwt.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -title: "Token Authentication Implementation" -description: "Describe the reference implementation of the Docker Registry v2 authentication schema" -keywords: registry, on-prem, images, tags, repository, distribution, JWT authentication, advanced ---- - -# Docker Registry v2 Bearer token specification - -This specification covers the `docker/distribution` implementation of the -v2 Registry's authentication schema. Specifically, it describes the JSON -Web Token schema that `docker/distribution` has adopted to implement the -client-opaque Bearer token issued by an authentication service and -understood by the registry. - -This document borrows heavily from the [JSON Web Token Draft Spec](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32) - -## Getting a Bearer Token - -For this example, the client makes an HTTP GET request to the following URL: - -``` -https://auth.docker.io/token?service=registry.docker.io&scope=repository:samalba/my-app:pull,push -``` - -The token server should first attempt to authenticate the client using any -authentication credentials provided with the request. As of Docker 1.8, the -registry client in the Docker Engine only supports Basic Authentication to -these token servers. If an attempt to authenticate to the token server fails, -the token server should return a `401 Unauthorized` response indicating that -the provided credentials are invalid. - -Whether the token server requires authentication is up to the policy of that -access control provider. Some requests may require authentication to determine -access (such as pushing or pulling a private repository) while others may not -(such as pulling from a public repository). - -After authenticating the client (which may simply be an anonymous client if -no attempt was made to authenticate), the token server must next query its -access control list to determine whether the client has the requested scope. In -this example request, if I have authenticated as user `jlhawn`, the token -server will determine what access I have to the repository `samalba/my-app` -hosted by the entity `registry.docker.io`. - -Once the token server has determined what access the client has to the -resources requested in the `scope` parameter, it will take the intersection of -the set of requested actions on each resource and the set of actions that the -client has in fact been granted. If the client only has a subset of the -requested access **it must not be considered an error** as it is not the -responsibility of the token server to indicate authorization errors as part of -this workflow. - -Continuing with the example request, the token server will find that the -client's set of granted access to the repository is `[pull, push]` which when -intersected with the requested access `[pull, push]` yields an equal set. If -the granted access set was found only to be `[pull]` then the intersected set -would only be `[pull]`. If the client has no access to the repository then the -intersected set would be empty, `[]`. - -It is this intersected set of access which is placed in the returned token. - -The server will now construct a JSON Web Token to sign and return. A JSON Web -Token has 3 main parts: - -1. Headers - - The header of a JSON Web Token is a standard JOSE header. The "typ" field - will be "JWT" and it will also contain the "alg" which identifies the - signing algorithm used to produce the signature. It also must have a "kid" - field, representing the ID of the key which was used to sign the token. - - The "kid" field has to be in a libtrust fingerprint compatible format. - Such a format can be generated by following steps: - - 1. Take the DER encoded public key which the JWT token was signed against. - - 2. Create a SHA256 hash out of it and truncate to 240bits. - - 3. Split the result into 12 base32 encoded groups with `:` as delimiter. - - Here is an example JOSE Header for a JSON Web Token (formatted with - whitespace for readability): - - ``` - { - "typ": "JWT", - "alg": "ES256", - "kid": "PYYO:TEWU:V7JH:26JV:AQTZ:LJC3:SXVJ:XGHA:34F2:2LAQ:ZRMK:Z7Q6" - } - ``` - - It specifies that this object is going to be a JSON Web token signed using - the key with the given ID using the Elliptic Curve signature algorithm - using a SHA256 hash. - -2. Claim Set - - The Claim Set is a JSON struct containing these standard registered claim - name fields: - -
-
- iss (Issuer) -
-
- The issuer of the token, typically the fqdn of the authorization - server. -
-
- sub (Subject) -
-
- The subject of the token; the name or id of the client which - requested it. This should be empty (`""`) if the client did not - authenticate. -
-
- aud (Audience) -
-
- The intended audience of the token; the name or id of the service - which will verify the token to authorize the client/subject. -
-
- exp (Expiration) -
-
- The token should only be considered valid up to this specified date - and time. -
-
- nbf (Not Before) -
-
- The token should not be considered valid before this specified date - and time. -
-
- iat (Issued At) -
-
- Specifies the date and time which the Authorization server - generated this token. -
-
- jti (JWT ID) -
-
- A unique identifier for this token. Can be used by the intended - audience to prevent replays of the token. -
-
- - The Claim Set will also contain a private claim name unique to this - authorization server specification: - -
-
- access -
-
- An array of access entry objects with the following fields: -
-
- type -
-
- The type of resource hosted by the service. -
-
- name -
-
- The name of the resource of the given type hosted by the - service. -
-
- actions -
-
- An array of strings which give the actions authorized on - this resource. -
-
-
-
- - Here is an example of such a JWT Claim Set (formatted with whitespace for - readability): - - ``` - { - "iss": "auth.docker.com", - "sub": "jlhawn", - "aud": "registry.docker.com", - "exp": 1415387315, - "nbf": 1415387015, - "iat": 1415387015, - "jti": "tYJCO1c6cnyy7kAn0c7rKPgbV1H1bFws", - "access": [ - { - "type": "repository", - "name": "samalba/my-app", - "actions": [ - "pull", - "push" - ] - } - ] - } - ``` - -3. Signature - - The authorization server will produce a JOSE header and Claim Set with no - extraneous whitespace, i.e., the JOSE Header from above would be - - ``` - {"typ":"JWT","alg":"ES256","kid":"PYYO:TEWU:V7JH:26JV:AQTZ:LJC3:SXVJ:XGHA:34F2:2LAQ:ZRMK:Z7Q6"} - ``` - - and the Claim Set from above would be - - ``` - {"iss":"auth.docker.com","sub":"jlhawn","aud":"registry.docker.com","exp":1415387315,"nbf":1415387015,"iat":1415387015,"jti":"tYJCO1c6cnyy7kAn0c7rKPgbV1H1bFws","access":[{"type":"repository","name":"samalba/my-app","actions":["push","pull"]}]} - ``` - - The utf-8 representation of this JOSE header and Claim Set are then - url-safe base64 encoded (sans trailing '=' buffer), producing: - - ``` - eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IlBZWU86VEVXVTpWN0pIOjI2SlY6QVFUWjpMSkMzOlNYVko6WEdIQTozNEYyOjJMQVE6WlJNSzpaN1E2In0 - ``` - - for the JOSE Header and - - ``` - eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJqbGhhd24iLCJhdWQiOiJyZWdpc3RyeS5kb2NrZXIuY29tIiwiZXhwIjoxNDE1Mzg3MzE1LCJuYmYiOjE0MTUzODcwMTUsImlhdCI6MTQxNTM4NzAxNSwianRpIjoidFlKQ08xYzZjbnl5N2tBbjBjN3JLUGdiVjFIMWJGd3MiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InNhbWFsYmEvbXktYXBwIiwiYWN0aW9ucyI6WyJwdXNoIl19XX0 - ``` - - for the Claim Set. These two are concatenated using a '.' character, - yielding the string: - - ``` - eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IlBZWU86VEVXVTpWN0pIOjI2SlY6QVFUWjpMSkMzOlNYVko6WEdIQTozNEYyOjJMQVE6WlJNSzpaN1E2In0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJqbGhhd24iLCJhdWQiOiJyZWdpc3RyeS5kb2NrZXIuY29tIiwiZXhwIjoxNDE1Mzg3MzE1LCJuYmYiOjE0MTUzODcwMTUsImlhdCI6MTQxNTM4NzAxNSwianRpIjoidFlKQ08xYzZjbnl5N2tBbjBjN3JLUGdiVjFIMWJGd3MiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InNhbWFsYmEvbXktYXBwIiwiYWN0aW9ucyI6WyJwdXNoIl19XX0 - ``` - - This is then used as the payload to a the `ES256` signature algorithm - specified in the JOSE header and specified fully in [Section 3.4 of the JSON Web Algorithms (JWA) - draft specification](https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-38#section-3.4) - - This example signature will use the following ECDSA key for the server: - - ``` - { - "kty": "EC", - "crv": "P-256", - "kid": "PYYO:TEWU:V7JH:26JV:AQTZ:LJC3:SXVJ:XGHA:34F2:2LAQ:ZRMK:Z7Q6", - "d": "R7OnbfMaD5J2jl7GeE8ESo7CnHSBm_1N2k9IXYFrKJA", - "x": "m7zUpx3b-zmVE5cymSs64POG9QcyEpJaYCD82-549_Q", - "y": "dU3biz8sZ_8GPB-odm8Wxz3lNDr1xcAQQPQaOcr1fmc" - } - ``` - - A resulting signature of the above payload using this key is: - - ``` - QhflHPfbd6eVF4lM9bwYpFZIV0PfikbyXuLx959ykRTBpe3CYnzs6YBK8FToVb5R47920PVLrh8zuLzdCr9t3w - ``` - - Concatenating all of these together with a `.` character gives the - resulting JWT: - - ``` - eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IlBZWU86VEVXVTpWN0pIOjI2SlY6QVFUWjpMSkMzOlNYVko6WEdIQTozNEYyOjJMQVE6WlJNSzpaN1E2In0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJqbGhhd24iLCJhdWQiOiJyZWdpc3RyeS5kb2NrZXIuY29tIiwiZXhwIjoxNDE1Mzg3MzE1LCJuYmYiOjE0MTUzODcwMTUsImlhdCI6MTQxNTM4NzAxNSwianRpIjoidFlKQ08xYzZjbnl5N2tBbjBjN3JLUGdiVjFIMWJGd3MiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InNhbWFsYmEvbXktYXBwIiwiYWN0aW9ucyI6WyJwdXNoIl19XX0.QhflHPfbd6eVF4lM9bwYpFZIV0PfikbyXuLx959ykRTBpe3CYnzs6YBK8FToVb5R47920PVLrh8zuLzdCr9t3w - ``` - -This can now be placed in an HTTP response and returned to the client to use to -authenticate to the audience service: - - -``` -HTTP/1.1 200 OK -Content-Type: application/json - -{"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IlBZWU86VEVXVTpWN0pIOjI2SlY6QVFUWjpMSkMzOlNYVko6WEdIQTozNEYyOjJMQVE6WlJNSzpaN1E2In0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJqbGhhd24iLCJhdWQiOiJyZWdpc3RyeS5kb2NrZXIuY29tIiwiZXhwIjoxNDE1Mzg3MzE1LCJuYmYiOjE0MTUzODcwMTUsImlhdCI6MTQxNTM4NzAxNSwianRpIjoidFlKQ08xYzZjbnl5N2tBbjBjN3JLUGdiVjFIMWJGd3MiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InNhbWFsYmEvbXktYXBwIiwiYWN0aW9ucyI6WyJwdXNoIl19XX0.QhflHPfbd6eVF4lM9bwYpFZIV0PfikbyXuLx959ykRTBpe3CYnzs6YBK8FToVb5R47920PVLrh8zuLzdCr9t3w"} -``` - -## Using the signed token - -Once the client has a token, it will try the registry request again with the -token placed in the HTTP `Authorization` header like so: - -``` -Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IkJWM0Q6MkFWWjpVQjVaOktJQVA6SU5QTDo1RU42Ok40SjQ6Nk1XTzpEUktFOkJWUUs6M0ZKTDpQT1RMIn0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJCQ0NZOk9VNlo6UUVKNTpXTjJDOjJBVkM6WTdZRDpBM0xZOjQ1VVc6NE9HRDpLQUxMOkNOSjU6NUlVTCIsImF1ZCI6InJlZ2lzdHJ5LmRvY2tlci5jb20iLCJleHAiOjE0MTUzODczMTUsIm5iZiI6MTQxNTM4NzAxNSwiaWF0IjoxNDE1Mzg3MDE1LCJqdGkiOiJ0WUpDTzFjNmNueXk3a0FuMGM3cktQZ2JWMUgxYkZ3cyIsInNjb3BlIjoiamxoYXduOnJlcG9zaXRvcnk6c2FtYWxiYS9teS1hcHA6cHVzaCxwdWxsIGpsaGF3bjpuYW1lc3BhY2U6c2FtYWxiYTpwdWxsIn0.Y3zZSwaZPqy4y9oRBVRImZyv3m_S9XDHF1tWwN7mL52C_IiA73SJkWVNsvNqpJIn5h7A2F8biv_S2ppQ1lgkbw -``` - -This is also described in [Section 2.1 of RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-2.1) - -## Verifying the token - -The registry must now verify the token presented by the user by inspecting the -claim set within. The registry will: - -- Ensure that the issuer (`iss` claim) is an authority it trusts. -- Ensure that the registry identifies as the audience (`aud` claim). -- Check that the current time is between the `nbf` and `exp` claim times. -- If enforcing single-use tokens, check that the JWT ID (`jti` claim) value has - not been seen before. - - To enforce this, the registry may keep a record of `jti`s it has seen for - up to the `exp` time of the token to prevent token replays. -- Check the `access` claim value and use the identified resources and the list - of actions authorized to determine whether the token grants the required - level of access for the operation the client is attempting to perform. -- Verify that the signature of the token is valid. - -If any of these requirements are not met, the registry will return a -`403 Forbidden` response to indicate that the token is invalid. - -**Note**: it is only at this point in the workflow that an authorization error -may occur. The token server should *not* return errors when the user does not -have the requested authorization. Instead, the returned token should indicate -whatever of the requested scope the client does have (the intersection of -requested and granted access). If the token does not supply proper -authorization then the registry will return the appropriate error. - -At no point in this process should the registry need to call back to the -authorization server. The registry only needs to be supplied with the trusted -public keys to verify the token signatures. diff --git a/_vendor/github.com/distribution/distribution/docs/spec/auth/oauth.md b/_vendor/github.com/distribution/distribution/docs/spec/auth/oauth.md deleted file mode 100644 index f646f454ad7..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/auth/oauth.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: "Oauth2 Token Authentication" -description: "Specifies the Docker Registry v2 authentication" -keywords: registry, on-prem, images, tags, repository, distribution, oauth2, advanced ---- - -# Docker Registry v2 authentication using OAuth2 - -This document describes support for the OAuth2 protocol within the authorization -server. [RFC6749](https://tools.ietf.org/html/rfc6749) should be used as a -reference for the protocol and HTTP endpoints described here. - -**Note**: Not all token servers implement oauth2. If the request to the endpoint -returns `404` using the HTTP `POST` method, refer to -[Token Documentation](token.md) for using the HTTP `GET` method supported by all -token servers. - -## Refresh token format - -The format of the refresh token is completely opaque to the client and should be -determined by the authorization server. The authorization should ensure the -token is sufficiently long and is responsible for storing any information about -long-lived tokens which may be needed for revoking. Any information stored -inside the token will not be extracted and presented by clients. - -## Getting a token - -POST /token - -#### Headers -Content-Type: application/x-www-form-urlencoded - -#### Post parameters - -
-
- grant_type -
-
- (REQUIRED) Type of grant used to get token. When getting a refresh token - using credentials this type should be set to "password" and have the - accompanying username and password parameters. Type "authorization_code" - is reserved for future use for authenticating to an authorization server - without having to send credentials directly from the client. When - requesting an access token with a refresh token this should be set to - "refresh_token". -
-
- service -
-
- (REQUIRED) The name of the service which hosts the resource to get - access for. Refresh tokens will only be good for getting tokens for - this service. -
-
- client_id -
-
- (REQUIRED) String identifying the client. This client_id does not need - to be registered with the authorization server but should be set to a - meaningful value in order to allow auditing keys created by unregistered - clients. Accepted syntax is defined in - [RFC6749 Appendix A.1](https://tools.ietf.org/html/rfc6749#appendix-A.1) -
-
- access_type -
-
- (OPTIONAL) Access which is being requested. If "offline" is provided - then a refresh token will be returned. The default is "online" only - returning short lived access token. If the grant type is "refresh_token" - this will only return the same refresh token and not a new one. -
-
- scope -
-
- (OPTIONAL) The resource in question, formatted as one of the space-delimited - entries from the scope parameters from the WWW-Authenticate header - shown above. This query parameter should only be specified once but may - contain multiple scopes using the scope list format defined in the scope - grammar. If multiple scope is provided from - WWW-Authenticate header the scopes should first be - converted to a scope list before requesting the token. The above example - would be specified as: scope=repository:samalba/my-app:push. - When requesting a refresh token the scopes may be empty since the - refresh token will not be limited by this scope, only the provided short - lived access token will have the scope limitation. -
-
- refresh_token -
-
- (OPTIONAL) The refresh token to use for authentication when grant type "refresh_token" is used. -
-
- username -
-
- (OPTIONAL) The username to use for authentication when grant type "password" is used. -
-
- password -
-
- (OPTIONAL) The password to use for authentication when grant type "password" is used. -
-
- -#### Response fields - -
-
- access_token -
-
- (REQUIRED) An opaque Bearer token that clients should - supply to subsequent requests in the Authorization header. - This token should not be attempted to be parsed or understood by the - client but treated as opaque string. -
-
- scope -
-
- (REQUIRED) The scope granted inside the access token. This may be the - same scope as requested or a subset. This requirement is stronger than - specified in [RFC6749 Section 4.2.2](https://tools.ietf.org/html/rfc6749#section-4.2.2) - by strictly requiring the scope in the return value. -
-
- expires_in -
-
- (REQUIRED) The duration in seconds since the token was issued that it - will remain valid. When omitted, this defaults to 60 seconds. For - compatibility with older clients, a token should never be returned with - less than 60 seconds to live. -
-
- issued_at -
-
- (Optional) The RFC3339-serialized UTC - standard time at which a given token was issued. If issued_at is omitted, the - expiration is from when the token exchange completed. -
-
- refresh_token -
-
- (Optional) Token which can be used to get additional access tokens for - the same subject with different scopes. This token should be kept secure - by the client and only sent to the authorization server which issues - bearer tokens. This field will only be set when `access_type=offline` is - provided in the request. -
-
- - -#### Example getting refresh token - -``` -POST /token HTTP/1.1 -Host: auth.docker.io -Content-Type: application/x-www-form-urlencoded - -grant_type=password&username=johndoe&password=A3ddj3w&service=hub.docker.io&client_id=dockerengine&access_type=offline - -HTTP/1.1 200 OK -Content-Type: application/json - -{"refresh_token":"kas9Da81Dfa8","access_token":"eyJhbGciOiJFUzI1NiIsInR5","expires_in":900,"scope":""} -``` - -#### Example refreshing an Access Token - -``` -POST /token HTTP/1.1 -Host: auth.docker.io -Content-Type: application/x-www-form-urlencoded - -grant_type=refresh_token&refresh_token=kas9Da81Dfa8&service=registry-1.docker.io&client_id=dockerengine&scope=repository:samalba/my-app:pull,push - -HTTP/1.1 200 OK -Content-Type: application/json - -{"refresh_token":"kas9Da81Dfa8","access_token":"eyJhbGciOiJFUzI1NiIsInR5":"expires_in":900,"scope":"repository:samalba/my-app:pull,repository:samalba/my-app:push"} -``` diff --git a/_vendor/github.com/distribution/distribution/docs/spec/auth/scope.md b/_vendor/github.com/distribution/distribution/docs/spec/auth/scope.md deleted file mode 100644 index 037fd676206..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/auth/scope.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: "Token Scope Documentation" -description: "Describes the scope and access fields used for registry authorization tokens" -keywords: registry, on-prem, images, tags, repository, distribution, advanced, access, scope ---- - -# Docker Registry Token Scope and Access - -Tokens used by the registry are always restricted what resources they may -be used to access, where those resources may be accessed, and what actions -may be done on those resources. Tokens always have the context of a user which -the token was originally created for. This document describes how these -restrictions are represented and enforced by the authorization server and -resource providers. - -## Scope Components - -### Subject (Authenticated User) - -The subject represents the user for which a token is valid. Any actions -performed using an access token should be considered on behalf of the subject. -This is included in the `sub` field of access token JWT. A refresh token should -be limited to a single subject and only be able to give out access tokens for -that subject. - -### Audience (Resource Provider) - -The audience represents a resource provider which is intended to be able to -perform the actions specified in the access token. Any resource provider which -does not match the audience should not use that access token. The audience is -included in the `aud` field of the access token JWT. A refresh token should be -limited to a single audience and only be able to give out access tokens for that -audience. - -### Resource Type - -The resource type represents the type of resource which the resource name is -intended to represent. This type may be specific to a resource provider but must -be understood by the authorization server in order to validate the subject -is authorized for a specific resource. - -#### Resource Class - -The resource type might have a resource class which further classifies the -the resource name within the resource type. A class is not required and -is specific to the resource type. - -#### Example Resource Types - - - `repository` - represents a single repository within a registry. A -repository may represent many manifest or content blobs, but the resource type -is considered the collections of those items. Actions which may be performed on -a `repository` are `pull` for accessing the collection and `push` for adding to -it. By default the `repository` type has the class of `image`. - - `repository(plugin)` - represents a single repository of plugins within a -registry. A plugin repository has the same content and actions as a repository. - - `registry` - represents the entire registry. Used for administrative actions -or lookup operations that span an entire registry. - -### Resource Name - -The resource name represent the name which identifies a resource for a resource -provider. A resource is identified by this name and the provided resource type. -An example of a resource name would be the name component of an image tag, such -as "samalba/myapp" or "hostname/samalba/myapp". - -### Resource Actions - -The resource actions define the actions which the access token allows to be -performed on the identified resource. These actions are type specific but will -normally have actions identifying read and write access on the resource. Example -for the `repository` type are `pull` for read access and `push` for write -access. - -## Authorization Server Use - -Each access token request may include a scope and an audience. The subject is -always derived from the passed in credentials or refresh token. When using -a refresh token the passed in audience must match the audience defined for -the refresh token. The audience (resource provider) is provided using the -`service` field. Multiple resource scopes may be provided using multiple `scope` -fields on the `GET` request. The `POST` request only takes in a single -`scope` field but may use a space to separate a list of multiple resource -scopes. - -### Resource Scope Grammar - -``` -scope := resourcescope [ ' ' resourcescope ]* -resourcescope := resourcetype ":" resourcename ":" action [ ',' action ]* -resourcetype := resourcetypevalue [ '(' resourcetypevalue ')' ] -resourcetypevalue := /[a-z0-9]+/ -resourcename := [ hostname '/' ] component [ '/' component ]* -hostname := hostcomponent ['.' hostcomponent]* [':' port-number] -hostcomponent := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/ -port-number := /[0-9]+/ -action := /[a-z]*/ -component := alpha-numeric [ separator alpha-numeric ]* -alpha-numeric := /[a-z0-9]+/ -separator := /[_.]|__|[-]*/ -``` -Full reference grammar is defined -[here](https://godoc.org/github.com/docker/distribution/reference). Currently -the scope name grammar is a subset of the reference grammar. - -> **NOTE:** that the `resourcename` may contain one `:` due to a possible port -> number in the hostname component of the `resourcename`, so a naive -> implementation that interprets the first three `:`-delimited tokens of a -> `scope` to be the `resourcetype`, `resourcename`, and a list of `action` -> would be insufficient. - -## Resource Provider Use - -Once a resource provider has verified the authenticity of the scope through -JWT access token verification, the resource provider must ensure that scope -satisfies the request. The resource provider should match the given audience -according to name or URI the resource provider uses to identify itself. Any -denial based on subject is not defined here and is up to resource provider, the -subject is mainly provided for audit logs and any other user-specific rules -which may need to be provided but are not defined by the authorization server. - -The resource provider must ensure that ANY resource being accessed as the -result of a request has the appropriate access scope. Both the resource type -and resource name must match the accessed resource and an appropriate action -scope must be included. - -When appropriate authorization is not provided either due to lack of scope -or missing token, the resource provider to return a `WWW-AUTHENTICATE` HTTP -header with the `realm` as the authorization server, the `service` as the -expected audience identifying string, and a `scope` field for each required -resource scope to complete the request. - -## JWT Access Tokens - -Each JWT access token may only have a single subject and audience but multiple -resource scopes. The subject and audience are put into standard JWT fields -`sub` and `aud`. The resource scope is put into the `access` field. The -structure of the access field can be seen in the -[jwt documentation](jwt.md). - -## Refresh Tokens - -A refresh token must be defined for a single subject and audience. Further -restricting scope to specific type, name, and actions combinations should be -done by fetching an access token using the refresh token. Since the refresh -token is not scoped to specific resources for an audience, extra care should -be taken to only use the refresh token to negotiate new access tokens directly -with the authorization server, and never with a resource provider. diff --git a/_vendor/github.com/distribution/distribution/docs/spec/auth/token.md b/_vendor/github.com/distribution/distribution/docs/spec/auth/token.md deleted file mode 100644 index 97f1971ddde..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/auth/token.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -title: "Token Authentication Specification" -description: "Specifies the Docker Registry v2 authentication" -keywords: registry, on-prem, images, tags, repository, distribution, Bearer authentication, advanced ---- - -# Docker Registry v2 authentication via central service - -This document outlines the v2 Docker registry authentication scheme: - -![v2 registry auth](../images/v2-registry-auth.png) - -1. Attempt to begin a push/pull operation with the registry. -2. If the registry requires authorization it will return a `401 Unauthorized` - HTTP response with information on how to authenticate. -3. The registry client makes a request to the authorization service for a - Bearer token. -4. The authorization service returns an opaque Bearer token representing the - client's authorized access. -5. The client retries the original request with the Bearer token embedded in - the request's Authorization header. -6. The Registry authorizes the client by validating the Bearer token and the - claim set embedded within it and begins the push/pull session as usual. - -## Requirements - -- Registry clients which can understand and respond to token auth challenges - returned by the resource server. -- An authorization server capable of managing access controls to their - resources hosted by any given service (such as repositories in a Docker - Registry). -- A Docker Registry capable of trusting the authorization server to sign tokens - which clients can use for authorization and the ability to verify these - tokens for single use or for use during a sufficiently short period of time. - -## Authorization Server Endpoint Descriptions - -The described server is meant to serve as a standalone access control manager -for resources hosted by other services which wish to authenticate and manage -authorizations using a separate access control manager. - -A service like this is used by the official Docker Registry to authenticate -clients and verify their authorization to Docker image repositories. - -As of Docker 1.6, the registry client within the Docker Engine has been updated -to handle such an authorization workflow. - -## How to authenticate - -Registry V1 clients first contact the index to initiate a push or pull. Under -the Registry V2 workflow, clients should contact the registry first. If the -registry server requires authentication it will return a `401 Unauthorized` -response with a `WWW-Authenticate` header detailing how to authenticate to this -registry. - -For example, say I (username `jlhawn`) am attempting to push an image to the -repository `samalba/my-app`. For the registry to authorize this, I will need -`push` access to the `samalba/my-app` repository. The registry will first -return this response: - -``` -HTTP/1.1 401 Unauthorized -Content-Type: application/json; charset=utf-8 -Docker-Distribution-Api-Version: registry/2.0 -Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:samalba/my-app:pull,push" -Date: Thu, 10 Sep 2015 19:32:31 GMT -Content-Length: 235 -Strict-Transport-Security: max-age=31536000 - -{"errors":[{"code":"UNAUTHORIZED","message":"access to the requested resource is not authorized","detail":[{"Type":"repository","Name":"samalba/my-app","Action":"pull"},{"Type":"repository","Name":"samalba/my-app","Action":"push"}]}]} -``` - -Note the HTTP Response Header indicating the auth challenge: - -``` -Www-Authenticate: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:samalba/my-app:pull,push" -``` - -This format is documented in [Section 3 of RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-3) - -This challenge indicates that the registry requires a token issued by the -specified token server and that the request the client is attempting will -need to include sufficient access entries in its claim set. To respond to this -challenge, the client will need to make a `GET` request to the URL -`https://auth.docker.io/token` using the `service` and `scope` values from the -`WWW-Authenticate` header. - -## Requesting a Token - -Defines getting a bearer and refresh token using the token endpoint. - -#### Query Parameters - -
-
- service -
-
- The name of the service which hosts the resource. -
-
- offline_token -
-
- Whether to return a refresh token along with the bearer token. A refresh - token is capable of getting additional bearer tokens for the same - subject with different scopes. The refresh token does not have an - expiration and should be considered completely opaque to the client. -
-
- client_id -
-
- String identifying the client. This client_id does not need - to be registered with the authorization server but should be set to a - meaningful value in order to allow auditing keys created by unregistered - clients. Accepted syntax is defined in - [RFC6749 Appendix A.1](https://tools.ietf.org/html/rfc6749#appendix-A.1). -
-
- scope -
-
- The resource in question, formatted as one of the space-delimited - entries from the scope parameters from the WWW-Authenticate header - shown above. This query parameter should be specified multiple times if - there is more than one scope entry from the WWW-Authenticate - header. The above example would be specified as: - scope=repository:samalba/my-app:push. The scope field may - be empty to request a refresh token without providing any resource - permissions to the returned bearer token. -
-
- - -#### Token Response Fields - -
-
- token -
-
- An opaque Bearer token that clients should supply to subsequent - requests in the Authorization header. -
-
- access_token -
-
- For compatibility with OAuth 2.0, we will also accept token under the name - access_token. At least one of these fields must be specified, but - both may also appear (for compatibility with older clients). When both are specified, - they should be equivalent; if they differ the client's choice is undefined. -
-
- expires_in -
-
- (Optional) The duration in seconds since the token was issued that it - will remain valid. When omitted, this defaults to 60 seconds. For - compatibility with older clients, a token should never be returned with - less than 60 seconds to live. -
-
- issued_at -
-
- (Optional) The RFC3339-serialized UTC - standard time at which a given token was issued. If issued_at is omitted, the - expiration is from when the token exchange completed. -
-
- refresh_token -
-
- (Optional) Token which can be used to get additional access tokens for - the same subject with different scopes. This token should be kept secure - by the client and only sent to the authorization server which issues - bearer tokens. This field will only be set when `offline_token=true` is - provided in the request. -
-
- -#### Example - -For this example, the client makes an HTTP GET request to the following URL: - -``` -https://auth.docker.io/token?service=registry.docker.io&scope=repository:samalba/my-app:pull,push -``` - -The token server should first attempt to authenticate the client using any -authentication credentials provided with the request. From Docker 1.11 the -Docker engine supports both Basic Authentication and [OAuth2](oauth.md) for -getting tokens. Docker 1.10 and before, the registry client in the Docker Engine -only supports Basic Authentication. If an attempt to authenticate to the token -server fails, the token server should return a `401 Unauthorized` response -indicating that the provided credentials are invalid. - -Whether the token server requires authentication is up to the policy of that -access control provider. Some requests may require authentication to determine -access (such as pushing or pulling a private repository) while others may not -(such as pulling from a public repository). - -After authenticating the client (which may simply be an anonymous client if -no attempt was made to authenticate), the token server must next query its -access control list to determine whether the client has the requested scope. In -this example request, if I have authenticated as user `jlhawn`, the token -server will determine what access I have to the repository `samalba/my-app` -hosted by the entity `registry.docker.io`. - -Once the token server has determined what access the client has to the -resources requested in the `scope` parameter, it will take the intersection of -the set of requested actions on each resource and the set of actions that the -client has in fact been granted. If the client only has a subset of the -requested access **it must not be considered an error** as it is not the -responsibility of the token server to indicate authorization errors as part of -this workflow. - -Continuing with the example request, the token server will find that the -client's set of granted access to the repository is `[pull, push]` which when -intersected with the requested access `[pull, push]` yields an equal set. If -the granted access set was found only to be `[pull]` then the intersected set -would only be `[pull]`. If the client has no access to the repository then the -intersected set would be empty, `[]`. - -It is this intersected set of access which is placed in the returned token. - -The server then constructs an implementation-specific token with this -intersected set of access, and returns it to the Docker client to use to -authenticate to the audience service (within the indicated window of time): - -``` -HTTP/1.1 200 OK -Content-Type: application/json - -{"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IlBZWU86VEVXVTpWN0pIOjI2SlY6QVFUWjpMSkMzOlNYVko6WEdIQTozNEYyOjJMQVE6WlJNSzpaN1E2In0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJqbGhhd24iLCJhdWQiOiJyZWdpc3RyeS5kb2NrZXIuY29tIiwiZXhwIjoxNDE1Mzg3MzE1LCJuYmYiOjE0MTUzODcwMTUsImlhdCI6MTQxNTM4NzAxNSwianRpIjoidFlKQ08xYzZjbnl5N2tBbjBjN3JLUGdiVjFIMWJGd3MiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InNhbWFsYmEvbXktYXBwIiwiYWN0aW9ucyI6WyJwdXNoIl19XX0.QhflHPfbd6eVF4lM9bwYpFZIV0PfikbyXuLx959ykRTBpe3CYnzs6YBK8FToVb5R47920PVLrh8zuLzdCr9t3w", "expires_in": 3600,"issued_at": "2009-11-10T23:00:00Z"} -``` - - -## Using the Bearer token - -Once the client has a token, it will try the registry request again with the -token placed in the HTTP `Authorization` header like so: - -``` -Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IkJWM0Q6MkFWWjpVQjVaOktJQVA6SU5QTDo1RU42Ok40SjQ6Nk1XTzpEUktFOkJWUUs6M0ZKTDpQT1RMIn0.eyJpc3MiOiJhdXRoLmRvY2tlci5jb20iLCJzdWIiOiJCQ0NZOk9VNlo6UUVKNTpXTjJDOjJBVkM6WTdZRDpBM0xZOjQ1VVc6NE9HRDpLQUxMOkNOSjU6NUlVTCIsImF1ZCI6InJlZ2lzdHJ5LmRvY2tlci5jb20iLCJleHAiOjE0MTUzODczMTUsIm5iZiI6MTQxNTM4NzAxNSwiaWF0IjoxNDE1Mzg3MDE1LCJqdGkiOiJ0WUpDTzFjNmNueXk3a0FuMGM3cktQZ2JWMUgxYkZ3cyIsInNjb3BlIjoiamxoYXduOnJlcG9zaXRvcnk6c2FtYWxiYS9teS1hcHA6cHVzaCxwdWxsIGpsaGF3bjpuYW1lc3BhY2U6c2FtYWxiYTpwdWxsIn0.Y3zZSwaZPqy4y9oRBVRImZyv3m_S9XDHF1tWwN7mL52C_IiA73SJkWVNsvNqpJIn5h7A2F8biv_S2ppQ1lgkbw -``` - -This is also described in [Section 2.1 of RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-2.1) diff --git a/_vendor/github.com/distribution/distribution/docs/spec/deprecated-schema-v1.md b/_vendor/github.com/distribution/distribution/docs/spec/deprecated-schema-v1.md deleted file mode 100644 index 66ff5c215ee..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/deprecated-schema-v1.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Update deprecated schema image manifest version 2, v1 images -description: Update deprecated schema v1 iamges -keywords: registry, on-prem, images, tags, repository, distribution, api, advanced, manifest ---- - -## Image manifest version 2, schema 1 -With the release of image manifest version 2, schema 2, image manifest version -2, schema 1 has been deprecated. This could lead to compatibility and -vulnerability issues in images that haven't been updated to image manifest -version 2, schema 2. - -This page contains information on how to update from image manifest version 2, -schema 1. However, these instructions will not ensure your new image will run -successfully. There may be several other issues to troubleshoot that are -associated with the deprecated image manifest that will block your image from -running succesfully. A list of possible methods to help update your image is -also included below. - -### Update to image manifest version 2, schema 2 - -One way to upgrade an image from image manifest version 2, schema 1 to -schema 2 is to `docker pull` the image and then `docker push` the image with a -current version of Docker. Doing so will automatically convert the image to use -the latest image manifest specification. - -Converting an image to image manifest version 2, schema 2 converts the -manifest format, but does not update the contents within the image. Images -using manifest version 2, schema 1 may contain unpatched vulnerabilities. We -recommend looking for an alternative image or rebuilding it. - - -### Update FROM statement - -You can rebuild the image by updating the `FROM` statement in your -`Dockerfile`. If your image manifest is out-of-date, there is a chance the -image pulled from your `FROM` statement in your `Dockerfile` is also -out-of-date. See the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/#from) -and the [Dockerfile best practices guide](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) -for more information on how to update the `FROM` statement in your -`Dockerfile`. diff --git a/_vendor/github.com/distribution/distribution/docs/spec/images/v2-registry-auth.png b/_vendor/github.com/distribution/distribution/docs/spec/images/v2-registry-auth.png deleted file mode 100644 index 3b05d04b5bd..00000000000 Binary files a/_vendor/github.com/distribution/distribution/docs/spec/images/v2-registry-auth.png and /dev/null differ diff --git a/_vendor/github.com/distribution/distribution/docs/spec/implementations.md b/_vendor/github.com/distribution/distribution/docs/spec/implementations.md deleted file mode 100644 index 3474653502f..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/implementations.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -published: false ---- - -# Distribution API Implementations - -This is a list of known implementations of the Distribution API spec. - -## [Docker Distribution Registry](https://github.com/docker/distribution) - -Docker distribution is the reference implementation of the distribution API -specification. It aims to fully implement the entire specification. - -### Releases -#### 2.0.1 (_in development_) -Implements API 2.0.1 - -_Known Issues_ - - No resumable push support - - Content ranges ignored - - Blob upload status will always return a starting range of 0 - -#### 2.0.0 -Implements API 2.0.0 - -_Known Issues_ - - No resumable push support - - No PATCH implementation for blob upload - - Content ranges ignored - diff --git a/_vendor/github.com/distribution/distribution/docs/spec/index.md b/_vendor/github.com/distribution/distribution/docs/spec/index.md deleted file mode 100644 index 46fddb12eae..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Reference Overview" -description: "Explains registry JSON objects" -keywords: registry, service, images, repository, json ---- - -# Docker Registry Reference - -* [HTTP API V2](api.md) -* [Storage Driver](https://docs.docker.com/registry/storage-drivers/) -* [Token Authentication Specification](auth/token.md) -* [Token Authentication Implementation](auth/jwt.md) diff --git a/_vendor/github.com/distribution/distribution/docs/spec/json.md b/_vendor/github.com/distribution/distribution/docs/spec/json.md deleted file mode 100644 index 825b17ac26d..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/json.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -published: false -title: "Docker Distribution JSON Canonicalization" -description: "Explains registry JSON objects" -keywords: ["registry, service, images, repository, json"] ---- - - - -# Docker Distribution JSON Canonicalization - -To provide consistent content hashing of JSON objects throughout Docker -Distribution APIs, the specification defines a canonical JSON format. Adopting -such a canonicalization also aids in caching JSON responses. - -Note that protocols should not be designed to depend on identical JSON being -generated across different versions or clients. The canonicalization rules are -merely useful for caching and consistency. - -## Rules - -Compliant JSON should conform to the following rules: - -1. All generated JSON should comply with [RFC - 7159](http://www.ietf.org/rfc/rfc7159.txt). -2. Resulting "JSON text" shall always be encoded in UTF-8. -3. Unless a canonical key order is defined for a particular schema, object - keys shall always appear in lexically sorted order. -4. All whitespace between tokens should be removed. -5. No "trailing commas" are allowed in object or array definitions. -6. The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e". - Ampersand "&" is escaped to "\u0026". - -## Examples - -The following is a simple example of a canonicalized JSON string: - -```json -{"asdf":1,"qwer":[],"zxcv":[{},true,1000000000,"tyui"]} -``` - -## Reference - -### Other Canonicalizations - -The OLPC project specifies [Canonical -JSON](http://wiki.laptop.org/go/Canonical_JSON). While this is used in -[TUF](http://theupdateframework.com/), which may be used with other -distribution-related protocols, this alternative format has been proposed in -case the original source changes. Specifications complying with either this -specification or an alternative should explicitly call out the -canonicalization format. Except for key ordering, this specification is mostly -compatible. - -### Go - -In Go, the [`encoding/json`](http://golang.org/pkg/encoding/json/) library -will emit canonical JSON by default. Simply using `json.Marshal` will suffice -in most cases: - -```go -incoming := map[string]interface{}{ - "asdf": 1, - "qwer": []interface{}{}, - "zxcv": []interface{}{ - map[string]interface{}{}, - true, - int(1e9), - "tyui", - }, -} - -canonical, err := json.Marshal(incoming) -if err != nil { - // ... handle error -} -``` - -To apply canonical JSON format spacing to an existing serialized JSON buffer, one -can use -[`json.Indent`](http://golang.org/src/encoding/json/indent.go?s=1918:1989#L65) -with the following arguments: - -```go -incoming := getBytes() -var canonical bytes.Buffer -if err := json.Indent(&canonical, incoming, "", ""); err != nil { - // ... handle error -} -``` diff --git a/_vendor/github.com/distribution/distribution/docs/spec/manifest-v2-1.md b/_vendor/github.com/distribution/distribution/docs/spec/manifest-v2-1.md deleted file mode 100644 index 335509b00e9..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/manifest-v2-1.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: "Image Manifest V 2, Schema 1 " -description: "image manifest for the Registry." -keywords: registry, on-prem, images, tags, repository, distribution, api, advanced, manifest ---- - -# Image Manifest Version 2, Schema 1 - -This document outlines the format of the V2 image manifest. The image -manifest described herein was introduced in the Docker daemon in the [v1.3.0 -release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453). -It is a provisional manifest to provide a compatibility with the [V1 Image -format](https://github.com/docker/docker/blob/master/image/spec/v1.md), as the -requirements are defined for the [V2 Schema 2 -image](https://github.com/docker/distribution/pull/62). - - -Image manifests describe the various constituents of a docker image. Image -manifests can be serialized to JSON format with the following media types: - -Manifest Type | Media Type -------------- | ------------- -manifest | "application/vnd.docker.distribution.manifest.v1+json" -signed manifest | "application/vnd.docker.distribution.manifest.v1+prettyjws" - -*Note that "application/json" will also be accepted for schema 1.* - -References: - - - [Proposal: JSON Registry API V2.1](https://github.com/docker/docker/issues/9015) - - [Proposal: Provenance step 1 - Transform images for validation and verification](https://github.com/docker/docker/issues/8093) - -## *Manifest* Field Descriptions - -Manifest provides the base accessible fields for working with V2 image format - in the registry. - -- **`name`** *string* - - name is the name of the image's repository - -- **`tag`** *string* - - tag is the tag of the image - -- **`architecture`** *string* - - architecture is the host architecture on which this image is intended to - run. This is for information purposes and not currently used by the engine - -- **`fsLayers`** *array* - - fsLayers is a list of filesystem layer blob sums contained in this image. - - An fsLayer is a struct consisting of the following fields - - **`blobSum`** *digest.Digest* - - blobSum is the digest of the referenced filesystem image layer. A - digest must be a sha256 hash. - - -- **`history`** *array* - - history is a list of unstructured historical data for v1 compatibility. It - contains ID of the image layer and ID of the layer's parent layers. - - history is a struct consisting of the following fields - - **`v1Compatibility`** string - - V1Compatibility is the raw V1 compatibility information. This will - contain the JSON object describing the V1 of this image. - -- **`schemaVersion`** *int* - - SchemaVersion is the image manifest schema that this image follows. - ->**Note**:the length of `history` must be equal to the length of `fsLayers` and ->entries in each are correlated by index. - -## Signed Manifests - -Signed manifests provides an envelope for a signed image manifest. A signed -manifest consists of an image manifest along with an additional field -containing the signature of the manifest. - -The docker client can verify signed manifests and displays a message to the user. - -### Signing Manifests - -Image manifests can be signed in two different ways: with a *libtrust* private - key or an x509 certificate chain. When signing with an x509 certificate chain, - the public key of the first element in the chain must be the public key - corresponding with the sign key. - -### Signed Manifest Field Description - -Signed manifests include an image manifest and a list of signatures generated -by *libtrust*. A signature consists of the following fields: - - -- **`header`** *[JOSE](http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2)* - - A [JSON Web Signature](http://self-issued.info/docs/draft-ietf-jose-json-web-signature.html) - -- **`signature`** *string* - - A signature for the image manifest, signed by a *libtrust* private key - -- **`protected`** *string* - - The signed protected header - -## Example Manifest - -*Example showing the official 'hello-world' image manifest.* - -``` -{ - "name": "hello-world", - "tag": "latest", - "architecture": "amd64", - "fsLayers": [ - { - "blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" - }, - { - "blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" - }, - { - "blobSum": "sha256:cc8567d70002e957612902a8e985ea129d831ebe04057d88fb644857caa45d11" - }, - { - "blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" - } - ], - "history": [ - { - "v1Compatibility": "{\"id\":\"e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\",\"parent\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"created\":\"2014-12-31T22:57:59.178729048Z\",\"container\":\"27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\",\"container_config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [/hello]\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"docker_version\":\"1.4.1\",\"config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/hello\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n" - }, - { - "v1Compatibility": "{\"id\":\"e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\",\"parent\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"created\":\"2014-12-31T22:57:59.178729048Z\",\"container\":\"27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\",\"container_config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [/hello]\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"docker_version\":\"1.4.1\",\"config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/hello\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n" - }, - ], - "schemaVersion": 1, - "signatures": [ - { - "header": { - "jwk": { - "crv": "P-256", - "kid": "OD6I:6DRK:JXEJ:KBM4:255X:NSAA:MUSF:E4VM:ZI6W:CUN2:L4Z6:LSF4", - "kty": "EC", - "x": "3gAwX48IQ5oaYQAYSxor6rYYc_6yjuLCjtQ9LUakg4A", - "y": "t72ge6kIA1XOjqjVoEOiPPAURltJFBMGDSQvEGVB010" - }, - "alg": "ES256" - }, - "signature": "XREm0L8WNn27Ga_iE_vRnTxVMhhYY0Zst_FfkKopg6gWSoTOZTuW4rK0fg_IqnKkEKlbD83tD46LKEGi5aIVFg", - "protected": "eyJmb3JtYXRMZW5ndGgiOjY2MjgsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wNC0wOFQxODo1Mjo1OVoifQ" - } - ] -} - -``` diff --git a/_vendor/github.com/distribution/distribution/docs/spec/manifest-v2-2.md b/_vendor/github.com/distribution/distribution/docs/spec/manifest-v2-2.md deleted file mode 100644 index 8ff2cadfef1..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/manifest-v2-2.md +++ /dev/null @@ -1,295 +0,0 @@ ---- -title: "Image Manifest V 2, Schema 2 " -description: "image manifest for the Registry." -keywords: registry, on-prem, images, tags, repository, distribution, api, advanced, manifest ---- - -# Image Manifest Version 2, Schema 2 - -This document outlines the format of the V2 image manifest, schema version 2. -The original (and provisional) image manifest for V2 (schema 1), was introduced -in the Docker daemon in the [v1.3.0 -release](https://github.com/docker/docker/commit/9f482a66ab37ec396ac61ed0c00d59122ac07453) -and is specified in the [schema 1 manifest definition](manifest-v2-1.md) - -This second schema version has two primary goals. The first is to allow -multi-architecture images, through a "fat manifest" which references image -manifests for platform-specific versions of an image. The second is to -move the Docker engine towards content-addressable images, by supporting -an image model where the image's configuration can be hashed to generate -an ID for the image. - -# Media Types - -The following media types are used by the manifest formats described here, and -the resources they reference: - -- `application/vnd.docker.distribution.manifest.v1+json`: schema1 (existing manifest format) -- `application/vnd.docker.distribution.manifest.v2+json`: New image manifest format (schemaVersion = 2) -- `application/vnd.docker.distribution.manifest.list.v2+json`: Manifest list, aka "fat manifest" -- `application/vnd.docker.container.image.v1+json`: Container config JSON -- `application/vnd.docker.image.rootfs.diff.tar.gzip`: "Layer", as a gzipped tar -- `application/vnd.docker.image.rootfs.foreign.diff.tar.gzip`: "Layer", as a gzipped tar that should never be pushed -- `application/vnd.docker.plugin.v1+json`: Plugin config JSON - -## Manifest List - -The manifest list is the "fat manifest" which points to specific image manifests -for one or more platforms. Its use is optional, and relatively few images will -use one of these manifests. A client will distinguish a manifest list from an -image manifest based on the Content-Type returned in the HTTP response. - -## *Manifest List* Field Descriptions - -- **`schemaVersion`** *int* - - This field specifies the image manifest schema version as an integer. This - schema uses the version `2`. - -- **`mediaType`** *string* - - The MIME type of the manifest list. This should be set to - `application/vnd.docker.distribution.manifest.list.v2+json`. - -- **`manifests`** *array* - - The manifests field contains a list of manifests for specific platforms. - - Fields of an object in the manifests list are: - - - **`mediaType`** *string* - - The MIME type of the referenced object. This will generally be - `application/vnd.docker.distribution.manifest.v2+json`, but it could also - be `application/vnd.docker.distribution.manifest.v1+json` if the manifest - list references a legacy schema-1 manifest. - - - **`size`** *int* - - The size in bytes of the object. This field exists so that a client - will have an expected size for the content before validating. If the - length of the retrieved content does not match the specified length, - the content should not be trusted. - - - **`digest`** *string* - - The digest of the content, as defined by the - [Registry V2 HTTP API Specificiation](api.md#digest-parameter). - - - **`platform`** *object* - - The platform object describes the platform which the image in the - manifest runs on. A full list of valid operating system and architecture - values are listed in the [Go language documentation for `$GOOS` and - `$GOARCH`](https://golang.org/doc/install/source#environment) - - - **`architecture`** *string* - - The architecture field specifies the CPU architecture, for example - `amd64` or `ppc64le`. - - - **`os`** *string* - - The os field specifies the operating system, for example - `linux` or `windows`. - - - **`os.version`** *string* - - The optional os.version field specifies the operating system version, - for example `10.0.10586`. - - - **`os.features`** *array* - - The optional os.features field specifies an array of strings, - each listing a required OS feature (for example on Windows - `win32k`). - - - **`variant`** *string* - - The optional variant field specifies a variant of the CPU, for - example `armv6l` to specify a particular CPU variant of the ARM CPU. - - - **`features`** *array* - - The optional features field specifies an array of strings, each - listing a required CPU feature (for example `sse4` or `aes`). - -## Example Manifest List - -*Example showing a simple manifest list pointing to image manifests for two platforms:* -```json -{ - "schemaVersion": 2, - "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", - "manifests": [ - { - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 7143, - "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f", - "platform": { - "architecture": "ppc64le", - "os": "linux", - } - }, - { - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 7682, - "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270", - "platform": { - "architecture": "amd64", - "os": "linux", - "features": [ - "sse4" - ] - } - } - ] -} -``` - -# Image Manifest - -The image manifest provides a configuration and a set of layers for a container -image. It's the direct replacement for the schema-1 manifest. - -## *Image Manifest* Field Descriptions - -- **`schemaVersion`** *int* - - This field specifies the image manifest schema version as an integer. This - schema uses version `2`. - -- **`mediaType`** *string* - - The MIME type of the manifest. This should be set to - `application/vnd.docker.distribution.manifest.v2+json`. - -- **`config`** *object* - - The config field references a configuration object for a container, by - digest. This configuration item is a JSON blob that the runtime uses - to set up the container. This new schema uses a tweaked version - of this configuration to allow image content-addressability on the - daemon side. - - Fields of a config object are: - - - **`mediaType`** *string* - - The MIME type of the referenced object. This should generally be - `application/vnd.docker.container.image.v1+json`. - - - **`size`** *int* - - The size in bytes of the object. This field exists so that a client - will have an expected size for the content before validating. If the - length of the retrieved content does not match the specified length, - the content should not be trusted. - - - **`digest`** *string* - - The digest of the content, as defined by the - [Registry V2 HTTP API Specificiation](api.md#digest-parameter). - -- **`layers`** *array* - - The layer list is ordered starting from the base image (opposite order of schema1). - - Fields of an item in the layers list are: - - - **`mediaType`** *string* - - The MIME type of the referenced object. This should - generally be `application/vnd.docker.image.rootfs.diff.tar.gzip`. - Layers of type - `application/vnd.docker.image.rootfs.foreign.diff.tar.gzip` may be - pulled from a remote location but they should never be pushed. - - - **`size`** *int* - - The size in bytes of the object. This field exists so that a client - will have an expected size for the content before validating. If the - length of the retrieved content does not match the specified length, - the content should not be trusted. - - - **`digest`** *string* - - The digest of the content, as defined by the - [Registry V2 HTTP API Specificiation](api.md#digest-parameter). - - - **`urls`** *array* - - Provides a list of URLs from which the content may be fetched. Content - must be verified against the `digest` and `size`. This field is - optional and uncommon. - -## Example Image Manifest - -*Example showing an image manifest:* -```json -{ - "schemaVersion": 2, - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "config": { - "mediaType": "application/vnd.docker.container.image.v1+json", - "size": 7023, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" - }, - "layers": [ - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 32654, - "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 16724, - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" - }, - { - "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", - "size": 73109, - "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" - } - ] -} -``` - -# Backward compatibility - -The registry will continue to accept uploads of manifests in both the old and -new formats. - -When pushing images, clients which support the new manifest format should first -construct a manifest in the new format. If uploading this manifest fails, -presumably because the registry only supports the old format, the client may -fall back to uploading a manifest in the old format. - -When pulling images, clients indicate support for this new version of the -manifest format by sending the -`application/vnd.docker.distribution.manifest.v2+json` and -`application/vnd.docker.distribution.manifest.list.v2+json` media types in an -`Accept` header when making a request to the `manifests` endpoint. Updated -clients should check the `Content-Type` header to see whether the manifest -returned from the endpoint is in the old format, or is an image manifest or -manifest list in the new format. - -If the manifest being requested uses the new format, and the appropriate media -type is not present in an `Accept` header, the registry will assume that the -client cannot handle the manifest as-is, and rewrite it on the fly into the old -format. If the object that would otherwise be returned is a manifest list, the -registry will look up the appropriate manifest for the amd64 platform and -linux OS, rewrite that manifest into the old format if necessary, and return -the result to the client. If no suitable manifest is found in the manifest -list, the registry will return a 404 error. - -One of the challenges in rewriting manifests to the old format is that the old -format involves an image configuration for each layer in the manifest, but the -new format only provides one image configuration. To work around this, the -registry will create synthetic image configurations for all layers except the -top layer. These image configurations will not result in runnable images on -their own, but only serve to fill in the parent chain in a compatible way. -The IDs in these synthetic configurations will be derived from hashes of their -respective blobs. The registry will create these configurations and their IDs -using the same scheme as Docker 1.10 when it creates a legacy manifest to push -to a registry which doesn't support the new format. diff --git a/_vendor/github.com/distribution/distribution/docs/spec/menu.md b/_vendor/github.com/distribution/distribution/docs/spec/menu.md deleted file mode 100644 index 7e52d8d7756..00000000000 --- a/_vendor/github.com/distribution/distribution/docs/spec/menu.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Reference" -description: "Explains registry JSON objects" -keywords: registry, service, images, repository, json -type: "menu" -identifier: "smn_registry_ref" ---- diff --git a/_vendor/modules.txt b/_vendor/modules.txt index 31de5ca8aed..081d51d7260 100644 --- a/_vendor/modules.txt +++ b/_vendor/modules.txt @@ -4,6 +4,5 @@ # github.com/docker/scout-cli v1.0.2 # github.com/docker/cli v24.0.6+incompatible # github.com/docker/compose-cli v1.0.35 -# github.com/distribution/distribution v2.8.4-0.20231004140828-d607c6ccb937+incompatible # github.com/compose-spec/compose-spec v0.0.0-20230927132538-f223c5150d5d # github.com/docker/compose/v2 v2.22.0 diff --git a/content/registry/recipes/mirror.md b/content/docker-hub/mirror.md similarity index 96% rename from content/registry/recipes/mirror.md rename to content/docker-hub/mirror.md index f2db37a821b..586cc037ea6 100644 --- a/content/registry/recipes/mirror.md +++ b/content/docker-hub/mirror.md @@ -5,10 +5,9 @@ keywords: registry, on-prem, images, tags, repository, distribution, mirror, Hub title: Registry as a pull through cache aliases: - /engine/admin/registry_mirror/ +- /registry/recipes/mirror/ --- -{{< include "registry.md" >}} - ## Use-case If you have multiple instances of Docker running in your environment, such as @@ -107,8 +106,7 @@ proxy: > **Warning** > > For the scheduler to clean up old entries, `delete` must be enabled in the -> registry configuration. See [Registry Configuration](../configuration.md) for -> more details. +> registry configuration. { .warning } ### Configure the Docker daemon @@ -139,4 +137,4 @@ Save the file and reload Docker for the change to take effect. > ``` > > It's telling you that the file doesn't exist yet in the local cache and is -> being pulled from upstream. \ No newline at end of file +> being pulled from upstream. diff --git a/content/docker-hub/service-accounts.md b/content/docker-hub/service-accounts.md index 63d7ce06463..ffc0cf6e487 100644 --- a/content/docker-hub/service-accounts.md +++ b/content/docker-hub/service-accounts.md @@ -56,5 +56,5 @@ official images and other public images, you don't have to grant any access perm Refer to the following topics for additional information: -- [Mirroring Docker Hub](../registry/recipes/mirror.md) -- [Docker pricing FAQs](https://www.docker.com/pricing/faq/) \ No newline at end of file +- [Mirroring Docker Hub](./mirror.md) +- [Docker pricing FAQs](https://www.docker.com/pricing/faq/) diff --git a/content/engine/faq.md b/content/engine/faq.md index 9ca1571b074..ea585b6a092 100644 --- a/content/engine/faq.md +++ b/content/engine/faq.md @@ -66,7 +66,7 @@ be re-used for all your future projects. And so on. Hub](https://hub.docker.com/) where thousands of people have uploaded useful images: anything from Redis, CouchDB, PostgreSQL to IRC bouncers to Rails app servers to Hadoop to base images for various Linux -distros. The [*registry*](../registry/index.md) also includes an official "standard +distros. The registry also includes an official "standard library" of useful containers maintained by the Docker team. The registry itself is open-source, so anyone can deploy their own registry to store and transfer private containers, for internal server deployments for example. @@ -226,4 +226,4 @@ You can find more answers on: - [Docker Support Forums](https://forums.docker.com) - [GitHub](https://github.com/moby/moby) - [Ask questions on Stackoverflow](https://stackoverflow.com/search?q=docker) -- [Join the conversation on Twitter](https://twitter.com/docker) \ No newline at end of file +- [Join the conversation on Twitter](https://twitter.com/docker) diff --git a/content/includes/registry.md b/content/includes/registry.md deleted file mode 100644 index d3473679422..00000000000 --- a/content/includes/registry.md +++ /dev/null @@ -1,7 +0,0 @@ -> **Important** -> -> This page contains information about hosting your own registry using the -> [open source Docker Registry](https://github.com/distribution/distribution). For information about Docker Hub, which offers a -> hosted registry with additional features such as teams, organizations, web -> hooks, automated builds, etc, see [Docker Hub](/docker-hub/). -{ .important } diff --git a/content/reference.md b/content/reference.md index 44783b87846..d8ed4c5e11a 100644 --- a/content/reference.md +++ b/content/reference.md @@ -53,11 +53,6 @@ grid_specs: description: Outlines the Docker Registry authentication schemes. icon: key link: /registry/spec/auth/ -- title: Registry storage drivers - description: Enables support for given cloud providers when storing images with - Registry. - icon: shelves - link: /registry/storage-drivers/ aliases: - /app/working-with-app/ - /engine/reference/commandline/app/ @@ -97,4 +92,4 @@ various APIs, CLIs, drivers and specifications, and file formats. ## Drivers and specifications -{{< grid grid_specs >}} \ No newline at end of file +{{< grid grid_specs >}} diff --git a/content/registry.md b/content/registry.md new file mode 100644 index 00000000000..96624db48de --- /dev/null +++ b/content/registry.md @@ -0,0 +1,69 @@ +--- +title: Registry +description: Registry documentation has moved +keywords: registry, distribution +aliases: + - /registry/compatibility/ + - /registry/deploying/ + - /registry/deprecated/ + - /registry/garbage-collection/ + - /registry/help/ + - /registry/insecure/ + - /registry/introduction/ + - /registry/notifications/ + - /registry/recipes/ + - /registry/recipes/apache/ + - /registry/recipes/nginx/ + - /registry/recipes/osx-setup-guide/ + - /registry/spec/ + - /registry/spec/api/ + - /registry/spec/auth/ + - /registry/spec/auth/jwt/ + - /registry/spec/auth/oauth/ + - /registry/spec/auth/scope/ + - /registry/spec/auth/token/ + - /registry/spec/deprecated-schema-v1/ + - /registry/spec/implementations/ + - /registry/spec/json/ + - /registry/spec/manifest-v2-1/ + - /registry/spec/manifest-v2-2/ + - /registry/spec/menu/ + - /registry/storage-drivers/ + - /registry/storage-drivers/azure/ + - /registry/storage-drivers/filesystem/ + - /registry/storage-drivers/gcs/ + - /registry/storage-drivers/inmemory/ + - /registry/storage-drivers/oss/ + - /registry/storage-drivers/s3/ + - /registry/storage-drivers/swift/ +--- + +Registry, the open source implementation for storing and distributing container +images and other content, has been donated to the CNCF. Registry now goes under +the name of Distribution, and the documentation has moved to +[distribution.github.io/distribution][docs]. + +For reference documentation on the API protocol that Distribution implements, +see [Registry HTTP API][api]. + +For documentation related to authentication, see: + +- [Token authentication specification][token] +- [OAuth 2.0 token authentication][oauth2] +- [JWT authentication][jwt] +- [Token scope and access][scope] + +For information about image manifests, see: + +- [Image Manifest Version 2, Schema 2][schema2] +- [Image Manifest Version 2, Schema 1][schema1] (deprecated) + +[spec]: https://github.com/opencontainers/distribution-spec +[docs]: https://distribution.github.io/distribution/ +[api]: https://distribution.github.io/distribution/spec/api/ +[oauth2]: https://distribution.github.io/distribution/spec/auth/oauth/ +[jwt]: https://distribution.github.io/distribution/spec/auth/jwt/ +[token]: https://distribution.github.io/distribution/spec/auth/token/ +[scope]: https://distribution.github.io/distribution/spec/auth/scope/ +[schema2]: https://distribution.github.io/distribution/spec/manifest-v2-2/ +[schema1]: https://distribution.github.io/distribution/spec/deprecated-schema-v1/ diff --git a/content/registry/_index.md b/content/registry/_index.md deleted file mode 100644 index 1902bb6f331..00000000000 --- a/content/registry/_index.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -description: High-level overview of the Registry -keywords: registry, on-prem, images, tags, repository, distribution -title: Docker Registry -aliases: -- /registry/overview/ ---- - -{{< include "registry.md" >}} - -## What it is - -The Registry is a stateless, highly scalable server side application that stores -and lets you distribute Docker images. The Registry is open-source, under the -permissive [Apache license](https://en.wikipedia.org/wiki/Apache_License). -You can find the source code on -[GitHub](https://github.com/distribution/distribution). - -## Why use it - -You should use the Registry if you want to: - - * Tightly control where your images are being stored - * Fully own your images distribution pipeline - * Integrate image storage and distribution tightly into your in-house development workflow - -## Alternatives - -If you're looking for a zero maintenance, ready-to-go solution, [Docker Hub](https://hub.docker.com), provides a free-to-use, hosted Registry, plus additional features (organization accounts, -Automated builds, and more). - -## Requirements - -The Registry is compatible with Docker engine version 1.6.0 or later. - -## Basic commands - -Start your registry: - -```console -$ docker run -d -p 5000:5000 --name registry registry:2 -``` - -Pull (or build) an image from the hub: - -```console -$ docker pull ubuntu -``` - -Tag the image so that it points to your registry: - -```console -$ docker image tag ubuntu localhost:5000/myfirstimage -``` - -Push it: - -```console -$ docker push localhost:5000/myfirstimage -``` - -Pull it back: - -```console -$ docker pull localhost:5000/myfirstimage -``` - -Now stop your registry and remove all data: - -```console -$ docker container stop registry && docker container rm -v registry - ``` - -## Next - -Read the [detailed introduction about the registry](introduction.md) or jump directly to [deployment instructions](deploying.md). \ No newline at end of file diff --git a/content/registry/compatibility.md b/content/registry/compatibility.md deleted file mode 100644 index aa99dca166f..00000000000 --- a/content/registry/compatibility.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -description: describes get by digest pitfall -keywords: registry, manifest, images, tags, repository, distribution, digest -title: Registry compatibility ---- - -{{< include "registry.md" >}} - -## Synopsis -If a manifest is pulled by digest from a registry 2.3 with Docker Engine 1.9 -and older, and the manifest was pushed with Docker Engine 1.10, a security check -causes the Engine to receive a manifest it cannot use and the pull fails. - -## Registry manifest support - -Historically, the registry has supported a [single manifest type](./spec/manifest-v2-1.md) -known as Schema 1. - -With the move toward multiple architecture images, the distribution project -introduced two new manifest types: Schema 2 manifests and manifest lists. Registry -2.3 supports all three manifest types and sometimes performs an on-the-fly -transformation of a manifest before serving the JSON in the response, to -preserve compatibility with older versions of Docker Engine. - -This conversion has some implications for pulling manifests by digest and this -document enumerates these implications. - - -## Content Addressable Storage (CAS) - -Manifests are stored and retrieved in the registry by keying off a digest -representing a hash of the contents. One of the advantages provided by CAS is -security: if the contents are changed, then the digest no longer matches. -This prevents any modification of the manifest by a MITM attack or an untrusted -third party. - -When a manifest is stored by the registry, this digest is returned in the HTTP -response headers and, if events are configured, delivered within the event. The -manifest can either be retrieved by the tag, or this digest. - -For registry versions 2.2.1 and below, the registry always stores and -serves Schema 1 manifests. Engine 1.10 first -attempts to send a Schema 2 manifest, falling back to sending a -Schema 1 type manifest when it detects that the registry does not -support the new version. - - -## Registry v2.3 - -### Manifest push with Docker 1.10 - -The Engine constructs a Schema 2 manifest which the -registry persists to disk. - -When the manifest is pulled by digest or tag with Docker Engine 1.10, a -_Schema 2_ manifest is returned. Docker Engine 1.10 -understands the new manifest format. - -When the manifest is pulled by tag with Docker Engine 1.9 and older, the -manifest is converted on-the-fly to Schema 1 and sent in the -response. The Docker Engine 1.9 is compatible with this older format. - -When the manifest is pulled by digest with Docker Engine 1.9 and older, the -same rewriting process does not happen in the registry. If it did, -the digest would no longer match the hash of the manifest and would violate the -constraints of CAS. - -For this reason if a manifest is pulled by digest from a registry 2.3 with Docker -Engine 1.9 and older, and the manifest was pushed with Docker Engine 1.10, a -security check causes the Engine to receive a manifest it cannot use and the -pull fails. - -### Manifest push with Docker 1.9 and older - -The Docker Engine constructs a Schema 1 manifest which the -registry persists to disk. - -When the manifest is pulled by digest or tag with any Docker version, a -Schema 1 manifest is returned. \ No newline at end of file diff --git a/content/registry/deploying.md b/content/registry/deploying.md deleted file mode 100644 index 6d7d5f7305a..00000000000 --- a/content/registry/deploying.md +++ /dev/null @@ -1,581 +0,0 @@ ---- -description: Explains how to deploy a registry -keywords: registry, on-prem, images, tags, repository, distribution, deployment -title: Deploy a registry server ---- - -{{< include "registry.md" >}} - -Before you can deploy a registry, you need to install Docker on the host. -A registry is an instance of the `registry` image, and runs within Docker. - -This topic provides basic information about deploying and configuring a -registry. For an exhaustive list of configuration options, see the -[configuration reference](configuration.md). - -If you have an air-gapped datacenter, see -[Considerations for air-gapped registries](#considerations-for-air-gapped-registries). - -## Run a local registry - -Use a command like the following to start the registry container: - -```console -$ docker run -d -p 5000:5000 --restart=always --name registry registry:2 -``` - -The registry is now ready to use. - -> **Warning** -> -> These first few examples show registry configurations that are -> only appropriate for testing. A production-ready registry must be protected by -> TLS and should ideally use an access-control mechanism. Keep reading and then -> continue to the [configuration guide](configuration.md) to deploy a -> production-ready registry. -{ .warning } - -## Copy an image from Docker Hub to your registry - -You can pull an image from Docker Hub and push it to your registry. The -following example pulls the `ubuntu:16.04` image from Docker Hub and re-tags it -as `my-ubuntu`, then pushes it to the local registry. Finally, the -`ubuntu:16.04` and `my-ubuntu` images are deleted locally and the -`my-ubuntu` image is pulled from the local registry. - -1. Pull the `ubuntu:16.04` image from Docker Hub. - - ```console - $ docker pull ubuntu:16.04 - ``` - -2. Tag the image as `localhost:5000/my-ubuntu`. This creates an additional tag - for the existing image. When the first part of the tag is a hostname and - port, Docker interprets this as the location of a registry, when pushing. - - ```console - $ docker tag ubuntu:16.04 localhost:5000/my-ubuntu - ``` - -3. Push the image to the local registry running at `localhost:5000`: - - ```console - $ docker push localhost:5000/my-ubuntu - ``` - -4. Remove the locally-cached `ubuntu:16.04` and `localhost:5000/my-ubuntu` - images, so that you can test pulling the image from your registry. This - does not remove the `localhost:5000/my-ubuntu` image from your registry. - - ```console - $ docker image remove ubuntu:16.04 - $ docker image remove localhost:5000/my-ubuntu - ``` - -5. Pull the `localhost:5000/my-ubuntu` image from your local registry. - - ```console - $ docker pull localhost:5000/my-ubuntu - ``` - -## Stop a local registry - -To stop the registry, use the same `docker container stop` command as with any other -container. - -```console -$ docker container stop registry -``` - -To remove the container, use `docker container rm`. - -```console -$ docker container stop registry && docker container rm -v registry -``` - -## Basic configuration - -To configure the container, you can pass additional or modified options to the -`docker run` command. - -The following sections provide basic guidelines for configuring your registry. -For more details, see the [registry configuration reference](configuration.md). - -### Start the registry automatically - -If you want to use the registry as part of your permanent infrastructure, you -should set it to restart automatically when Docker restarts or if it exits. -This example uses the `--restart always` flag to set a restart policy for the -registry. - -```console -$ docker run -d \ - -p 5000:5000 \ - --restart=always \ - --name registry \ - registry:2 -``` - -### Customize the published port - -If you are already using port 5000, or you want to run multiple local -registries to separate areas of concern, you can customize the registry's -port settings. This example runs the registry on port 5001 and also names it -`registry-test`. Remember, the first part of the `-p` value is the host port -and the second part is the port within the container. Within the container, the -registry listens on port `5000` by default. - -```console -$ docker run -d \ - -p 5001:5000 \ - --name registry-test \ - registry:2 -``` - -If you want to change the port the registry listens on within the container, you -can use the environment variable `REGISTRY_HTTP_ADDR` to change it. This command -causes the registry to listen on port 5001 within the container: - -```console -$ docker run -d \ - -e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \ - -p 5001:5001 \ - --name registry-test \ - registry:2 -``` - - -## Storage customization - -### Customize the storage location - -By default, your registry data is persisted as a [docker volume](../storage/volumes.md) -on the host filesystem. If you want to store your registry contents at a specific -location on your host filesystem, such as if you have an SSD or SAN mounted into -a particular directory, you might decide to use a bind mount instead. A bind mount -is more dependent on the filesystem layout of the Docker host, but more performant -in many situations. The following example bind-mounts the host directory -`/mnt/registry` into the registry container at `/var/lib/registry/`. - -```console -$ docker run -d \ - -p 5000:5000 \ - --restart=always \ - --name registry \ - -v /mnt/registry:/var/lib/registry \ - registry:2 -``` - -### Customize the storage back-end - -By default, the registry stores its data on the local filesystem, whether you -use a bind mount or a volume. You can store the registry data in an Amazon S3 -bucket, Google Cloud Platform, or on another storage back-end by using -[storage drivers](./storage-drivers/index.md). For more information, see -[storage configuration options](./configuration.md#storage). - -## Run an externally-accessible registry - -Running a registry only accessible on `localhost` has limited usefulness. In -order to make your registry accessible to external hosts, you must first secure -it using TLS. - -This example is extended in [Run the registry as a -service](#run-the-registry-as-a-service) below. - -### Get a certificate - -These examples assume the following: - -- Your registry URL is `https://myregistry.domain.com/`. -- Your DNS, routing, and firewall settings allow access to the registry's host - on port 443. -- You have already obtained a certificate from a certificate authority (CA). - -If you have been issued an intermediate certificate instead, see -[use an intermediate certificate](#use-an-intermediate-certificate). - -1. Create a `certs` directory. - - ```console - $ mkdir -p certs - ``` - - Copy the `.crt` and `.key` files from the CA into the `certs` directory. - The following steps assume that the files are named `domain.crt` and - `domain.key`. - -2. Stop the registry if it is currently running. - - ```console - $ docker container stop registry - ``` - -3. Restart the registry, directing it to use the TLS certificate. This command - bind-mounts the `certs/` directory into the container at `/certs/`, and sets - environment variables that tell the container where to find the `domain.crt` - and `domain.key` file. The registry runs on port 443, the default HTTPS port. - - ```console - $ docker run -d \ - --restart=always \ - --name registry \ - -v "$(pwd)"/certs:/certs \ - -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ - -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ - -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ - -p 443:443 \ - registry:2 - ``` - -4. Docker clients can now pull from and push to your registry using its - external address. The following commands demonstrate this: - - ```console - $ docker pull ubuntu:16.04 - $ docker tag ubuntu:16.04 myregistry.domain.com/my-ubuntu - $ docker push myregistry.domain.com/my-ubuntu - $ docker pull myregistry.domain.com/my-ubuntu - ``` - -#### Use an intermediate certificate - -A certificate issuer may supply you with an *intermediate* certificate. In this -case, you must concatenate your certificate with the intermediate certificate to -form a *certificate bundle*. You can do this using the `cat` command: - -```console -cat domain.crt intermediate-certificates.pem > certs/domain.crt -``` - -You can use the certificate bundle just as you use the `domain.crt` file in -the previous example. - -### Support for Let's Encrypt - -The registry supports using Let's Encrypt to automatically obtain a -browser-trusted certificate. For more information on Let's Encrypt, see -[https://letsencrypt.org/how-it-works/](https://letsencrypt.org/how-it-works/) -and the relevant section of the -[registry configuration](configuration.md#letsencrypt). - -### Use an insecure registry (testing only) - -It is possible to use a self-signed certificate, or to use our registry -insecurely. Unless you have set up verification for your self-signed -certificate, this is for testing only. See [run an insecure registry](insecure.md). - -## Run the registry as a service - -[Swarm services](../engine/swarm/services.md) provide several advantages over -standalone containers. They use a declarative model, which means that you define -the desired state and Docker works to keep your service in that state. Services -provide automatic load balancing scaling, and the ability to control the -distribution of your service, among other advantages. Services also allow you to -store sensitive data such as TLS certificates in -[secrets](../engine/swarm/secrets.md). - -The storage back-end you use determines whether you use a fully scaled service -or a service with either only a single node or a node constraint. - -- If you use a distributed storage driver, such as Amazon S3, you can use a - fully replicated service. Each worker can write to the storage back-end - without causing write conflicts. - -- If you use a local bind mount or volume, each worker node writes to its - own storage location, which means that each registry contains a different - data set. You can solve this problem by using a single-replica service and a - node constraint to ensure that only a single worker is writing to the bind - mount. - -The following example starts a registry as a single-replica service, which is -accessible on any swarm node on port 80. It assumes you are using the same -TLS certificates as in the previous examples. - -First, save the TLS certificate and key as secrets: - -```console -$ docker secret create domain.crt certs/domain.crt - -$ docker secret create domain.key certs/domain.key -``` - -Next, add a label to the node where you want to run the registry. -To get the node's name, use `docker node ls`. Substitute your node's name for -`node1` below. - -```console -$ docker node update --label-add registry=true node1 -``` - -Next, create the service, granting it access to the two secrets and constraining -it to only run on nodes with the label `registry=true`. Besides the constraint, -you are also specifying that only a single replica should run at a time. The -example bind-mounts `/mnt/registry` on the swarm node to `/var/lib/registry/` -within the container. Bind mounts rely on the pre-existing source directory, -so be sure `/mnt/registry` exists on `node1`. You might need to create it before -running the following `docker service create` command. - -By default, secrets are mounted into a service at `/run/secrets/`. - -```console -$ docker service create \ - --name registry \ - --secret domain.crt \ - --secret domain.key \ - --constraint 'node.labels.registry==true' \ - --mount type=bind,src=/mnt/registry,dst=/var/lib/registry \ - -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ - -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt \ - -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key \ - --publish published=443,target=443 \ - --replicas 1 \ - registry:2 -``` - -You can access the service on port 443 of any swarm node. Docker sends the -requests to the node which is running the service. - -## Load balancing considerations - -One may want to use a load balancer to distribute load, terminate TLS or -provide high availability. While a full load balancing setup is outside the -scope of this document, there are a few considerations that can make the process -smoother. - -The most important aspect is that a load balanced cluster of registries must -share the same resources. For the current version of the registry, this means -the following must be the same: - - - Storage Driver - - HTTP Secret - - Redis Cache (if configured) - -Differences in any of the above cause problems serving requests. -As an example, if you're using the filesystem driver, all registry instances -must have access to the same filesystem root, on -the same machine. For other drivers, such as S3 or Azure, they should be -accessing the same resource and share an identical configuration. -The _HTTP Secret_ coordinates uploads, so also must be the same across -instances. Configuring different redis instances works (at the time -of writing), but is not optimal if the instances are not shared, because -more requests are directed to the backend. - -### Important/Required HTTP-Headers - -Getting the headers correct is very important. For all responses to any -request under the "/v2/" url space, the `Docker-Distribution-API-Version` -header should be set to the value "registry/2.0", even for a 4xx response. -This header allows the docker engine to quickly resolve authentication realms -and fallback to version 1 registries, if necessary. Confirming this is setup -correctly can help avoid problems with fallback. - -In the same train of thought, you must make sure you are properly sending the -`X-Forwarded-Proto`, `X-Forwarded-For`, and `Host` headers to their "client-side" -values. Failure to do so usually makes the registry issue redirects to internal -hostnames or downgrading from https to http. - -A properly secured registry should return 401 when the "/v2/" endpoint is hit -without credentials. The response should include a `WWW-Authenticate` -challenge, providing guidance on how to authenticate, such as with basic auth -or a token service. If the load balancer has health checks, it is recommended -to configure it to consider a 401 response as healthy and any other as down. -This secures your registry by ensuring that configuration problems with -authentication don't accidentally expose an unprotected registry. If you're -using a less sophisticated load balancer, such as Amazon's Elastic Load -Balancer, that doesn't allow one to change the healthy response code, health -checks can be directed at "/", which always returns a `200 OK` response. - -## Restricting access - -Except for registries running on secure local networks, registries should always -implement access restrictions. - -### Native basic auth - -The simplest way to achieve access restriction is through basic authentication -(this is very similar to other web servers' basic authentication mechanism). -This example uses native basic authentication using `htpasswd` to store the -secrets. - -> **Warning** -> -> You cannot use authentication with authentication schemes that send -> credentials as clear text. You must -> [configure TLS first](deploying.md#run-an-externally-accessible-registry) for -> authentication to work. -{ .warning } - -1. Create a password file with one entry for the user `testuser`, with password - `testpassword`: - - ```console - $ mkdir auth - $ docker run \ - --entrypoint htpasswd \ - httpd:2 -Bbn testuser testpassword > auth/htpasswd - ``` - - On Windows, make sure the output file is correctly encoded: - - ```powershell - docker run --rm --entrypoint htpasswd httpd:2 -Bbn testuser testpassword | Set-Content -Encoding ASCII auth/htpasswd - ``` - -2. Stop the registry. - - ```console - $ docker container stop registry - ``` - -3. Start the registry with basic authentication. - - ```console - $ docker run -d \ - -p 5000:5000 \ - --restart=always \ - --name registry \ - -v "$(pwd)"/auth:/auth \ - -e "REGISTRY_AUTH=htpasswd" \ - -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ - -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ - -v "$(pwd)"/certs:/certs \ - -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ - -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ - registry:2 - ``` - -4. Try to pull an image from the registry, or push an image to the registry. - These commands fail. - -5. Sign in to the registry. - - ```console - $ docker login myregistrydomain.com:5000 - ``` - - Provide the username and password from the first step. - - Test that you can now pull an image from the registry or push an image to - the registry. - -> **X509 errors** -> -> X509 errors usually indicate that you are attempting to use a self-signed -> certificate without configuring the Docker daemon correctly. See [run an -> insecure registry](insecure.md). -{ .tip } - -### More advanced authentication - -You may want to leverage more advanced basic auth implementations by using a -proxy in front of the registry. See the [recipes list](recipes/index.md). - -The registry also supports delegated authentication which redirects users to a -specific trusted token server. This approach is more complicated to set up, and -only makes sense if you need to fully configure ACLs and need more control over -the registry's integration into your global authorization and authentication -systems. Refer to the following [background information](spec/auth/token.md) and -[configuration information here](configuration.md#auth). - -This approach requires you to implement your own authentication system or -leverage a third-party implementation. - -## Deploy your registry using a Compose file - -If your registry invocation is advanced, it may be easier to use a Compose file to deploy it, rather than relying on a specific `docker run` -invocation. Use the following example `docker-compose.yml` as a template. - -```yaml -registry: - restart: always - image: registry:2 - ports: - - 5000:5000 - environment: - REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt - REGISTRY_HTTP_TLS_KEY: /certs/domain.key - REGISTRY_AUTH: htpasswd - REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd - REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm - volumes: - - /path/data:/var/lib/registry - - /path/certs:/certs - - /path/auth:/auth -``` - -Replace `/path` with the directory which contains the `certs/` and `auth/` -directories. - -Start your registry by issuing the following command in the directory containing -the `docker-compose.yml` file: - -```console -$ docker compose up -d -``` - -## Considerations for air-gapped registries - -You can run a registry in an environment with no internet connectivity. -However, if you rely on any images which are not local, you need to consider the -following: - -- You may need to build your local registry's data volume on a connected - host where you can run `docker pull` to get any images which are available - remotely, and then migrate the registry's data volume to the air-gapped - network. - -- Certain images, such as the official Microsoft Windows base images, are not - distributable. This means that when you push an image based on one of these - images to your private registry, the non-distributable layers are **not** - pushed, but are always fetched from their authorized location. This is fine - for internet-connected hosts, but not in an air-gapped set-up. - - You can configure the Docker daemon to allow pushing non-distributable layers - to private registries. - **This is only useful in air-gapped set-ups in the presence of - non-distributable images, or in extremely bandwidth-limited situations.** - You are responsible for ensuring that you are in compliance with the terms of - use for non-distributable layers. - - 1. Edit the `daemon.json` file, which is located in `/etc/docker/` on Linux - hosts and `C:\ProgramData\docker\config\daemon.json` on Windows Server. - Assuming the file was previously empty, add the following contents: - - ```json - { - "allow-nondistributable-artifacts": ["myregistrydomain.com:5000"] - } - ``` - - The value is an array of registry addresses, separated by commas. - - Save and exit the file. - - 2. Restart Docker. - - 3. Restart the registry if it does not start automatically. - - 4. When you push images to the registries in the list, their - non-distributable layers are pushed to the registry. - - > **Warning** - > - > Non-distributable artifacts typically have restrictions on - > how and where they can be distributed and shared. Only use this feature - > to push artifacts to private registries and ensure that you are in - > compliance with any terms that cover redistributing non-distributable - > artifacts. - { .warning } - - -## Next steps - -More specific and advanced information is available in the following sections: - - - [Configuration reference](configuration.md) - - [Working with notifications](notifications.md) - - [Advanced "recipes"](recipes/index.md) - - [Registry API](spec/api.md) - - [Storage driver model](storage-drivers/index.md) - - [Token authentication](spec/auth/token.md) \ No newline at end of file diff --git a/content/registry/deprecated.md b/content/registry/deprecated.md deleted file mode 100644 index af69e5c317f..00000000000 --- a/content/registry/deprecated.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: describes deprecated functionality -keywords: registry, manifest, images, signatures, repository, distribution, digest -title: Docker Registry deprecation ---- - -{{< include "registry.md" >}} - -This document details functionality or components which are deprecated within -the registry. - -### v2.5.0 - -The signature store has been removed from the registry. Since `v2.4.0` it has -been possible to configure the registry to generate manifest signatures rather -than load them from storage. In this version of the registry this becomes -the default behavior. Signatures which are attached to manifests on put are -not stored in the registry. This does not alter the functional behavior of -the registry. - -Old signatures blobs can be removed from the registry storage by running the -garbage-collect subcommand. \ No newline at end of file diff --git a/content/registry/garbage-collection.md b/content/registry/garbage-collection.md deleted file mode 100644 index c2d39746159..00000000000 --- a/content/registry/garbage-collection.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -description: High level discussion of garbage collection -keywords: registry, garbage, images, tags, repository, distribution -title: Garbage collection ---- - -{{< include "registry.md" >}} - -As of v2.4.0 a garbage collector command is included within the registry binary. -This document describes what this command does and how and why it should be used. - -## About garbage collection - -In the context of the Docker registry, garbage collection is the process of -removing blobs from the filesystem when they are no longer referenced by a -manifest. Blobs can include both layers and manifests. - -Registry data can occupy considerable amounts of disk space. In addition, -garbage collection can be a security consideration, when it is desirable to ensure -that certain layers no longer exist on the filesystem. - -## Garbage collection in practice - -Filesystem layers are stored by their content address in the Registry. This -has many advantages, one of which is that data is stored once and referred to by manifests. -See [here](compatibility.md#content-addressable-storage-cas) for more details. - -Layers are therefore shared amongst manifests; each manifest maintains a reference -to the layer. As long as a layer is referenced by one manifest, it cannot be garbage -collected. - -Manifests and layers can be `deleted` with the registry API (refer to the API -documentation [here](spec/api.md#deleting-a-layer) and -[here](spec/api.md#deleting-an-image) for details). This API removes references -to the target and makes them eligible for garbage collection. It also makes them -unable to be read via the API. - -If a layer is deleted, it is removed from the filesystem when garbage collection -is run. If a manifest is deleted the layers to which it refers are removed from -the filesystem if no other manifests refers to them. - - -### Example - -In this example manifest A references two layers: `a` and `b`. Manifest `B` references -layers `a` and `c`. In this state, nothing is eligible for garbage collection: - -``` -A -----> a <----- B - \--> b | - c <--/ -``` - -Manifest B is deleted via the API: - -``` -A -----> a B - \--> b - c -``` - -In this state layer `c` no longer has a reference and is eligible for garbage -collection. Layer `a` had one reference removed but not garbage -collected as it is still referenced by manifest `A`. The blob representing -manifest `B` is eligible for garbage collection. - -After garbage collection has been run, manifest `A` and its blobs remain. - -``` -A -----> a - \--> b -``` - - -### More details about garbage collection - -Garbage collection runs in two phases. First, in the 'mark' phase, the process -scans all the manifests in the registry. From these manifests, it constructs a -set of content address digests. This set is the 'mark set' and denotes the set -of blobs to *not* delete. Secondly, in the 'sweep' phase, the process scans all -the blobs and if a blob's content address digest is not in the mark set, the -process deletes it. - - -> **Note** -> -> You should ensure that the registry is in read-only mode or not running at -> all. If you were to upload an image while garbage collection is running, there -> is the risk that the image's layers are mistakenly deleted leading to a -> corrupted image. - -This type of garbage collection is known as stop-the-world garbage collection. - -## Run garbage collection - -Garbage collection can be run as follows - -`bin/registry garbage-collect [--dry-run] [--delete-untagged] /path/to/config.yml` - -The garbage-collect command accepts a `--dry-run` parameter, which prints the progress -of the mark and sweep phases without removing any data. If you need to clean up untagged manifests as well, you can run the command with `--delete-untagged` parameter. Running with a log level of `info` -gives a clear indication of items eligible for deletion. - -The config.yml file should be in the following format: - -```yaml -version: 0.1 -storage: - filesystem: - rootdirectory: /registry/data -``` - -Below is example output from a dry run garbage collection with registry log level set to `info` - -``` -hello-world -hello-world: marking manifest sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf -hello-world: marking blob sha256:03f4658f8b782e12230c1783426bd3bacce651ce582a4ffb6fbbfa2079428ecb -hello-world: marking blob sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 -hello-world: marking configuration sha256:690ed74de00f99a7d00a98a5ad855ac4febd66412be132438f9b8dbd300a937d -ubuntu - -4 blobs marked, 5 blobs eligible for deletion -blob eligible for deletion: sha256:28e09fddaacbfc8a13f82871d9d66141a6ed9ca526cb9ed295ef545ab4559b81 -blob eligible for deletion: sha256:7e15ce58ccb2181a8fced7709e9893206f0937cc9543bc0c8178ea1cf4d7e7b5 -blob eligible for deletion: sha256:87192bdbe00f8f2a62527f36bb4c7c7f4eaf9307e4b87e8334fb6abec1765bcb -blob eligible for deletion: sha256:b549a9959a664038fc35c155a95742cf12297672ca0ae35735ec027d55bf4e97 -blob eligible for deletion: sha256:f251d679a7c61455f06d793e43c06786d7766c88b8c24edf242b2c08e3c3f599 -``` \ No newline at end of file diff --git a/content/registry/glossary.md b/content/registry/glossary.md deleted file mode 100644 index a40398f9ed7..00000000000 --- a/content/registry/glossary.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -published: false ---- - -# Glossary - -This page contains definitions for distribution related terms. - -
-

Blob

-
-
A blob is any kind of content that is stored by a Registry under a content-addressable identifier (a "digest").
-

- Layers are a good example of "blobs". -

-
- -

Image

-
-
An image is a named set of immutable data from which a Docker container can be created.
-

- An image is represented by a json file called a manifest, and is conceptually a set of layers. - - Image names indicate the location where they can be pulled from and pushed to, as they usually start with a registry domain name and port. - -

-
- -

Layer

-
-
A layer is a tar archive bundling partial content from a filesystem.
-

- Layers from an image are usually extracted in order on top of each other to make up a root filesystem from which containers run out. -

-
- -

Manifest

-
A manifest is the JSON representation of an image.
- -

Namespace

-
A namespace is a collection of repositories with a common name prefix.
-

- The namespace with an empty prefix is considered the Global Namespace. -

-
- -

Registry

-
A registry is a service that let you store and deliver images.
-
- -

Repository

-
-
A repository is a set of data containing all versions of a given image.
-
- -

Scope

-
A scope is the portion of a namespace onto which a given authorization token is granted.
- -

Tag

-
A tag is conceptually a "version" of a named image.
-

- Example: `docker pull myimage:latest` instructs docker to pull the image "myimage" in version "latest". -

- -
- - -
\ No newline at end of file diff --git a/content/registry/help.md b/content/registry/help.md deleted file mode 100644 index 6f23283fbef..00000000000 --- a/content/registry/help.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: Getting help with the Registry -keywords: registry, on-prem, images, tags, repository, distribution, help, 101, TL;DR -title: Get help ---- - -{{< include "registry.md" >}} - -If you need help, you can reach us on the #distribution channel in the CNCF Slack. - -If you want to report a bug, be sure to first read about [how to contribute](https://github.com/distribution/distribution/blob/master/CONTRIBUTING.md). You can then do so on the [GitHub project bugtracker](https://github.com/distribution/distribution/issues). \ No newline at end of file diff --git a/content/registry/images/notifications.gliffy b/content/registry/images/notifications.gliffy deleted file mode 100644 index 5ecf4c3aed6..00000000000 --- a/content/registry/images/notifications.gliffy +++ /dev/null @@ -1 +0,0 @@ -{"contentType":"application/gliffy+json","version":"1.3","stage":{"background":"#FFFFFF","width":737,"height":630,"nodeIndex":171,"autoFit":true,"exportBorder":false,"gridOn":true,"snapToGrid":true,"drawingGuidesOn":true,"pageBreaksOn":false,"printGridOn":false,"printPaper":"LETTER","printShrinkToFit":false,"printPortrait":true,"maxWidth":5000,"maxHeight":5000,"themeData":null,"viewportType":"default","fitBB":{"min":{"x":290,"y":83},"max":{"x":736.5,"y":630}},"objects":[{"x":699.0,"y":246.0,"rotation":0.0,"id":166,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":29,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[-30.0,-12.0],[-30.0,59.5],[33.0,59.5],[33.0,131.0]],"lockSegments":{},"ortho":true}},"linkMap":[]},{"x":632.0,"y":243.0,"rotation":0.0,"id":165,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":28,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[-25.0,-11.0],[-25.0,64.5],[-88.0,64.5],[-88.0,140.0]],"lockSegments":{},"ortho":true}},"linkMap":[],"children":[]},{"x":512.0,"y":203.0,"rotation":0.0,"id":161,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":27,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":1,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":null,"controlPath":[[-19.0,-3.0],[79.12746812182615,-3.0]],"lockSegments":{},"ortho":false}},"linkMap":[],"children":[]},{"x":589.9999999999999,"y":167.5,"rotation":0.0,"id":143,"width":101.11111111111111,"height":65.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.rectangle","order":2,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":0.722222222222222,"y":0.0,"rotation":0.0,"id":144,"width":99.66666666666663,"height":16.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Broadcaster

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}}}]},{"x":290.0,"y":105.0,"rotation":0.0,"id":160,"width":210.0,"height":190.0,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":26,"lockAspectRatio":false,"lockShape":false,"children":[{"x":12.92581625076238,"y":17.018834253729665,"rotation":0.0,"id":155,"width":189.57418374923762,"height":151.48116574627034,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":25,"lockAspectRatio":false,"lockShape":false,"children":[{"x":97.57418374923762,"y":58.481165746270335,"rotation":90.0,"id":151,"width":149.0,"height":37.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_bottom","order":21,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":153,"magnitude":1},{"id":154,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":8.0,"rotation":0.0,"id":152,"width":149.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":151,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":8.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":151,"magnitude":1},{"id":154,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":151,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":153,"width":149.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":151,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":10,"paddingBottom":8,"paddingLeft":10,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Listener

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":67.5,"y":1.0,"rotation":0.0,"id":154,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":152,"px":0.5,"py":0.0,"xOffset":-7.0,"yOffset":-7.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_bottom","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":10.074195639419855,"y":17.481165746270335,"rotation":0.0,"id":150,"width":120.0,"height":119.0,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":20,"lockAspectRatio":false,"lockShape":false,"children":[{"x":1.0,"y":80.5,"rotation":0.0,"id":133,"width":117.0,"height":38.5,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_bottom","order":16,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":135,"magnitude":1},{"id":136,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":8.0,"rotation":0.0,"id":134,"width":117.0,"height":30.5,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":133,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":8.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":133,"magnitude":1},{"id":136,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":133,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":135,"width":117.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":133,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":10,"paddingBottom":8,"paddingLeft":10,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

handler

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":51.5,"y":1.0,"rotation":0.0,"id":136,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":134,"px":0.5,"py":0.0,"xOffset":-7.0,"yOffset":-7.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_bottom","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":0.0,"y":39.0,"rotation":0.0,"id":129,"width":120.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":12,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":131,"magnitude":1},{"id":132,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":130,"width":120.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":129,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":129,"magnitude":1},{"id":132,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":129,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":131,"width":120.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":129,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

repository

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":53.0,"y":31.0,"rotation":0.0,"id":132,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":130,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":0.0,"y":0.0,"rotation":0.0,"id":125,"width":120.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":8,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":127,"magnitude":1},{"id":128,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":126,"width":120.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":125,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":125,"magnitude":1},{"id":128,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":125,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":127,"width":120.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":125,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

request

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":53.0,"y":31.0,"rotation":0.0,"id":128,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":126,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]}]},{"x":0.5154455517800614,"y":0.5154455517799761,"rotation":90.39513704250749,"id":145,"width":150.0,"height":150.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_bottom","order":4,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":147,"magnitude":1},{"id":148,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":8.0,"rotation":0.0,"id":146,"width":150.0,"height":142.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":145,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":8.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":145,"magnitude":1},{"id":148,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":145,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":147,"width":150.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":145,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":10,"paddingBottom":8,"paddingLeft":10,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

 

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":68.0,"y":0.9999999999999432,"rotation":0.0,"id":148,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":146,"px":0.5,"py":0.0,"xOffset":-7.0,"yOffset":-7.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_bottom","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]}]},{"x":0.0,"y":0.0,"rotation":0.0,"id":156,"width":210.0,"height":190.0,"uid":"com.gliffy.shape.basic.basic_v1.default.rectangle","order":0,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.rectangle.basic_v1","strokeWidth":2.0,"strokeColor":"#434343","fillColor":"#ffffff","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":159,"width":206.0,"height":16.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Registry instance

","tid":null,"valign":"middle","vposition":"above","hposition":"none"}}}]}]},{"x":473.0,"y":525.0,"rotation":0.0,"id":115,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":69,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":68,"py":1.0,"px":0.5}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":109,"py":0.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":0,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[2.0,4.5],[2.0,11.533649282003012],[2.0,18.567298564006137],[2.0,25.60094784600915]],"lockSegments":{},"ortho":true}},"linkMap":[]},{"x":665.0,"y":530.0,"rotation":0.0,"id":114,"width":100.0,"height":100.0,"uid":"com.gliffy.shape.basic.basic_v1.default.line","order":68,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[],"startConstraint":{"type":"StartPositionConstraint","StartPositionConstraint":{"nodeId":100,"py":1.0,"px":0.5}},"endConstraint":{"type":"EndPositionConstraint","EndPositionConstraint":{"nodeId":112,"py":0.0,"px":0.5}}},"graphic":{"type":"Line","Line":{"strokeWidth":2.0,"strokeColor":"#000000","fillColor":"none","dashStyle":null,"startArrow":0,"endArrow":0,"startArrowRotation":"auto","endArrowRotation":"auto","interpolationType":"linear","cornerRadius":10.0,"controlPath":[[-2.0,-0.5],[-2.0,6.533649282003012],[-2.0,13.567298564006137],[-2.0,20.60094784600915]],"lockSegments":{},"ortho":true}},"linkMap":[]},{"x":598.0,"y":550.0,"rotation":0.0,"id":112,"width":120.0,"height":80.0,"uid":"com.gliffy.shape.network.network_v3.home.cloud","order":66,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.cloud.network_v3","strokeWidth":2.0,"strokeColor":"#000000","fillColor":"#000000","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":113,"width":116.00000000000001,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Remote

Endpoint_N

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}}}]},{"x":420.0,"y":550.0,"rotation":0.0,"id":109,"width":120.0,"height":80.0,"uid":"com.gliffy.shape.network.network_v3.home.cloud","order":64,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.cloud.network_v3","strokeWidth":2.0,"strokeColor":"#000000","fillColor":"#000000","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":111,"width":116.00000000000001,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Remote

Endpoint_1

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}}}]},{"x":540.0,"y":438.5,"rotation":0.0,"id":104,"width":50.0,"height":16.0,"uid":"com.gliffy.shape.basic.basic_v1.default.text","order":63,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

. . .

","tid":null,"valign":"middle","vposition":"none","hposition":"none"}},"linkMap":[]},{"x":410.0,"y":379.5,"rotation":0.0,"id":103,"width":130.0,"height":150.0,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":62,"lockAspectRatio":false,"lockShape":false,"children":[{"x":15.0,"y":20.0,"rotation":0.0,"id":84,"width":100.0,"height":117.0,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":45,"lockAspectRatio":false,"lockShape":false,"children":[{"x":0.0,"y":78.0,"rotation":0.0,"id":80,"width":100.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":41,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":82,"magnitude":1},{"id":83,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":81,"width":100.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":80,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":80,"magnitude":1},{"id":83,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":80,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":82,"width":100.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":80,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

http

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":43.0,"y":31.0,"rotation":0.0,"id":83,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":81,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":0.0,"y":39.0,"rotation":0.0,"id":76,"width":100.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":37,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":78,"magnitude":1},{"id":79,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":77,"width":100.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":76,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":76,"magnitude":1},{"id":79,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":76,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":78,"width":100.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":76,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

retry

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":43.0,"y":31.0,"rotation":0.0,"id":79,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":77,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":0.0,"y":0.0,"rotation":0.0,"id":72,"width":100.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":33,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":74,"magnitude":1},{"id":75,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":73,"width":100.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":72,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":72,"magnitude":1},{"id":75,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":72,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":74,"width":100.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":72,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

queue

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":43.0,"y":31.0,"rotation":0.0,"id":75,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":73,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]}]},{"x":0.0,"y":0.0,"rotation":0.0,"id":68,"width":130.0,"height":150.0,"uid":"com.gliffy.shape.sitemap.sitemap_v1.default.download","order":31,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.download.sitemap_v1","strokeWidth":2.0,"strokeColor":"#666666","fillColor":"#ffffff","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":71,"width":126.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Endpoint_1

","tid":null,"valign":"middle","vposition":"above","hposition":"none"}}}]}]},{"x":598.0,"y":379.5,"rotation":0.0,"id":102,"width":130.0,"height":150.0,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":61,"lockAspectRatio":false,"lockShape":false,"children":[{"x":15.0,"y":20.0,"rotation":0.0,"id":87,"width":100.0,"height":117.0,"uid":"com.gliffy.shape.basic.basic_v1.default.group","order":60,"lockAspectRatio":false,"lockShape":false,"children":[{"x":0.0,"y":78.0,"rotation":0.0,"id":88,"width":100.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":56,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":90,"magnitude":1},{"id":91,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":89,"width":100.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":88,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":88,"magnitude":1},{"id":91,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":88,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":90,"width":100.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":88,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

http

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":43.0,"y":31.0,"rotation":0.0,"id":91,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":89,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":0.0,"y":39.0,"rotation":0.0,"id":92,"width":100.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":52,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":94,"magnitude":1},{"id":95,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":93,"width":100.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":92,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":92,"magnitude":1},{"id":95,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":92,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":94,"width":100.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":92,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

retry

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":43.0,"y":31.0,"rotation":0.0,"id":95,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":93,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]},{"x":0.0,"y":0.0,"rotation":0.0,"id":96,"width":100.0,"height":40.0,"uid":"com.gliffy.shape.ui.ui_v3.containers_content.popover_top","order":48,"lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"MinWidthConstraint","MinWidthConstraint":{"width":100}},{"type":"HeightConstraint","HeightConstraint":{"isMin":true,"heightInfo":[{"id":98,"magnitude":1},{"id":99,"magnitude":1}],"minHeight":0.0,"growParent":false,"padding":0.0}}]},"linkMap":[],"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":97,"width":100.0,"height":32.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"PositionConstraint","PositionConstraint":{"nodeId":96,"px":0.0,"py":0.0,"xOffset":0.0,"yOffset":0.0}},{"type":"HeightConstraint","HeightConstraint":{"isMin":false,"heightInfo":[{"id":96,"magnitude":1},{"id":99,"magnitude":-1}],"minHeight":0.0,"growParent":false,"padding":0.0}},{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":96,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[{"x":0.0,"y":0.0,"rotation":0.0,"id":98,"width":100.0,"height":29.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"WidthConstraint","WidthConstraint":{"isMin":false,"widthInfo":[{"id":96,"magnitude":1}],"minWidth":0.0,"growParent":false,"padding":0.0}}]},"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":8,"paddingRight":8,"paddingBottom":8,"paddingLeft":8,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

queue

","tid":null,"valign":"top","vposition":"none","hposition":"none"}}}]},{"x":43.0,"y":31.0,"rotation":0.0,"id":99,"width":15.0,"height":8.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"constraints":{"constraints":[{"type":"ConstWidthConstraint","ConstWidthConstraint":{"width":15}},{"type":"ConstHeightConstraint","ConstHeightConstraint":{"height":8}},{"type":"PositionConstraint","PositionConstraint":{"nodeId":97,"px":0.5,"py":1.0,"xOffset":-7.0,"yOffset":-1.0}}]},"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.ui.ui_v3.containers_content.popover_top","strokeWidth":2.0,"strokeColor":"#BBBBBB","fillColor":"#FFFFFF","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":4.0,"shadowY":4.0}},"children":[]}]}]},{"x":0.0,"y":0.0,"rotation":0.0,"id":100,"width":130.0,"height":150.0,"uid":"com.gliffy.shape.sitemap.sitemap_v1.default.download","order":46,"lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Shape","Shape":{"tid":"com.gliffy.stencil.download.sitemap_v1","strokeWidth":2.0,"strokeColor":"#666666","fillColor":"#ffffff","gradient":false,"dashStyle":null,"dropShadow":false,"state":0,"opacity":1.0,"shadowX":0.0,"shadowY":0.0}},"linkMap":[],"children":[{"x":2.0,"y":0.0,"rotation":0.0,"id":101,"width":126.0,"height":14.0,"uid":null,"order":"auto","lockAspectRatio":false,"lockShape":false,"graphic":{"type":"Text","Text":{"overflow":"none","paddingTop":2,"paddingRight":2,"paddingBottom":2,"paddingLeft":2,"outerPaddingTop":6,"outerPaddingRight":6,"outerPaddingBottom":2,"outerPaddingLeft":6,"type":"fixed","lineTValue":null,"linePerpValue":null,"cardinalityType":null,"html":"

Endpoint_N

","tid":null,"valign":"middle","vposition":"above","hposition":"none"}}}]}]}],"shapeStyles":{"com.gliffy.shape.sitemap.sitemap_v1.default":{"fill":"#ffffff","stroke":"#666666","strokeWidth":2},"com.gliffy.shape.network.network_v3.home":{"fill":"#000000"},"com.gliffy.shape.network.network_v3.business":{"fill":"#003366"},"com.gliffy.shape.basic.basic_v1.default":{"fill":"#FFFFFF","stroke":"#434343","strokeWidth":2}},"lineStyles":{"global":{"endArrow":1}},"textStyles":{"global":{"size":"14px"}}},"metadata":{"title":"untitled","revision":0,"exportBorder":false,"loadPosition":"default","libraries":["com.gliffy.libraries.sitemap.sitemap_v2","com.gliffy.libraries.sitemap.sitemap_v1.default","com.gliffy.libraries.ui.ui_v3.containers_content","com.gliffy.libraries.table.table_v2.default","com.gliffy.libraries.ui.ui_v3.navigation","com.gliffy.libraries.ui.ui_v3.forms_controls","com.gliffy.libraries.ui.ui_v3.icon_symbols","com.gliffy.libraries.ui.ui_v2.forms_components","com.gliffy.libraries.ui.ui_v2.content","com.gliffy.libraries.ui.ui_v2.miscellaneous","com.gliffy.libraries.network.network_v3.home","com.gliffy.libraries.network.network_v3.business","com.gliffy.libraries.network.network_v3.rack","com.gliffy.libraries.uml.uml_v2.class","com.gliffy.libraries.uml.uml_v2.sequence","com.gliffy.libraries.uml.uml_v2.activity","com.gliffy.libraries.uml.uml_v2.state_machine","com.gliffy.libraries.uml.uml_v2.deployment","com.gliffy.libraries.uml.uml_v2.use_case","com.gliffy.libraries.erd.erd_v1.default","com.gliffy.libraries.flowchart.flowchart_v1.default","com.gliffy.libraries.swimlanes.swimlanes_v1.default","com.gliffy.libraries.uml.uml_v2.component","com.gliffy.libraries.basic.basic_v1.default","com.gliffy.libraries.images"]},"embeddedResources":{"index":0,"resources":[]}} \ No newline at end of file diff --git a/content/registry/images/notifications.png b/content/registry/images/notifications.png deleted file mode 100644 index c7a78f37b47..00000000000 Binary files a/content/registry/images/notifications.png and /dev/null differ diff --git a/content/registry/images/notifications.svg b/content/registry/images/notifications.svg deleted file mode 100644 index 6c3d680b95b..00000000000 --- a/content/registry/images/notifications.svg +++ /dev/null @@ -1 +0,0 @@ -Registry instanceBroadcaster requestrepositoryhandlerListenerEndpoint_1queueretryhttpEndpoint_Nqueueretryhttp. . .RemoteEndpoint_1RemoteEndpoint_N \ No newline at end of file diff --git a/content/registry/insecure.md b/content/registry/insecure.md deleted file mode 100644 index 64527c4d95d..00000000000 --- a/content/registry/insecure.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -description: Deploying a Registry in an insecure fashion -keywords: registry, on-prem, images, tags, repository, distribution, insecure -title: Test an insecure registry ---- - -{{< include "registry.md" >}} - -While it's highly recommended to secure your registry using a TLS certificate -issued by a known CA, you can choose to use self-signed certificates, or use -your registry over an unencrypted HTTP connection. Either of these choices -involves security trade-offs and additional configuration steps. - -## Deploy a plain HTTP registry - -> **Warning** -> -> It's not possible to use an insecure registry with basic authentication. -{ .warning } - -This procedure configures Docker to entirely disregard security for your -registry. This is very insecure and is not recommended. It exposes your -registry to trivial man-in-the-middle (MITM) attacks. Only use this solution for -isolated testing or in a tightly controlled, air-gapped environment. - -1. Edit the `daemon.json` file, whose default location is - `/etc/docker/daemon.json` on Linux or - `C:\ProgramData\docker\config\daemon.json` on Windows Server. If you use - Docker Desktop for Mac, Windows, or Linux, navigate to **Settings** and then select the **Docker Engine** tab. - - If the `daemon.json` file does not exist, create it. Assuming there are no - other settings in the file, it should have the following contents: - - ```json - { - "insecure-registries" : ["myregistrydomain.com:5000"] - } - ``` - - Substitute the address of your insecure registry for the one in the example. - - With insecure registries enabled, Docker goes through the following steps: - - - Try using HTTPS. - - If HTTPS is available but the certificate is invalid, ignore the error - about the certificate. - - If HTTPS is not available, fall back to HTTP. - - -2. Restart Docker for the changes to take effect. - - -Repeat these steps on every engine host that wants to access your registry. - - -## Use self-signed certificates - -> **Warning** -> -> Using this along with basic authentication requires to also trust the -certificate into the OS cert store for some versions of Docker. This is covered below. -{.warning } - -This is more secure than the insecure registry solution. - -1. Generate your own certificate: - - ```console - $ mkdir -p certs - - $ openssl req \ - -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \ - -addext "subjectAltName = DNS:myregistry.domain.com" \ - -x509 -days 365 -out certs/domain.crt - ``` - - Be sure to use the name `myregistry.domain.com` as a CN. - -2. Use the result to [start your registry with TLS enabled](./deploying.md#get-a-certificate). - -3. Instruct every Docker daemon to trust that certificate. The way to do this - depends on your OS. - - - Linux: Copy the `domain.crt` file to - `/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt` on every Docker - host. You do not need to restart Docker. - - - Windows Server: - - 1. Open Windows Explorer, right-click the `domain.crt` - file, and choose Install certificate. When prompted, select the following - options: - - | Store location | local machine | - | Place all certificates in the following store | selected | - - 2. Select **Browser** and then select **Trusted Root Certificate Authorities**. - - 3. Select **Finish** and then restart Docker. - - - Docker Desktop for Mac: Follow the instructions in - [Adding custom CA certificates](../desktop/faqs/macfaqs.md#add-custom-ca-certificates-server-side). - Restart Docker. - - - Docker Desktop for Windows: Follow the instructions in - [Adding custom CA certificates](../desktop/faqs/windowsfaqs.md#how-do-i-add-custom-ca-certificates). - Restart Docker. - - -## Troubleshoot insecure registry - -This section lists some common failures and how to recover from them. - -### Failing... - -Failing to configure the Engine daemon and trying to pull from a registry that is not using -TLS results in the following message: - -```none -FATA[0000] Error response from daemon: v1 ping attempt failed with error: -Get https://myregistrydomain.com:5000/v1/_ping: tls: oversized record received with length 20527. -If this private registry supports only HTTP or HTTPS with an unknown CA certificate, add -`--insecure-registry myregistrydomain.com:5000` to the daemon's arguments. -In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; -simply place the CA certificate at /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt -``` - -### Docker still complains about the certificate when using authentication? - -When using authentication, some versions of Docker also require you to trust the -certificate at the OS level. - -#### Ubuntu - -```console -$ cp certs/domain.crt /usr/local/share/ca-certificates/myregistrydomain.com.crt -update-ca-certificates -``` - -#### Red Hat Enterprise Linux - -```console -$ cp certs/domain.crt /etc/pki/ca-trust/source/anchors/myregistrydomain.com.crt -update-ca-trust -``` - -#### Oracle Linux - -```console -$ update-ca-trust enable -``` - -Restart Docker for the changes to take effect. - -### Windows - -Open Windows Explorer, right-click the certificate, and choose -**Install certificate**. - -Then, select the following options: - -* Store location: local machine -* Check **place all certificates in the following store** -* Click **Browser**, and select **Trusted Root Certificate Authorities** -* Click **Finish** - -[Learn more about managing TLS certificates](https://technet.microsoft.com/en-us/library/cc754841(v=ws.11).aspx#BKMK_addlocal). - -After adding the CA certificate to Windows, restart Docker Desktop for Windows. \ No newline at end of file diff --git a/content/registry/introduction.md b/content/registry/introduction.md deleted file mode 100644 index ef10f86b8b0..00000000000 --- a/content/registry/introduction.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -description: Explains what the Registry is, basic use cases and requirements -keywords: registry, on-prem, images, tags, repository, distribution, use cases, requirements -title: About Registry ---- - -{{< include "registry.md" >}} - -A registry is a storage and content delivery system, holding named Docker -images, available in different tagged versions. - -For example, with the image `distribution/registry`, with tag `2.1`, users interact with a registry by using Docker push and pull commands: - - ```console - $ docker pull registry-1.docker.io/distribution/registry:2.1 - ``` - -Storage itself is delegated to drivers. The default storage driver is the local -posix filesystem, which is suitable for development or small deployments. -Additional cloud-based storage drivers like S3, Microsoft Azure, OpenStack Swift, -and Aliyun OSS are also supported. People looking into using other storage -backends may do so by writing their own driver implementing the -[Storage API](storage-drivers/index.md). - -Since securing access to your hosted images is paramount, the Registry natively -supports TLS and basic authentication. - -The Registry GitHub repository includes additional information about advanced -authentication and authorization methods. Only very large or public deployments -are expected to extend the Registry in this way. - -Finally, the Registry ships with a robust [notification system](notifications.md), -calling webhooks in response to activity, and both extensive logging and reporting, -mostly useful for large installations that want to collect metrics. - -## Understanding image naming - -Image names as used in typical docker commands reflect their origin: - - * `docker pull ubuntu` instructs docker to pull an image named `ubuntu` from the official Docker Hub. This is simply a shortcut for the longer `docker pull docker.io/library/ubuntu` command - * `docker pull myregistrydomain:port/foo/bar` instructs docker to contact the registry located at `myregistrydomain:port` to find the image `foo/bar` - -You can find out more about the various Docker commands dealing with images in -the [official Docker Engine documentation](../engine/reference/commandline/cli.md). - -## Use cases - -Running your own Registry is a great solution to integrate with and complement -your CI/CD system. In a typical workflow, a commit to your source revision -control system would trigger a build on your CI system, which would then push a -new image to your Registry if the build is successful. A notification from the -Registry would then trigger a deployment on a staging environment, or notify -other systems that a new image is available. - -It's also an essential component if you want to quickly deploy a new image over -a large cluster of machines. - -Finally, it's the best way to distribute images inside an isolated network. - -## Requirements - -You absolutely need to be familiar with Docker, specifically with regard to -pushing and pulling images. You must understand the difference between the -daemon and the cli, and at least grasp basic concepts about networking. - -Also, while just starting a registry is fairly easy, operating it in a -production environment requires operational skills, just like any other service. -You are expected to be familiar with systems availability and scalability, -logging and log processing, systems monitoring, and security 101. Strong -understanding of http and overall network communications, plus familiarity with -golang are certainly useful as well for advanced operations or hacking. - -## Next - -Dive into [deploying your registry](deploying.md) diff --git a/content/registry/migration.md b/content/registry/migration.md deleted file mode 100644 index 30a2df180be..00000000000 --- a/content/registry/migration.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -published: false ---- - -# Migrating a 1.0 registry to 2.0 - -TODO: This needs to be revised in light of Olivier's work - -A few thoughts here: - -There was no "1.0". There was an implementation of the Registry API V1 but only a version 0.9 of the service was released. -The image formats are not compatible in any way. One must convert v1 images to v2 images using a docker client or other tool. -One can migrate images from one version to the other by pulling images from the old registry and pushing them to the v2 registry. - ------ - -The Docker Registry 2.0 is backward compatible with images created by the earlier specification. If you are migrating a private registry to version 2.0, you should use the following process: - -1. Configure and test a 2.0 registry image in a sandbox environment. - -2. Back up up your production image storage. - - Your production image storage should reside on a volume or storage backend. - Make sure you have a backup of its contents. - -3. Stop your existing registry service. - -4. Restart your registry with your tested 2.0 image. \ No newline at end of file diff --git a/content/registry/notifications.md b/content/registry/notifications.md deleted file mode 100644 index 7cd8243b8c4..00000000000 --- a/content/registry/notifications.md +++ /dev/null @@ -1,350 +0,0 @@ ---- -description: Explains how to work with registry notifications -keywords: registry, on-prem, images, tags, repository, distribution, notifications, - advanced -title: Work with notifications ---- - -{{< include "registry.md" >}} - -The Registry supports sending webhook notifications in response to events -happening within the registry. Notifications are sent in response to manifest -pushes and pulls and layer pushes and pulls. These actions are serialized into -events. The events are queued into a registry-internal broadcast system which -queues and dispatches events to [Endpoints](notifications.md#endpoints). - -![Workflow of registry notifications](images/notifications.png) - -## Endpoints - -Notifications are sent to endpoints via HTTP requests. Each configured -endpoint has isolated queues, retry configuration and http targets within each -instance of a registry. When an action happens within the registry, it is -converted into an event which is dropped into an inmemory queue. When the -event reaches the end of the queue, an http request is made to the endpoint -until the request succeeds. The events are sent serially to each endpoint but -order is not guaranteed. - -## Configuration - -To setup a registry instance to send notifications to endpoints, you must add -them to the configuration. - -```yaml -notifications: - endpoints: - - name: alistener - url: https://mylistener.example.com/event - headers: - Authorization: [Bearer ] - timeout: 500ms - threshold: 5 - backoff: 1s -``` - -In the previous example, you would configure the registry with an endpoint to send events to -`https://mylistener.example.com/event`, with the header "Authorization: Bearer -". The request would timeout after 500 milliseconds. If -5 failures happen consecutively, the registry backs off for 1 second before -trying again. - -For details on the fields, see the [configuration documentation](configuration.md#notifications). - -A properly configured endpoint should lead to a log message from the registry -upon startup: - -``` -INFO[0000] configuring endpoint alistener (https://mylistener.example.com/event), timeout=500ms, headers=map[Authorization:[Bearer ]] app.id=812bfeb2-62d6-43cf-b0c6-152f541618a3 environment=development service=registry -``` - -## Events - -Events have a well-defined JSON structure and are sent as the body of -notification requests. One or more events are sent in a structure called an -envelope. Each event has a unique ID that can be used to uniquely identify incoming -requests, if required. Along with that, an action is provided with a -target, identifying the object mutated during the event. - -The fields available in an `event` are described below. - -Field | Type | Description ------ | ----- | ------------- -id | string |ID provides a unique identifier for the event. -timestamp | Time | Timestamp is the time at which the event occurred. -action | string | Action indicates what action encompasses the provided event. -target | distribution.Descriptor | Target uniquely describes the target of the event. -length | int | Length in bytes of content. Same as Size field in Descriptor. -repository | string | Repository identifies the named repository. -fromRepository | string | FromRepository identifies the named repository which a blob was mounted from if appropriate. -url | string | URL provides a direct link to the content. -tag | string | Tag identifies a tag name in tag events. -request | [RequestRecord](https://godoc.org/github.com/docker/distribution/notifications#RequestRecord) | Request covers the request that generated the event. -actor | [ActorRecord](https://godoc.org/github.com/docker/distribution/notifications#ActorRecord). | Actor specifies the agent that initiated the event. For most situations, this could be from the authorization context of the request. -source | [SourceRecord](https://godoc.org/github.com/docker/distribution/notifications#SourceRecord) | Source identifies the registry node that generated the event. Put differently, while the actor "initiates" the event, the source "generates" it. - -The following is an example of a JSON event, sent in response to the pull of a -manifest: - -```json -{ - "events": [ - { - "id": "320678d8-ca14-430f-8bb6-4ca139cd83f7", - "timestamp": "2016-03-09T14:44:26.402973972-08:00", - "action": "pull", - "target": { - "mediaType": "application/vnd.docker.distribution.manifest.v2+json", - "size": 708, - "digest": "sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf", - "length": 708, - "repository": "hello-world", - "url": "http://192.168.100.227:5000/v2/hello-world/manifests/sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf", - "tag": "latest" - }, - "request": { - "id": "6df24a34-0959-4923-81ca-14f09767db19", - "addr": "192.168.64.11:42961", - "host": "192.168.100.227:5000", - "method": "GET", - "useragent": "curl/7.38.0" - }, - "actor": {}, - "source": { - "addr": "xtal.local:5000", - "instanceID": "a53db899-3b4b-4a62-a067-8dd013beaca4" - } - } - ] -} -``` - -The target struct of events which are sent when manifests and blobs are deleted -contains a subset of the data contained in Get and Put events. Specifically, -only the digest and repository are sent. - -```json -{ - "target": { - "digest": "sha256:d89e1bee20d9cb344674e213b581f14fbd8e70274ecf9d10c514bab78a307845", - "repository": "library/test" - } -} -``` - -> **Note** -> -> As of version 2.1, the `length` field for event targets -> is being deprecated for the `size` field, bringing the target in line with -> common nomenclature. Both will continue to be set for the foreseeable -> future. Newer code should favor `size` but accept either. - -## Envelope - -The envelope contains one or more events, with the following json structure: - -```json -{ - "events": [ "..." ] -} -``` - -While events may be sent in the same envelope, the set of events within that -envelope have no implied relationship. For example, the registry may choose to -group unrelated events and send them in the same envelope to reduce the total -number of requests. - -The full package has the mediatype -"application/vnd.docker.distribution.events.v1+json", which is set on the -request coming to an endpoint. - -An example of a full event may look as follows: - -```http -GET /callback HTTP/1.1 -Host: application/vnd.docker.distribution.events.v1+json -Authorization: Bearer -Content-Type: application/vnd.docker.distribution.events.v1+json - -{ - "events": [ - { - "id": "asdf-asdf-asdf-asdf-0", - "timestamp": "2006-01-02T15:04:05Z", - "action": "push", - "target": { - "mediaType": "application/vnd.docker.distribution.manifest.v1+json", - "length": 1, - "digest": "sha256:fea8895f450959fa676bcc1df0611ea93823a735a01205fd8622846041d0c7cf", - "repository": "library/test", - "url": "https://example.com/v2/library/test/manifests/sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" - }, - "request": { - "id": "asdfasdf", - "addr": "client.local", - "host": "registrycluster.local", - "method": "PUT", - "useragent": "test/0.1" - }, - "actor": { - "name": "test-actor" - }, - "source": { - "addr": "hostname.local:port" - } - }, - { - "id": "asdf-asdf-asdf-asdf-1", - "timestamp": "2006-01-02T15:04:05Z", - "action": "push", - "target": { - "mediaType": "application/vnd.docker.container.image.rootfs.diff+x-gtar", - "length": 2, - "digest": "sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5", - "repository": "library/test", - "url": "https://example.com/v2/library/test/blobs/sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" - }, - "request": { - "id": "asdfasdf", - "addr": "client.local", - "host": "registrycluster.local", - "method": "PUT", - "useragent": "test/0.1" - }, - "actor": { - "name": "test-actor" - }, - "source": { - "addr": "hostname.local:port" - } - }, - { - "id": "asdf-asdf-asdf-asdf-2", - "timestamp": "2006-01-02T15:04:05Z", - "action": "push", - "target": { - "mediaType": "application/vnd.docker.container.image.rootfs.diff+x-gtar", - "length": 3, - "digest": "sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5", - "repository": "library/test", - "url": "https://example.com/v2/library/test/blobs/sha256:c3b3692957d439ac1928219a83fac91e7bf96c153725526874673ae1f2023f8d5" - }, - "request": { - "id": "asdfasdf", - "addr": "client.local", - "host": "registrycluster.local", - "method": "PUT", - "useragent": "test/0.1" - }, - "actor": { - "name": "test-actor" - }, - "source": { - "addr": "hostname.local:port" - } - } - ] -} -``` - -## Responses - -The registry is fairly accepting of the response codes from endpoints. If an -endpoint responds with any 2xx or 3xx response code (after following -redirects), the message is considered to have been delivered, and is discarded. - -In turn, it is recommended that endpoints are accepting of incoming responses, -as well. While the format of event envelopes are standardized by media type, -any "pickyness" about validation may cause the queue to backup on the -registry. - -## Monitoring - -The state of the endpoints are reported via the debug/vars http interface, -usually configured to `http://localhost:5001/debug/vars`. Information such as -configuration and metrics are available by endpoint. - -The following provides an example of a few endpoints that have experienced -several failures and have since recovered: - -```json -{ - "notifications": { - "endpoints": [ - { - "name": "local-5003", - "url": "http://localhost:5003/callback", - "Headers": { - "Authorization": [ - "Bearer \u003can example token\u003e" - ] - }, - "Timeout": 1000000000, - "Threshold": 10, - "Backoff": 1000000000, - "Metrics": { - "Pending": 76, - "Events": 76, - "Successes": 0, - "Failures": 0, - "Errors": 46, - "Statuses": { - } - } - }, - { - "name": "local-8083", - "url": "http://localhost:8083/callback", - "Headers": null, - "Timeout": 1000000000, - "Threshold": 10, - "Backoff": 1000000000, - "Metrics": { - "Pending": 0, - "Events": 76, - "Successes": 76, - "Failures": 0, - "Errors": 28, - "Statuses": { - "202 Accepted": 76 - } - } - } - ] - } -} -``` - -If using notifications as part of a larger application, it is critical to -monitor the size ("Pending" above) of the endpoint queues. If failures or -queue sizes are increasing, it can indicate a larger problem. - -The logs are also a valuable resource for monitoring problems. A failing -endpoint leads to messages similar to the following: - -```none -ERRO[0340] retryingsink: error writing events: httpSink{http://localhost:5003/callback}: error posting: Post http://localhost:5003/callback: dial tcp 127.0.0.1:5003: connection refused, retrying -WARN[0340] httpSink{http://localhost:5003/callback} encountered too many errors, backing off -``` - -The above indicates that several errors caused a backoff and the registry -waits before retrying. - -## Considerations - -Currently, the queues are inmemory, so endpoints should be _reasonably -reliable_. They are designed to make a best-effort to send the messages but if -an instance is lost, messages may be dropped. If an endpoint goes down, care -should be taken to ensure that the registry instance is not terminated before -the endpoint comes back up or messages are lost. - -This can be mitigated by running endpoints in close proximity to the registry -instances. One could run an endpoint that pages to disk and then forwards a -request to provide better durability. - -The notification system is designed around a series of interchangeable _sinks_ -which can be wired up to achieve interesting behavior. If this system doesn't -provide acceptable guarantees, adding a transactional `Sink` to the registry -is a possibility, although it may have an effect on request service time. -See the -[godoc](https://godoc.org/github.com/docker/distribution/notifications#Sink) -for more information. \ No newline at end of file diff --git a/content/registry/recipes/_index.md b/content/registry/recipes/_index.md deleted file mode 100644 index 412ae324d2d..00000000000 --- a/content/registry/recipes/_index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -description: Fun stuff to do with your registry -keywords: registry, on-prem, images, tags, repository, distribution, recipes, advanced -title: Recipes overview ---- - -{{< include "registry.md" >}} - -This section provides end-to-end scenarios for exotic or otherwise advanced use-cases. -These examples are not useful for most standard set-ups. - -## Requirements - -Before following these steps, work through the [deployment guide](../deploying.md). - -You must meet the following requirements: - - * Make sure you understand Docker security requirements, and how to configure your Docker Engine properly - * You have installed Docker Compose - * You have a certificate from a known CA instead of self-signed certificates. This is highly recommended. - * Inside the current directory, you have a X509 `domain.crt` and `domain.key`, for the CN `myregistrydomain.com` - * You have stopped and removed any previously running registry (typically `docker container stop registry && docker container rm -v registry`) - -## Recipes - - * [Using Apache as an authenticating proxy](apache.md) - * [Using Nginx as an authenticating proxy](nginx.md) - * [Running a Registry on macOS](osx-setup-guide.md) - * [Mirror the Docker Hub](mirror.md) \ No newline at end of file diff --git a/content/registry/recipes/apache.md b/content/registry/recipes/apache.md deleted file mode 100644 index ea0af077ffa..00000000000 --- a/content/registry/recipes/apache.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -description: Restricting access to your registry using an apache proxy -keywords: registry, on-prem, images, tags, repository, distribution, authentication, - proxy, apache, httpd, TLS, recipe, advanced -title: Authenticate proxy with apache ---- - -{{< include "registry.md" >}} - -## Use-case - -People already relying on an apache proxy to authenticate their users to other services might want to leverage it and have Registry communications tunneled through the same pipeline. - -Usually, that includes enterprise setups using LDAP/AD on the backend and a SSO mechanism fronting their internal http portal. - -### Alternatives - -If you just want authentication for your registry, and are happy maintaining users access separately, you should consider sticking with the native [basic auth registry feature](../deploying.md#native-basic-auth). - -### Solution - -With the method presented here, you implement basic authentication for Docker Engine in a reverse proxy that sits in front of your registry. - -While we use a simple `htpasswd` file as an example, any other apache authentication backend should be fairly easy to implement once you are done with the example. - -We also implement push restriction (to a limited user group) for the sake of the example. Again, you should modify this to fit your requirements. - -### Gotchas - -While this model gives you the ability to use whatever authentication backend you want through the secondary authentication mechanism implemented inside your proxy, it also requires that you move TLS termination from the Registry to the proxy itself. - -Furthermore, introducing an extra http layer in your communication pipeline adds complexity when deploying, maintaining, and debugging. - -## Setting things up - -1. Read [the requirements](index.md#requirements). - -2. Run the following script: - -``` -mkdir -p auth -mkdir -p data - -# This is the main apache configuration -cat < auth/httpd.conf -LoadModule headers_module modules/mod_headers.so - -LoadModule authn_file_module modules/mod_authn_file.so -LoadModule authn_core_module modules/mod_authn_core.so -LoadModule authz_groupfile_module modules/mod_authz_groupfile.so -LoadModule authz_user_module modules/mod_authz_user.so -LoadModule authz_core_module modules/mod_authz_core.so -LoadModule auth_basic_module modules/mod_auth_basic.so -LoadModule access_compat_module modules/mod_access_compat.so - -LoadModule log_config_module modules/mod_log_config.so - -LoadModule ssl_module modules/mod_ssl.so - -LoadModule proxy_module modules/mod_proxy.so -LoadModule proxy_http_module modules/mod_proxy_http.so - -LoadModule unixd_module modules/mod_unixd.so - - - SSLRandomSeed startup builtin - SSLRandomSeed connect builtin - - - - User daemon - Group daemon - - -ServerAdmin you@example.com - -ErrorLog /proc/self/fd/2 - -LogLevel warn - - - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - LogFormat "%h %l %u %t \"%r\" %>s %b" common - - - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio - - - CustomLog /proc/self/fd/1 common - - -ServerRoot "/usr/local/apache2" - -Listen 5043 - - - AllowOverride none - Require all denied - - - - - ServerName myregistrydomain.com - - SSLEngine on - SSLCertificateFile /usr/local/apache2/conf/domain.crt - SSLCertificateKeyFile /usr/local/apache2/conf/domain.key - - ## SSL settings recommendation from: https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html - # Anti CRIME - SSLCompression off - - # POODLE and other stuff - SSLProtocol all -SSLv2 -SSLv3 -TLSv1 - - # Secure cypher suites - SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH - SSLHonorCipherOrder on - - Header always set "Docker-Distribution-Api-Version" "registry/2.0" - Header onsuccess set "Docker-Distribution-Api-Version" "registry/2.0" - RequestHeader set X-Forwarded-Proto "https" - - ProxyRequests off - ProxyPreserveHost on - - # no proxy for /error/ (Apache HTTPd errors messages) - ProxyPass /error/ ! - - ProxyPass /v2 http://registry:5000/v2 - ProxyPassReverse /v2 http://registry:5000/v2 - - - Order deny,allow - Allow from all - AuthName "Registry Authentication" - AuthType basic - AuthUserFile "/usr/local/apache2/conf/httpd.htpasswd" - AuthGroupFile "/usr/local/apache2/conf/httpd.groups" - - # Read access to authentified users - - Require valid-user - - - # Write access to docker-deployer only - - Require group pusher - - - - - -EOF - -# Now, create a password file for "testuser" and "testpassword" -docker run --entrypoint htpasswd httpd:2.4 -Bbn testuser testpassword > auth/httpd.htpasswd -# Create another one for "testuserpush" and "testpasswordpush" -docker run --entrypoint htpasswd httpd:2.4 -Bbn testuserpush testpasswordpush >> auth/httpd.htpasswd - -# Create your group file -echo "pusher: testuserpush" > auth/httpd.groups - -# Copy over your certificate files -cp domain.crt auth -cp domain.key auth - -# Now create your compose file - -cat < docker-compose.yml -apache: - image: "httpd:2.4" - hostname: myregistrydomain.com - ports: - - 5043:5043 - links: - - registry:registry - volumes: - - `pwd`/auth:/usr/local/apache2/conf - -registry: - image: registry:2 - ports: - - 127.0.0.1:5000:5000 - volumes: - - `pwd`/data:/var/lib/registry - -EOF -``` - -## Starting and stopping - -Now, start your stack: - - ```console - $ docker compose up -d - ``` - -Sign in with a "push" authorized user (using `testuserpush` and `testpasswordpush`), then tag and push your first image: - - ```console - $ docker login myregistrydomain.com:5043 - $ docker tag ubuntu myregistrydomain.com:5043/test - $ docker push myregistrydomain.com:5043/test - ``` - -Now, sign in with a "pull-only" user (using `testuser` and `testpassword`), then pull back the image: - - ```console - $ docker login myregistrydomain.com:5043 - $ docker pull myregistrydomain.com:5043/test - ``` - -Verify that the "pull-only" can not push: - - ```console - $ docker push myregistrydomain.com:5043/test - ``` diff --git a/content/registry/recipes/nginx.md b/content/registry/recipes/nginx.md deleted file mode 100644 index d47d5f830e5..00000000000 --- a/content/registry/recipes/nginx.md +++ /dev/null @@ -1,213 +0,0 @@ ---- -description: Restricting access to your registry using a nginx proxy -keywords: registry, on-prem, images, tags, repository, distribution, nginx, proxy, - authentication, TLS, recipe, advanced -title: Authenticate proxy with nginx -aliases: -- /registry/nginx/ ---- - -{{< include "registry.md" >}} - -## Use-case - -People already relying on a nginx proxy to authenticate their users to other -services might want to leverage it and have Registry communications tunneled -through the same pipeline. - -Usually, that includes enterprise setups using LDAP/AD on the backend and a SSO -mechanism fronting their internal http portal. - -### Alternatives - -If you just want authentication for your registry, and are happy maintaining -users access separately, you should consider sticking with the native -[basic auth registry feature](../deploying.md#native-basic-auth). - -### Solution - -With the method presented here, you implement basic authentication for docker -engines in a reverse proxy that sits in front of your registry. - -While we use a simple `htpasswd` file as an example, any other nginx -authentication backend should be fairly easy to implement once you are done with -the example. - -We also implement push restriction (to a limited user group) for the sake of the -example. Again, you should modify this to fit your mileage. - -### Gotchas - -While this model gives you the ability to use whatever authentication backend -you want through the secondary authentication mechanism implemented inside your -proxy, it also requires that you move TLS termination from the Registry to the -proxy itself. - -> **Note** -> -> Docker does not recommend binding your registry to `localhost:5000` without -> authentication. This creates a potential loophole in your Docker Registry -> security. As a result, anyone who can sign on to the server where your Docker -> Registry is running can push images without authentication. - -Furthermore, introducing an extra http layer in your communication pipeline -makes it more complex to deploy, maintain, and debug. Make sure the extra -complexity is required. - -For instance, Amazon's Elastic Load Balancer (ELB) in HTTPS mode already sets -the following client header: - -``` -X-Real-IP -X-Forwarded-For -X-Forwarded-Proto -``` - -So if you have an Nginx instance sitting behind it, remove these lines from the following -example config: - -```none -proxy_set_header Host $http_host; # required for docker client's sake -proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Proto $scheme; -``` - -Otherwise Nginx resets the ELB's values, and the requests are not routed -properly. For more information, see -[#970](https://github.com/docker/distribution/issues/970). - -## Setting things up - -Review the [requirements](index.md#requirements), then follow these steps. - -1. Create the required directories - - ```console - $ mkdir -p auth data - ``` - -2. Create the main nginx configuration. Paste this code block into a new file called `auth/nginx.conf`: - - ```conf - events { - worker_connections 1024; - } - - http { - - upstream docker-registry { - server registry:5000; - } - - ## Set a variable to help us decide if we need to add the - ## 'Docker-Distribution-Api-Version' header. - ## The registry always sets this header. - ## In the case of nginx performing auth, the header is unset - ## since nginx is auth-ing before proxying. - map $upstream_http_docker_distribution_api_version $docker_distribution_api_version { - '' 'registry/2.0'; - } - - server { - listen 443 ssl; - server_name myregistrydomain.com; - - # SSL - ssl_certificate /etc/nginx/conf.d/domain.crt; - ssl_certificate_key /etc/nginx/conf.d/domain.key; - - # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html - ssl_protocols TLSv1.1 TLSv1.2; - ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - - # disable any limits to avoid HTTP 413 for large image uploads - client_max_body_size 0; - - # required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486) - chunked_transfer_encoding on; - - location /v2/ { - # Do not allow connections from docker 1.5 and earlier - # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents - if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { - return 404; - } - - # To add basic authentication to v2 use auth_basic setting. - auth_basic "Registry realm"; - auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd; - - ## If $docker_distribution_api_version is empty, the header is not added. - ## See the map directive above where this variable is defined. - add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always; - - proxy_pass http://docker-registry; - proxy_set_header Host $http_host; # required for docker client's sake - proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 900; - } - } - } - ``` - -3. Create a password file `auth/nginx.htpasswd` for "testuser" and "testpassword". - - ```console - $ docker run --rm --entrypoint htpasswd httpd:2 -Bbn testuser testpassword > auth/nginx.htpasswd - ``` - - > **Note** - > - > If you do not want to use `bcrypt`, you can omit the `-B` parameter. - -4. Copy your certificate files to the `auth/` directory. - - ```console - $ cp domain.crt auth - $ cp domain.key auth - ``` - -5. Create the compose file. Paste the following YAML into a new file called `docker-compose.yml`. - - ```yaml - nginx: - # Note : Only nginx:alpine supports bcrypt. - # If you don't need to use bcrypt, you can use a different tag. - # Ref. https://github.com/nginxinc/docker-nginx/issues/29 - image: "nginx:alpine" - ports: - - 5043:443 - links: - - registry:registry - volumes: - - ./auth:/etc/nginx/conf.d - - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro - - registry: - image: registry:2 - volumes: - - ./data:/var/lib/registry - ``` - -## Starting and stopping - -Now, start your stack: - - ```console - $ docker compose up -d - ``` - -Login with a "push" authorized user (using `testuser` and `testpassword`), then -tag and push your first image: - - ```console - $ docker login -u=testuser -p=testpassword -e=root@example.ch myregistrydomain.com:5043 - $ docker tag ubuntu myregistrydomain.com:5043/test - $ docker push myregistrydomain.com:5043/test - $ docker pull myregistrydomain.com:5043/test - ``` \ No newline at end of file diff --git a/content/registry/recipes/osx-setup-guide.md b/content/registry/recipes/osx-setup-guide.md deleted file mode 100644 index 53d52531682..00000000000 --- a/content/registry/recipes/osx-setup-guide.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -description: Explains how to run a registry on macOS -keywords: registry, on-prem, images, tags, repository, distribution, macOS, recipe, - advanced -title: macOS setup guide ---- - -{{< include "registry.md" >}} - -## Use-case - -This is useful if you intend to run a registry server natively on macOS. - -### Alternatives - -You can start a VM on macOS, and deploy your registry normally as a container using Docker inside that VM. - -### Solution - -Using the method described here, you install and compile your own from the git repository and run it as an macOS agent. - -### Gotchas - -Production services operation on macOS is out of scope of this document. Be sure you understand well these aspects before considering going to production with this. - -## Setup golang on your machine - -To set up golang on your machine, run: - -``` -bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer) -source ~/.gvm/scripts/gvm -gvm install go1.4.2 -gvm use go1.4.2 -``` - -See [How to Write Go Code](https://golang.org/doc/code.html), for more details. - -## Checkout the Docker Distribution source tree - -``` -mkdir -p $GOPATH/src/github.com/docker -git clone https://github.com/docker/distribution.git $GOPATH/src/github.com/docker/distribution -cd $GOPATH/src/github.com/docker/distribution -``` - -## Build the binary - -``` -GOPATH=$(PWD)/Godeps/_workspace:$GOPATH make binaries -sudo mkdir -p /usr/local/libexec -sudo cp bin/registry /usr/local/libexec/registry -``` - -## Setup - -Copy the registry configuration file in place: - -``` -mkdir /Users/Shared/Registry -cp docs/recipes/osx/config.yml /Users/Shared/Registry/config.yml -``` - -## Run the Docker Registry under launchd - -Copy the Docker registry plist into place: - -``` -plutil -lint docs/recipes/osx/com.docker.registry.plist -cp docs/recipes/osx/com.docker.registry.plist ~/Library/LaunchAgents/ -chmod 644 ~/Library/LaunchAgents/com.docker.registry.plist -``` - -Start the Docker registry: - -``` -launchctl load ~/Library/LaunchAgents/com.docker.registry.plist -``` - -### Restart the docker registry service - -``` -launchctl stop com.docker.registry -launchctl start com.docker.registry -``` - -### Unload the docker registry service - -``` -launchctl unload ~/Library/LaunchAgents/com.docker.registry.plist -``` \ No newline at end of file diff --git a/content/registry/recipes/osx/com.docker.registry.plist b/content/registry/recipes/osx/com.docker.registry.plist deleted file mode 100644 index 0982349f4d5..00000000000 --- a/content/registry/recipes/osx/com.docker.registry.plist +++ /dev/null @@ -1,42 +0,0 @@ - - - - - Label - com.docker.registry - KeepAlive - - StandardErrorPath - /Users/Shared/Registry/registry.log - StandardOutPath - /Users/Shared/Registry/registry.log - Program - /usr/local/libexec/registry - ProgramArguments - - /usr/local/libexec/registry - /Users/Shared/Registry/config.yml - - Sockets - - http-listen-address - - SockServiceName - 5000 - SockType - dgram - SockFamily - IPv4 - - http-debug-address - - SockServiceName - 5001 - SockType - dgram - SockFamily - IPv4 - - - - diff --git a/content/registry/recipes/osx/config.yml b/content/registry/recipes/osx/config.yml deleted file mode 100644 index 2677f824731..00000000000 --- a/content/registry/recipes/osx/config.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: 0.1 -log: - level: info - fields: - service: registry - environment: macbook-air -storage: - cache: - blobdescriptor: inmemory - filesystem: - rootdirectory: /Users/Shared/Registry -http: - addr: 0.0.0.0:5000 - secret: mytokensecret - debug: - addr: localhost:5001 diff --git a/content/registry/storage-drivers/_index.md b/content/registry/storage-drivers/_index.md deleted file mode 100644 index 32abb16da91..00000000000 --- a/content/registry/storage-drivers/_index.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -description: Explains how to use storage drivers -keywords: registry, on-prem, images, tags, repository, distribution, storage drivers, - advanced -title: Docker Registry storage driver -aliases: -- /registry/storagedrivers/ ---- - -{{< include "registry.md" >}} - -This document describes the registry storage driver model, implementation, and explains how to contribute new storage drivers. - -## Provided drivers - -This storage driver package comes bundled with several drivers: - -- [inmemory](inmemory.md): A temporary storage driver using a local inmemory map. This exists solely for reference and testing. -- [filesystem](filesystem.md): A local storage driver configured to use a directory tree in the local filesystem. -- [s3](s3.md): A driver storing objects in an Amazon Simple Storage Service (S3) bucket. -- [azure](azure.md): A driver storing objects in [Microsoft Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/). -- [swift](swift.md): A driver storing objects in [Openstack Swift](https://docs.openstack.org/swift/latest/). -- [oss](oss.md): A driver storing objects in [Aliyun OSS](https://www.aliyun.com/product/oss). -- [gcs](gcs.md): A driver storing objects in a [Google Cloud Storage](https://cloud.google.com/storage/) bucket. - -## Storage driver API - -The storage driver API is designed to model a filesystem-like key/value storage in a manner abstract enough to support a range of drivers from the local filesystem to Amazon S3 or other distributed object storage systems. - -Storage drivers are required to implement the `storagedriver.StorageDriver` interface provided in `storagedriver.go`, which includes methods for reading, writing, and deleting content, as well as listing child objects of a specified prefix key. - -Storage drivers are intended to be written in Go, providing compile-time -validation of the `storagedriver.StorageDriver` interface. - -## Driver selection and configuration - -The preferred method of selecting a storage driver is using the `StorageDriverFactory` interface in the `storagedriver/factory` package. These factories provide a common interface for constructing storage drivers with a parameters map. The factory model is based on the [Register](https://golang.org/pkg/database/sql/#Register) and [Open](https://golang.org/pkg/database/sql/#Open) methods in the builtin [database/sql](https://golang.org/pkg/database/sql) package. - -Storage driver factories may be registered by name using the -`factory.Register` method, and then later invoked by calling `factory.Create` -with a driver name and parameters map. If no such storage driver can be found, -`factory.Create` returns an `InvalidStorageDriverError`. - -## Driver contribution - -### Writing new storage drivers - -To create a valid storage driver, one must implement the -`storagedriver.StorageDriver` interface and make sure to expose this driver -via the factory system. - -#### Registering - -Storage drivers should call `factory.Register` with their driver name in an `init` method, allowing callers of `factory.New` to construct instances of this driver without requiring modification of imports throughout the codebase. - -## Testing - -Storage driver test suites are provided in -`storagedriver/testsuites/testsuites.go` and may be used for any storage -driver written in Go. Tests can be registered using the `RegisterSuite` -function, which run the same set of tests for any registered drivers. \ No newline at end of file diff --git a/content/registry/storage-drivers/azure.md b/content/registry/storage-drivers/azure.md deleted file mode 100644 index fe2b2f093e5..00000000000 --- a/content/registry/storage-drivers/azure.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: Explains how to use the Azure storage drivers -keywords: registry, service, driver, images, storage, azure -title: Microsoft Azure storage driver ---- - -{{< include "registry.md" >}} - -An implementation of the `storagedriver.StorageDriver` interface which uses [Microsoft Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/) for object storage. - -## Parameters - -| Parameter | Required | Description | -|:--------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `accountname` | yes | Name of the Azure Storage Account. | -| `accountkey` | yes | Primary or Secondary Key for the Storage Account. | -| `container` | yes | Name of the Azure root storage container in which all registry data is stored. Must comply the storage container name [requirements](https://docs.microsoft.com/rest/api/storageservices/fileservices/naming-and-referencing-containers--blobs--and-metadata). For example, if your url is `https://myaccount.blob.core.windows.net/myblob` use the container value of `myblob`.| -| `realm` | no | Domain name suffix for the Storage Service API endpoint. For example realm for "Azure in China" would be `core.chinacloudapi.cn` and realm for "Azure Government" would be `core.usgovcloudapi.net`. By default, this is `core.windows.net`. | - - -## Related information - -* To get information about -[azure-blob-storage](https://azure.microsoft.com/en-us/services/storage/), visit -the Microsoft website. -* You can use Microsoft's [Blob Service REST API](https://docs.microsoft.com/en-us/rest/api/storageservices/Blob-Service-REST-API) to [create a storage container](https://docs.microsoft.com/en-us/rest/api/storageservices/Create-Container). \ No newline at end of file diff --git a/content/registry/storage-drivers/filesystem.md b/content/registry/storage-drivers/filesystem.md deleted file mode 100644 index 6274157203b..00000000000 --- a/content/registry/storage-drivers/filesystem.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -description: Explains how to use the filesystem storage drivers -keywords: registry, service, driver, images, storage, filesystem -title: Filesystem storage driver ---- - -{{< include "registry.md" >}} - -An implementation of the `storagedriver.StorageDriver` interface which uses the local filesystem. - -## Parameters - -* `rootdirectory`: (optional) The absolute path to a root directory tree in which -to store all registry files. The registry stores all its data here so make sure -there is adequate space available. Defaults to `/var/lib/registry`. If the directory -does not exist, it will be created honoring [`umask`](https://man7.org/linux/man-pages/man2/umask.2.html) -bits. If `umask` bits are not set, the resulting permission will be `0777`. -* `maxthreads`: (optional) The maximum number of simultaneous blocking filesystem -operations permitted within the registry. Each operation spawns a new thread and -may cause thread exhaustion issues if many are done in parallel. Defaults to -`100`, and cannot be lower than `25`. \ No newline at end of file diff --git a/content/registry/storage-drivers/gcs.md b/content/registry/storage-drivers/gcs.md deleted file mode 100644 index f2af289829b..00000000000 --- a/content/registry/storage-drivers/gcs.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -description: Explains how to use the Google Cloud Storage drivers -keywords: registry, service, driver, images, storage, gcs, google, cloud -title: Google Cloud Storage driver ---- - -{{< include "registry.md" >}} - -An implementation of the `storagedriver.StorageDriver` interface which uses Google Cloud for object storage. - -## Parameters - -| Parameter | Required | Description | -|:--------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `bucket` | yes | The name of your Google Cloud Storage bucket where you wish to store objects (needs to already be created prior to driver initialization). | -| `keyfile` | no | A private service account key file in JSON format used for [Service Account Authentication](https://cloud.google.com/storage/docs/authentication#service_accounts). | -| `rootdirectory` | no | The root directory tree in which all registry files are stored. Defaults to the empty string (bucket root). If a prefix is used, the path `bucketname/` has to be pre-created before starting the registry. The prefix is applied to all Google Cloud Storage keys to allow you to segment data in your bucket if necessary.| -| `chunksize` | no (default 5242880) | This is the chunk size used for uploading large blobs, must be a multiple of 256*1024. | - -**Note:** Instead of a key file you can use [Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). \ No newline at end of file diff --git a/content/registry/storage-drivers/inmemory.md b/content/registry/storage-drivers/inmemory.md deleted file mode 100644 index 3768127c917..00000000000 --- a/content/registry/storage-drivers/inmemory.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Explains how to use the in-memory storage drivers -keywords: registry, service, driver, images, storage, in-memory -title: In-memory storage driver (testing only) ---- - -{{< include "registry.md" >}} - -For purely tests purposes, you can use the `inmemory` storage driver. This -driver is an implementation of the `storagedriver.StorageDriver` interface which -uses local memory for object storage. If you would like to run a registry from -volatile memory, use the [`filesystem` driver](filesystem.md) on a ramdisk. - -**IMPORTANT**: This storage driver *does not* persist data across runs. This is why it is only suitable for testing. *Never* use this driver in production. - -## Parameters - -None \ No newline at end of file diff --git a/content/registry/storage-drivers/oss.md b/content/registry/storage-drivers/oss.md deleted file mode 100644 index d2b0ce65f1c..00000000000 --- a/content/registry/storage-drivers/oss.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -description: Explains how to use the Aliyun OSS storage driver -keywords: registry, service, driver, images, storage, OSS, aliyun -title: Aliyun OSS storage driver ---- - -{{< include "registry.md" >}} - -An implementation of the `storagedriver.StorageDriver` interface which uses -[Aliyun OSS](https://www.alibabacloud.com/product/oss) for object storage. - -## Parameters - -| Parameter | Required | Description | -|:--------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `accesskeyid` | yes | Your access key ID. | -| `accesskeysecret` | yes | Your access key secret. | -| `region` | yes | The name of the OSS region in which you would like to store objects (for example oss-cn-beijing). For a list of regions, you can look at the [official documentation](https://www.alibabacloud.com/help/doc-detail/31837.html). | -| `endpoint` | no | An endpoint which defaults to `[bucket].[region].aliyuncs.com` or `[bucket].[region]-internal.aliyuncs.com` (when `internal=true`). You can change the default endpoint by changing this value. | -| `internal` | no | An internal endpoint or the public endpoint for OSS access. The default is false. For a list of regions, you can look at the [official documentation](https://www.alibabacloud.com/help/doc-detail/31837.html). | -| `bucket` | yes | The name of your OSS bucket where you wish to store objects (needs to already be created prior to driver initialization). | -| `encrypt` | no | Specifies whether you would like your data encrypted on the server side. Defaults to false if not specified. | -| `secure` | no | Specifies whether to transfer data to the bucket over ssl or not. If you omit this value, `true` is used. | -| `chunksize` | no | The default part size for multipart uploads (performed by WriteStream) to OSS. The default is 10 MB. Keep in mind that the minimum part size for OSS is 5MB. You might experience better performance for larger chunk sizes depending on the speed of your connection to OSS. | -| `rootdirectory` | no | The root directory tree in which to store all registry files. Defaults to an empty string (bucket root). | \ No newline at end of file diff --git a/content/registry/storage-drivers/s3.md b/content/registry/storage-drivers/s3.md deleted file mode 100644 index a71c3f2dbc7..00000000000 --- a/content/registry/storage-drivers/s3.md +++ /dev/null @@ -1,161 +0,0 @@ ---- -description: Explains how to use the S3 storage drivers -keywords: registry, service, driver, images, storage, S3 -title: S3 storage driver ---- - -{{< include "registry.md" >}} - -An implementation of the `storagedriver.StorageDriver` interface which uses -Amazon S3 or S3 compatible services for object storage. - -## Parameters - -| Parameter | Required | Description | -|:--------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `accesskey` | no | Your AWS Access Key. If you use [IAM roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html), omit to fetch temporary credentials from IAM. | -| `secretkey` | no | Your AWS Secret Key. If you use [IAM roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html), omit to fetch temporary credentials from IAM. | -| `region` | yes | The AWS region in which your bucket exists. For the moment, the Go AWS library in use does not use the newer DNS based bucket routing. | -| `regionendpoint` | no | Endpoint for S3 compatible storage services (Minio, etc). | -| `bucket` | yes | The bucket name in which you want to store the registry's data. | -| `encrypt` | no | Specifies whether the registry stores the image in encrypted format or not. A boolean value. The default is `false`. | -| `keyid` | no | Optional KMS key ID to use for encryption (encrypt must be true, or this parameter is ignored). The default is `none`. | -| `secure` | no | Indicates whether to use HTTPS instead of HTTP. A boolean value. The default is `true`. | -| `skipverify` | no | Skips TLS verification when the value is set to `true`. The default is `false`. | -| `v4auth` | no | Indicates whether the registry uses Version 4 of AWS's authentication. The default is `true`. | -| `chunksize` | no | The S3 API requires multipart upload chunks to be at least 5MB. This value should be a number that is larger than 5 * 1024 * 1024.| -| `rootdirectory` | no | This is a prefix that is applied to all S3 keys to allow you to segment data in your bucket if necessary. | -| `storageclass` | no | The S3 storage class applied to each registry file. The default is `STANDARD`. | -| `accelerate` | no | Specifies whether the registry should use S3 Transfer Acceleration. You must enable acceleration endpoint on a bucket before using this option. A boolean value. The default is `false`. | - -> **Note** You can provide empty strings for your access and secret keys to run the driver -> on an ec2 instance and handles authentication with the instance's credentials. If you -> use [IAM roles](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html), -> omit these keys to fetch temporary credentials from IAM. - -`region`: The name of the aws region in which you would like to store objects (for example `us-east-1`). For a list of regions, see [Regions, Availability Zones, and Local Zones](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html). - -`regionendpoint`: (optional) Endpoint URL for S3 compatible APIs. This should not be provided when using Amazon S3. - -`bucket`: The name of your S3 bucket where you wish to store objects. The bucket must exist prior to the driver initialization. - -`encrypt`: (optional) Whether you would like your data encrypted on the server side (defaults to false if not specified). - -`keyid`: (optional) Whether you would like your data encrypted with this KMS key ID (defaults to none if not specified, is ignored if encrypt is not true). - -`secure`: (optional) Whether you would like to transfer data to the bucket over ssl or not. Defaults to true (meaning transferring over ssl) if not specified. While setting this to false improves performance, it is not recommended due to security concerns. - -`v4auth`: (optional) Whether you would like to use aws signature version 4 with your requests. This defaults to `false` if not specified. The `eu-central-1` region does not work with version 2 signatures, so the driver errors out if initialized with this region and v4auth set to `false`. - -`chunksize`: (optional) The default part size for multipart uploads (performed by WriteStream) to S3. The default is 10 MB. Keep in mind that the minimum part size for S3 is 5MB. Depending on the speed of your connection to S3, a larger chunk size may result in better performance; faster connections benefit from larger chunk sizes. - -`rootdirectory`: (optional) The root directory tree in which all registry files are stored. Defaults to the empty string (bucket root). - -`storageclass`: (optional) The storage class applied to each registry file. Defaults to STANDARD. Valid options are STANDARD and REDUCED_REDUNDANCY. - -`accelerate`: (optional) Whether you would like to use accelerate endpoint for communication with S3. You must enable acceleration on a bucket before using this option. For details on how to enable the accelerate option, see [Amazon S3 Transfer Acceleration](https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html). - -## S3 permission scopes - -The following AWS policy is required by the registry for push and pull. Make sure to replace `S3_BUCKET_NAME` with the name of your bucket. - -``` -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "s3:ListBucket", - "s3:GetBucketLocation", - "s3:ListBucketMultipartUploads" - ], - "Resource": "arn:aws:s3:::S3_BUCKET_NAME" - }, - { - "Effect": "Allow", - "Action": [ - "s3:PutObject", - "s3:GetObject", - "s3:DeleteObject", - "s3:ListMultipartUploadParts", - "s3:AbortMultipartUpload" - ], - "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*" - } - ] -} -``` - -See [the S3 policy documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) for more details. - -# CloudFront as Middleware with S3 backend - -## Use Case - -Adding CloudFront as a middleware for your S3 backed registry can dramatically -improve pull times. Your registry can retrieve your images -from edge servers, rather than the geographically limited location of your S3 -bucket. The farther your registry is from your bucket, the more improvements are -possible. See [Amazon CloudFront](https://aws.amazon.com/cloudfront/details/). - -An alternative method for CloudFront that requires less configuration and will use -the same edge servers is [S3 Transfer Acceleration](https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html). -Please check acceleration [Requirements](https://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html#transfer-acceleration-requirements) -to see whether you need CloudFront or S3 Transfer Acceleration. - -## Configuring CloudFront for Distribution - -If you are unfamiliar with creating a CloudFront distribution, see [Getting -Started with -Cloudfront](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html). - -Defaults can be kept in most areas except: - -### Origin: - - - The CloudFront distribution must be created such that the `Origin Path` is set - to the directory level of the root "docker" key in S3. If your registry exists - on the root of the bucket, this path should be left blank. - - - For private S3 buckets, you must set `Restrict Bucket Access` to `Yes`. See - the [CloudFront documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html). - - -### Behaviors: - - - Viewer Protocol Policy: HTTPS Only - - Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE - - Cached HTTP Methods: OPTIONS (checked) - - Restrict Viewer Access (Use Signed URLs or Signed Cookies): Yes - - Trusted Signers: Self (Can add other accounts as long as you have access to CloudFront Key Pairs for those additional accounts) - -## Registry configuration - -Here the `middleware` option is used. It is still important to keep the -`storage` option, because CloudFront only handles `pull` actions; `push` actions -are still directly written to S3. - -The following example shows a minimum configuration: - -```yaml -... -storage: - s3: - region: us-east-1 - bucket: docker.myregistry.com -middleware: - storage: - - name: cloudfront - options: - baseurl: https://abcdefghijklmn.cloudfront.net/ - privatekey: /etc/docker/cloudfront/pk-ABCEDFGHIJKLMNOPQRST.pem - keypairid: ABCEDFGHIJKLMNOPQRST -... -``` - -## CloudFront Key-Pair - -A CloudFront key-pair is required for all AWS accounts needing access to your -CloudFront distribution. You must have access to your AWS account's root credentials to create the required Cloudfront keypair. For information, see [Creating CloudFront Key -Pairs](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html#private-content-creating-cloudfront-key-pairs). \ No newline at end of file diff --git a/content/registry/storage-drivers/swift.md b/content/registry/storage-drivers/swift.md deleted file mode 100644 index 6d52213460c..00000000000 --- a/content/registry/storage-drivers/swift.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -description: Explains how to use the OpenStack swift storage driver -keywords: registry, service, driver, images, storage, swift -title: OpenStack Swift storage driver ---- - -{{< include "registry.md" >}} - -An implementation of the `storagedriver.StorageDriver` interface that uses -[OpenStack Swift](http://docs.openstack.org/developer/swift/) for object -storage. - -## Parameters - -| Parameter | Required | Description | -|:--------------|:---------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `authurl` | yes | URL for obtaining an auth token. https://storage.myprovider.com/v2.0 or https://storage.myprovider.com/v3/auth | -| `username` | yes | Your Openstack user name. | -| `password` | yes | Your Openstack password. | -| `region` | no | The Openstack region in which your container exists. | -| `container` | yes | The name of your Swift container where you wish to store the registry's data. The driver creates the named container during its initialization. | -| `tenant` | no | Your Openstack tenant name. You can either use `tenant` or `tenantid`. | -| `tenantid` | no | Your Openstack tenant name. You can either use `tenant` or `tenantid`. | -| `domain` | no | Your Openstack domain name for Identity v3 API. You can either use `domain` or `domainid`. | -| `domainid` | no | Your Openstack domain name for Identity v3 API. You can either use `domain` or `domainid`. | -| `trustid` | no | Your Openstack trust ID for Identity v3 API. | -| `insecureskipverify` | no | Skips TLS verification if the value is wet to `true`. The default is `false`. | -| `chunksize` | no | Size of the data segments for the Swift Dynamic Large Objects. This value should be a number (defaults to 5M). | -| `prefix` | no | This is a prefix that is applied to all Swift keys to allow you to segment data in your container if necessary. Defaults to the empty string which is the container's root. | -| `secretkey` | no | The secret key used to generate temporary URLs. | -| `accesskey` | no | The access key to generate temporary URLs. It is used by HP Cloud Object Storage in addition to the `secretkey` parameter. | -| `authversion` | no | Specify the OpenStack Auth's version, for example `3`. By default the driver autodetects the auth's version from the AuthURL. | -| `endpointtype` | no | The endpoint type used when connecting to swift. Possible values are `public`, `internal`, and `admin`. The default is `public`. | - -The features supported by the Swift server are queried by requesting the `/info` -URL on the server. In case the administrator disabled that feature, the -configuration file can specify the following optional parameters : - -| Optional parameter | Description | -|:--------------|:---------| -| `tempurlcontainerkey` | Specify whether to use container secret key to generate temporary URL when set to true, or the account secret key otherwise. | -| `tempurlmethods` | Array of HTTP methods that are supported by the TempURL middleware of the Swift server. For example: `["GET", "PUT", "HEAD", "POST", "DELETE"]` | \ No newline at end of file diff --git a/data/toc.yaml b/data/toc.yaml index d17ea4d47b8..4d81225a572 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -891,8 +891,6 @@ Reference: path: /docker-hub/api/dvp/ - title: Deprecated API path: /docker-hub/api/deprecated/ - - title: Registry API - path: /registry/spec/api/ - sectiontitle: Docker Extension SDK API section: - path: /desktop/extensions-sdk/dev/api/reference/interfaces/DesktopUI/ @@ -993,46 +991,6 @@ Reference: title: Version 3 - path: /compose/compose-file/compose-file-v2/ title: Version 2 -- sectiontitle: Drivers and specifications - section: - - sectiontitle: Registry image manifests - section: - - path: /registry/spec/manifest-v2-1/ - title: Image manifest v 2, schema 1 - - path: /registry/spec/manifest-v2-2/ - title: Image manifest v 2, schema 2 - - path: /registry/spec/deprecated-schema-v1/ - title: Update deprecated schema v1 images - - sectiontitle: Registry token authorization - section: - - path: /registry/spec/auth/ - title: Docker Registry token authentication - - path: /registry/spec/auth/jwt/ - title: Token authentication implementation - - path: /registry/spec/auth/oauth/ - title: Oauth2 token authentication - - path: /registry/spec/auth/scope/ - title: Token scope documentation - - path: /registry/spec/auth/token/ - title: Token authentication specification - - sectiontitle: Registry storage drivers - section: - - path: /registry/storage-drivers/ - title: Storage driver overview - - path: /registry/storage-drivers/oss/ - title: Aliyun OSS storage driver - - path: /registry/storage-drivers/filesystem/ - title: Filesystem storage driver - - path: /registry/storage-drivers/gcs/ - title: GCS storage driver - - path: /registry/storage-drivers/inmemory/ - title: In-memory storage driver - - path: /registry/storage-drivers/azure/ - title: Microsoft Azure storage driver - - path: /registry/storage-drivers/s3/ - title: S3 storage driver - - path: /registry/storage-drivers/swift/ - title: Swift storage driver - path: /glossary/ title: Glossary @@ -2210,43 +2168,6 @@ Manuals: - path: /trusted-content/insights-analytics/ title: Insights and analytics -- sectiontitle: Open-source projects - section: - - sectiontitle: Docker Registry - section: - - path: /registry/ - title: Registry overview - - path: /registry/introduction/ - title: Understand the Registry - - path: /registry/deploying/ - title: Deploy a registry server - - path: /registry/configuration/ - title: Configure a registry - - path: /registry/notifications/ - title: Work with notifications - - sectiontitle: Recipes - section: - - path: /registry/recipes/ - title: Recipes overview - - path: /registry/recipes/apache/ - title: Authenticating proxy with apache - - path: /registry/recipes/nginx/ - title: Authenticating proxy with nginx - - path: /registry/recipes/mirror/ - title: Mirroring Docker Hub - - path: /registry/recipes/osx-setup-guide/ - title: Running on macOS - - path: /registry/garbage-collection/ - title: Garbage collection - - path: /registry/insecure/ - title: Testing an insecure registry - - path: /registry/deprecated/ - title: Deprecated features - - path: /registry/compatibility/ - title: Compatibility - - path: /registry/help/ - title: Getting help - - path: /release-notes/ title: Release notes - path: /support/ diff --git a/go.mod b/go.mod index c0a56190e08..bebbe5d7973 100644 --- a/go.mod +++ b/go.mod @@ -6,18 +6,13 @@ toolchain go1.21.1 require ( github.com/compose-spec/compose-spec v0.0.0-20230927132538-f223c5150d5d // indirect - github.com/distribution/distribution v2.8.4-0.20231004140828-d607c6ccb937+incompatible // indirect - github.com/distribution/reference v0.5.0 // indirect github.com/docker/buildx v0.11.2 // indirect github.com/docker/cli v24.0.6+incompatible // indirect github.com/docker/compose-cli v1.0.35 // indirect github.com/docker/compose/v2 v2.22.0 // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/scout-cli v1.0.2 // indirect github.com/moby/buildkit v0.13.0-beta1.0.20231011101155-c444964c2e8f // indirect github.com/moby/moby v24.0.5+incompatible // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect ) exclude github.com/cucumber/godog v0.0.0-00010101000000-000000000000 diff --git a/hugo.yaml b/hugo.yaml index dbbaebdfc12..fc9c7a2ae70 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -296,18 +296,6 @@ module: - source: docs/ecs-compose-features.md target: content/cloud/ecs-compose-features.md - - path: github.com/distribution/distribution - mounts: - - source: docs - target: content/registry - excludeFiles: - - "**/index.md" - - "**/api.md.tmpl" - - source: docs/spec/index.md - target: content/registry/spec/_index.md - - source: docs/spec/auth/index.md - target: content/registry/spec/auth/_index.md - - path: github.com/compose-spec/compose-spec mounts: - source: 01-status.md