diff --git a/README.md b/README.md index 77ccf7b2a..fcb470c85 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This repository contains the following components: | **libraries** | A rich set of libraries for interacting with,distribution components. Please see [godoc](http://godoc.org/github.com/docker/distribution) for details. **Note**: These libraries are **unstable**. | | **dist** | An _experimental_ tool to provide distribution, oriented functionality without the `docker` daemon. | | **specifications** | _Distribution_ related specifications are available in [docs/spec](docs/spec) | -| **documentation** | Documentation is available in [doc](http://docs.docker.com/distribution). | +| **documentation** | Docker's full documentation set is available at [docs.docker.com](http://docs.docker.com). This repository [contains the subset](docs/overview.md) related just to the registry. | ### How does this integrate with Docker engine? diff --git a/contrib/compose/README.md b/contrib/compose/README.md index e6f618150..a9522fd24 100644 --- a/contrib/compose/README.md +++ b/contrib/compose/README.md @@ -1,23 +1,147 @@ # Docker Compose V1 + V2 registry -This compose configuration will setup a v1 and v2 registry behind an nginx -proxy. By default the combined registry may be accessed at localhost:5000. -This registry does not support pushing images to v2 and pull from v1. Clients -from before 1.6 will be configured to use the v1 registry, and newer clients -will use the v2 registry. +This compose configuration configures a `v1` and `v2` registry behind an `nginx` +proxy. By default, you can access the combined registry at `localhost:5000`. -## Prerequisites -Install [docker-compose](https://github.com/docker/compose) +The configuration does not support pushing images to `v2` and pulling from `v1`. +If a `docker` client has a version less than 1.6, Nginx will route its requests +to the 1.0 registry. Requests from newer clients will route to the 2.0 registry. -## How to run -``` -$ docker-compose up -``` +### Install Docker Compose + +1. Open a new terminal on the host with your `distribution` source. + +2. Get the `docker-compose` binary. + + $ sudo wget https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` -O /usr/local/bin/docker-compose + + This command installs the binary in the `/usr/local/bin` directory. + +3. Add executable permissions to the binary. + + $ sudo chmod +x /usr/local/bin/docker-compose + +## Build and run with Compose + +1. In your terminal, navigate to the `distribution/contrib/compose` directory + + This directory includes a single `docker-compose.yml` configuration. + + nginx: + build: "nginx" + ports: + - "5000:5000" + links: + - registryv1:registryv1 + - registryv2:registryv2 + registryv1: + image: registry + ports: + - "5000" + registryv2: + build: "../../" + ports: + - "5000" + + This configuration builds a new `nginx` image as specified by the + `nginx/Dockerfile` file. The 1.0 registry comes from Docker's official + public image. Finally, the registry 2.0 image is built from the + `distribution/Dockerfile` you've used previously. + +2. Get a registry 1.0 image. + + $ docker pull registry:0.9.1 + + The Compose configuration looks for this image locally. If you don't do this + step, later steps can fail. + +3. Build `nginx`, the registry 2.0 image, and + + $ docker-compose build + registryv1 uses an image, skipping + Building registryv2... + Step 0 : FROM golang:1.4 + + ... + + Removing intermediate container 9f5f5068c3f3 + Step 4 : COPY docker-registry-v2.conf /etc/nginx/docker-registry-v2.conf + ---> 74acc70fa106 + Removing intermediate container edb84c2b40cb + Successfully built 74acc70fa106 + + The commmand outputs its progress until it completes. + +4. Start your configuration with compose. + + $ docker-compose up + Recreating compose_registryv1_1... + Recreating compose_registryv2_1... + Recreating compose_nginx_1... + Attaching to compose_registryv1_1, compose_registryv2_1, compose_nginx_1 + ... + + +5. In another terminal, display the running configuration. + + $ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + a81ad2557702 compose_nginx:latest "nginx -g 'daemon of 8 minutes ago Up 8 minutes 80/tcp, 443/tcp, 0.0.0.0:5000->5000/tcp compose_nginx_1 + 0618437450dd compose_registryv2:latest "registry cmd/regist 8 minutes ago Up 8 minutes 0.0.0.0:32777->5000/tcp compose_registryv2_1 + aa82b1ed8e61 registry:latest "docker-registry" 8 minutes ago Up 8 minutes 0.0.0.0:32776->5000/tcp compose_registryv1_1 + +### Explore a bit + +1. Check for TLS on your `nginx` server. + + $ curl -v https://localhost:5000 + * Rebuilt URL to: https://localhost:5000/ + * Hostname was NOT found in DNS cache + * Trying 127.0.0.1... + * Connected to localhost (127.0.0.1) port 5000 (#0) + * successfully set certificate verify locations: + * CAfile: none + CApath: /etc/ssl/certs + * SSLv3, TLS handshake, Client hello (1): + * SSLv3, TLS handshake, Server hello (2): + * SSLv3, TLS handshake, CERT (11): + * SSLv3, TLS alert, Server hello (2): + * SSL certificate problem: self signed certificate + * Closing connection 0 + curl: (60) SSL certificate problem: self signed certificate + More details here: http://curl.haxx.se/docs/sslcerts.html + +2. Tag the `v1` registry image. + + $ docker tag registry:latest localhost:5000/registry_one:latest + +2. Push it to the localhost. + + $ docker push localhost:5000/registry_one:latest + + If you are using the 1.6 Docker client, this pushes the image the `v2 `registry. + +4. Use `curl` to list the image in the registry. + + $ curl -v -X GET http://localhost:32777/v2/registry1/tags/list + * Hostname was NOT found in DNS cache + * Trying 127.0.0.1... + * Connected to localhost (127.0.0.1) port 32777 (#0) + > GET /v2/registry1/tags/list HTTP/1.1 + > User-Agent: curl/7.36.0 + > Host: localhost:32777 + > Accept: */* + > + < HTTP/1.1 200 OK + < Content-Type: application/json; charset=utf-8 + < Docker-Distribution-Api-Version: registry/2.0 + < Date: Tue, 14 Apr 2015 22:34:13 GMT + < Content-Length: 39 + < + {"name":"registry1","tags":["latest"]} + * Connection #0 to host localhost left intact + + This example refers to the specific port assigned to the 2.0 registry. You saw + this port earlier, when you used `docker ps` to show your running containers. -## How to push images -From a local project directory with Dockerfile -``` -$ docker build -t localhost:5000/myimage . -$ docker push localhost:5000/myimage -``` diff --git a/docs/configuration.md b/docs/configuration.md index 933474b20..bf40238c1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -3,41 +3,17 @@ page_description: Explains how to deploy a registry service page_keywords: registry, service, images, repository -# Configure a Registry +# Registry Configuration Reference -The registry server can be configured with a YAML file. This section provides a -simple example and a complete reference. +You configure a registry server using a YAML file. This page explains the +configuration options and the values they can take. You'll also find examples of +middleware and development environment configurations. -## A simple development configuration +## List of configuration options -The following is a simple example that can used for local development: - -```yaml -version: 0.1 -log: - level: debug -storage: - filesystem: - rootdirectory: /tmp/registry-dev -http: - addr: localhost:5000 - secret: asecretforlocaldevelopment - debug: - addr: localhost:5001 -``` - -The above configures the registry instance to run on port 5000, binding to -"localhost", with the debug server enabled. Registry data will be stored in -"/tmp/registry-dev". Logging will be in "debug" mode, which is the most -verbose. - -A similar simple configuration is available at -[config.yml](https://github.com/docker/distribution/blob/master/cmd/registry/config.yml), which is generally useful for local development. - - -## Configuration Reference - -Below is a comprehensive example of all possible configuration options for the registry. Some options are mutually exclusive, and each section is explained in more detail below, but this is a good starting point from which you may delete the sections you do not need to create your own configuration. A copy of this configuration can be found at config.sample.yml. +This section lists all the registry configuration options. Some options in +the list are mutually exclusive. So, make sure to read the detailed reference +information about each option that appears later in this page. ```yaml version: 0.1 @@ -100,6 +76,7 @@ reporting: newrelic: licensekey: newreliclicensekey name: newrelicname + verbose: true http: addr: localhost:5000 prefix: /my/nested/registry/ @@ -134,7 +111,10 @@ redis: idletimeout: 300s ``` -N.B. In some instances a configuration option may be marked **optional** but contain child options marked as **required**. This indicates that a parent may be omitted with all its children, however, if the parent is included, the children marked **required** must be included. +In some instances a configuration option is **optional** but it contains child +options marked as **required**. This indicates that 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 @@ -142,15 +122,15 @@ N.B. In some instances a configuration option may be marked **optional** but con version: 0.1 ``` -The version option is **required** and indicates the version of the configuration being used. It is expected to remain a top-level field, to allow for a consistent version check before parsing the remainder of the configuration file. - -N.B. The version of the registry software may be found at [/version/version.go](https://github.com/docker/distribution/blob/master/version/version.go) +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. The granularity and format of the log -messages can be adjusted with this configuration section. +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. ```yaml log: @@ -161,14 +141,52 @@ log: environment: staging ``` -- level: **Optional** - Sets the sensitivity of logging output. Permitted - values are `error`, `warn`, `info` and `debug`. The default is `info`. -- formatter: **Optional** - This selects the format of logging output, which - mostly affects how keyed attributes for a log line are encoded. Options are - "text", "json" or "logstash". The default is "text". -- fields: **Optional** - A map of field names to values that will be added to - every log line for the context. This is useful for identifying log messages - source after being mixed in other systems. + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ 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 or + 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. +
+ ## loglevel @@ -205,45 +223,193 @@ storage: layerinfo: inmemory ``` -The storage option is **required** and defines which storage backend is in use. At the moment only one backend may be configured, an error is returned when the registry is started with more than one storage backend configured. +The storage option is **required** and defines which storage backend is in use. +You must configure one backend; if you configure more, the registry returns an error. -A `cache` subsection can be used to enable caching of data accessed in the -storage backend. Currently, the only available cache provides fast access to -layer metadata. This if configured using the `layerinfo` field. The following -cache implementations are available: +### cache -- redis: using the redis pool to cache layer meta data. -- inmemory: use an in memory map to cache layer meta data. +Use the `cache` subsection to enable caching of data accessed in the storage +backend. Currently, the only available cache provides fast access to layer +metadata. This, if configured, uses the `layerinfo` field. -The following backends may be configured, **all options for a given storage backend are required**: +You can set `layerinfo` field to `redis` or `inmemory`. The `redis` value uses +a Redis pool to cache layer metadata. The `inmemory` value uses an in memory +map. ### filesystem -This storage backend uses the local disk to store registry files. It is ideal for development and may be appropriate for some small scale production applications. +The `filesystem` storage backend uses the local disk to store registry files. It +is ideal for development and may be appropriate for some small-scale production +applications. -- rootdirectory: **Required** - This is the absolute path to directory in which the repository will store data. +This backend has a single, required `rootdirectory` parameter. The parameter +specifies the absolute path to a directory. The registry stores all its data +here so make sure there is adequate space available. ### azure This storage backend uses Microsoft's Azure Storage platform. -- accountname: **Required** - Azure account name -- accountkey: **Required** - Azure account key -- container: **Required** - Name of the Azure container into which data will be stored + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ accountname + + yes + + Azure account name. +
+ accountkey + + yes + + Azure account key. +
+ container + + yes + + Name of the Azure container into which to store data. +
+ + ### S3 -This storage backend uses Amazon's Simple Storage Service (a.k.a. S3). +This storage backend uses Amazon's Simple Storage Service (S3). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ accesskey + + yes + + Your AWS Access Key. +
+ secretkey + + yes + + Your AWS Secret Key. +
+ 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. +
+ 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. +
+ secure + + no + + Indicates whether to use HTTPS instead of HTTP. A boolean value. The + default is false. +
+ v4auth + + no + + Indicates whether the registry uses Version 4 of AWS's authentication. + Generally, you should set this to true. By default, this is + false. +
+ 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 will be applied to all S3 keys to allow you to segment data in your bucket if necessary. +
-- accesskey: **Required** - Your AWS Access Key -- secretkey: **Required** - Your AWS Secret Key. -- region: **Required** - 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. -- bucket: **Required** - The bucket name in which you want to store the registry's data. -- encrypt: TODO: fill in description -- secure: TODO: fill in description -- v4auth: This indicates whether Version 4 of AWS's authentication should be used. Generally you will want to set this to true. -- chunksize: TODO: fill in description -- rootdirectory: **Optional** - This is a prefix that will be applied to all S3 keys to allow you to segment data in your bucket if necessary. ## auth @@ -259,33 +425,126 @@ auth: rootcertbundle: /root/certs/bundle ``` -The auth option is **optional** as there are use cases (i.e. a mirror that only permits pulls) for which authentication may not be desired. There are currently 2 possible auth providers, "silly" and "token", only one auth provider may be configured at the moment: +The `auth` option is **optional** as there are use cases (i.e. a mirror that +only permits pulls) for which authentication may not be desired. There are +currently 2 possible auth providers, `silly` and `token`. You can configure only +one `auth` provider. ### silly -The "silly" auth is only for development purposes. It simply checks for the existence of the "Authorization" header in the HTTP request, with no regard for the value of the header. If the header does not exist, it will respond with a challenge response, echoing back the realm, service, and scope that access was denied for. +The `silly` auth is only for development purposes. It simply checks for the +existence of the `Authorization` header in the HTTP request. It has no regard for +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 that access was +denied for. + +The following values are used to configure the response: + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ realm + + yes + + The realm in which the registry server authenticates. +
+ service + + yes + + The service being authenticated. +
-The values of the ```realm``` and ```service``` options are used in authentication reponses, both options are **required** -- realm: **Required** - The realm in which the registry server authenticates. -- service: **Required** - The service being authenticated. ### token -Token based authentication allows the authentication system to be decoupled from the registry. It is a well established authentication paradigm with a high degree of security. +Token based authentication allows the authentication system to be decoupled from +the registry. It is a well established authentication paradigm with a high +degree of security. -- realm: **Required** - The realm in which the registry server authenticates. -- service: **Required** - The service being authenticated. -- issuer: **Required** - The name of the token issuer. The issuer inserts this into the token so it must match the value configured for the issuer. -- rootcertbundle: **Required** - The absolute path to the root certificate bundle containing the public part of the certificates that will be used to sign authentication tokens. + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ 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 that is used to sign authentication tokens. +
For more information about Token based authentication configuration, see the [specification.] ## middleware -The middleware option is **optional** and allows middlewares to be injected at named hook points. A requirement of all middlewares is that they implement the same interface as the object they're wrapping. This means a registry middleware must implement the `distribution.Namespace` interface, repository middleware must implement `distribution.Respository`, and storage middleware must implement `driver.StorageDriver`. +The `middleware` option is **optional**. Use this option to inject middleware at +named hook points. All middlewares must implement the same interface as the +object they're wrapping. This means a registry middleware must implement the +`distribution.Namespace` interface, repository middleware must implement +`distribution.Respository`, and storage middleware must implement +`driver.StorageDriver`. -Currently only one middleware, cloudfront, a storage middleware, is included in the registry. +Currently only one middleware, `cloudfront`, a storage middleware, is supported +in the registry implementation. ```yaml middleware: @@ -306,14 +565,68 @@ middleware: duration: 3000 ``` -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{} and as such will support any interesting structures desired, leaving it up to the middleware initialization function to best determine how to handle the specific interpretation of the options. +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 -- baseurl: **Required** - SCHEME://HOST[/PATH] at which Cloudfront is served. -- privatekey: **Required** - Private Key for Cloudfront provided by AWS -- keypairid: **Required** - Key Pair ID provided by AWS -- duration: **Optional** - Duration for which a signed URL should be valid + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ baseurl + + yes + + SCHEME://HOST[/PATH] at which Cloudfront is served. +
+ privatekey + + yes + + Private Key for Cloudfront provided by AWS. +
+ keypairid + + yes + + Key pair ID provided by AWS. +
+ duration + + no + + Duration for which a signed URL should be valid. +
+ ## reporting @@ -326,20 +639,102 @@ reporting: 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, New Relic and Bugsnag, a valid configuration may contain both. +The `reporting` option is **optional** and configures error and metrics +reporting tools. At the moment only two services are supported, [New +Relic](http://newrelic.com/) and [Bugsnag](http://bugsnag.com), a valid +configuration may contain both. ### bugsnag -- apikey: **Required** - API Key provided by Bugsnag -- releasestage: **Optional** - TODO: fill in description -- endpoint: **Optional** - TODO: fill in description + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ apikey + + yes + + API Key provided by Bugsnag +
+ releasestage + + no + + Tracks where the registry is deployed, for example, + production,staging, or + development. +
+ endpoint + + no + + Specify the enterprise Bugsnag endpoint. +
+ ### newrelic -- licensekey: **Required** - License key provided by New Relic -- name: **Optional** - New Relic application name + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ licensekey + + yes + + License key provided by New Relic. +
+ name + + no + + New Relic application name. +
+ verbose + + no + + Enable New Relic debugging output on stdout. +
## http @@ -358,25 +753,112 @@ http: addr: localhost:5001 ``` -The http option details the configuration for the HTTP server that hosts the registry. +The `http` option details the configuration for the HTTP server that hosts the registry. + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ addr + + yes + + The HOST:PORT for which the server should accept connections. +
+ prefix + + no + +If the server does not run at the root path use this value to specify the +prefix. The root path is the section before v2. It +should have both preceding and trailing slashes, for example /path/. +
+ secret + + yes + +A random piece of data. This is 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. +
-- addr: **Required** - The HOST:PORT for which the server should accept connections. -- prefix: **Optional** - If the server will not run at the root path, this should specify the prefix (the part of the path before ```v2```). It should have both preceding and trailing slashes. -- secret: A random piece of data. It is used to sign state that may be stored with the client to protect against tampering. For production use you should generate a random piece of data using a cryptographically secure random generator. ### tls -The tls option within http is **optional** and allows you to configure SSL for the server. If you already have a server such as Nginx or Apache running on the same host as the registry, you may prefer to configure SSL termination there and proxy connections to the registry server. +The `tls` struct within `http` is **optional**. Use this to configure TLS +for the server. If you already have a server such as Nginx or Apache running on +the same host as the registry, you may prefer to configure TLS termination there +and proxy connections to the registry server. + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ certificate + + yes + + Absolute path to x509 cert file +
+ key + + yes + + Absolute path to x509 private key file. +
+ clientcas + + no + + An array of absolute paths to a x509 CA file +
-- certificate: **Required** - Absolute path to x509 cert file -- key: **Required** - Absolute path to x509 private key file -- clientcas: **Optional** - An array of absolute paths to a x509 CA file ### debug -The debug option is **optional** and allows you to configure a debug server that can be helpful in diagnosing problems. It is of most use to contributers to the distribution repository and should generally be disabled in production deployments. +The `debug` option is **optional** . Use it to configure a debug server that can +be helpful in diagnosing problems. Contributors to the distribution repository +should find the debug server useful. Docker recommends disabling it in +production environments. -- addr: **Required** - The HOST:PORT on which the debug server should accept connections. +The `debug` section takes a single, required `addr` parameter. This parameter +specifies the `HOST:PORT` on which the debug server should accept connections. ## notifications @@ -393,19 +875,119 @@ notifications: backoff: 1000 ``` -The notifications option is **optional** and currently may contain a single option, ```endpoints```. +The notifications option is **optional** and currently may contain a single +option, `endpoints`. ### endpoints Endpoints is a list of named services (URLs) that can accept event notifications. -- name: **Required** - A human readable name for the service. -- disabled: **Optional** - A boolean to enable/disable notifications for a service. -- url: **Required** - The URL to which events should be published. -- headers: **Required** - TODO: fill in description -- timeout: **Required** - TODO: fill in description -- threshold: **Required** - TODO: fill in description -- backoff: **Required** - TODO: fill in description + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ name + + yes + +A human readable name for the service. +
+ disabled + + no + +A boolean to enable/disable notifications for a service. +
+ url + + yes + +The URL to which events should be published. +
+ headers + + yes + + Static headers to add to each request. +
+ timeout + + yes + + An HTTP timeout value. This field takes a positive integer and an optional + suffix indicating the unit of time. Possible units are: +
    +
  • ns (nanoseconds)
  • +
  • us (microseconds)
  • +
  • ms (milliseconds)
  • +
  • s (seconds)
  • +
  • m (minutes)
  • +
  • h (hours)
  • +
+ If you omit the suffix, the system interprets the value as nanoseconds. +
+ threshold + + yes + + An integer specifying how long to wait before backing off a failure. +
+ backoff + + yes + + How long the system backs off before retrying. This field takes a positive + integer and an optional suffix indicating the unit of time. Possible units + are: +
    +
  • ns (nanoseconds)
  • +
  • us (microseconds)
  • +
  • ms (milliseconds)
  • +
  • s (seconds)
  • +
  • m (minutes)
  • +
  • h (hours)
  • +
+ If you omit the suffix, the system interprets the value as nanoseconds. +
+ ## redis @@ -424,17 +1006,85 @@ redis: ``` Declare parameters for constructing the redis connections. Registry instances -may use the redis instance for several applications. The current purpose is +may use the Redis instance for several applications. The current purpose is caching information about immutable blobs. Most of the options below control -how the registry connects to redis. The behavior of the pool can be controlled +how the registry connects to redis. You can control the pool's behavior with the [pool](#pool) subsection. -- addr: **Required** - Address (host and port) of redis instance. -- password: **Optional** - A password used to authenticate to the redis instance. -- db: **Optional** - Selects the db for each connection. -- dialtimeout: **Optional** - Timeout for connecting to a redis instance. -- readtimeout: **Optional** - Timeout for reading from redis connections. -- writetimeout: **Optional** - Timeout for writing to redis connections. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ addr + + yes + + Address (host and port) of redis instance. +
+ password + + no + + A password used to authenticate to the redis instance. +
+ db + + no + + Selects the db for each connection. +
+ dialtimeout + + no + + Timeout for connecting to a redis instance. +
+ readtimeout + + no + + Timeout for reading from redis connections. +
+ writetimeout + + no + + Timeout for writing to redis connections. +
+ ### pool @@ -445,10 +1095,132 @@ pool: idletimeout: 300s ``` -Configure the behavior of the redis connection pool. +Configure the behavior of the Redis connection pool. -- maxidle: **Optional** - sets the maximum number of idle connections. -- maxactive: **Optional** - sets the maximum number of connections that should + + + + + + + + + + + + + + + + + + + + + +
ParameterRequiredDescription
+ maxidle + + no + + Sets the maximum number of idle connections. +
+ maxactive + + no + + sets the maximum number of connections that should be opened before blocking a connection request. -- idletimeout: **Optional** - sets the amount time to wait before closing +
+ idletimeout + + no + + sets the amount time to wait before closing inactive connections. +
+ +## Example: Development configuration + +The following is a simple example you can use for local development: + +```yaml +version: 0.1 +log: + level: debug +storage: + filesystem: + rootdirectory: /tmp/registry-dev +http: + addr: localhost:5000 + secret: asecretforlocaldevelopment + debug: + addr: localhost:5001 +``` + +The above configures the registry instance to run on port `5000`, binding to +`localhost`, with the `debug` server enabled. Registry data storage is in the +`/tmp/registry-dev` directory. Logging is in `debug` mode, which is the most +verbose. + +A similar simple configuration is available at +[config.yml](https://github.com/docker/distribution/blob/master/cmd/registry/ +config.yml). Both are generally useful for local development. + + +## Example: Middleware configuration + +This example illustrates how to configure storage middleware in a registry. +Middleware allows the registry to serve layers via a content delivery network +(CDN). This is useful for reducing requests to the storage layer. + +Currently, the registry supports [Amazon +Cloudfront](http://aws.amazon.com/cloudfront/). You can only use Cloudfront in +conjunction with the S3 storage driver. + + + + + + + + + + + + + + + + + + +
ParameterDescription
nameThe storage middleware name. Currently cloudfront is an accepted value.
disabledSet to false to easily disable the middleware.
options: + A set of key/value options to configure the middleware. +
    +
  • baseurl: The Cloudfront base URL.
  • +
  • privatekey: The location of your AWS private key on the filesystem.
  • +
  • keypairid: The ID of your Cloudfront keypair.
  • +
  • duration: The duration in minutes for which the URL is valid. Default is 20.
  • +
+
+ +The following example illustrates these values: + +``` +middleware: + storage: + - name: cloudfront + disabled: false + options: + baseurl: http://d111111abcdef8.cloudfront.net + privatekey: /path/to/asecret.pem + keypairid: asecret + duration: 60 +``` + + +>**Note**: Cloudfront keys exist separately to other AWS keys. See +>[the documentation on AWS credentials](http://docs.aws.amazon.com/AWSSecurityCredentials/1.0/ +>AboutAWSCredentials.html#KeyPairs) for more information. + diff --git a/docs/deploying.md b/docs/deploying.md index c87c7bcfc..e397db60a 100644 --- a/docs/deploying.md +++ b/docs/deploying.md @@ -16,13 +16,17 @@ deployment process. This registry image is sufficient for running local tests but is insufficient for production. For production you should configure and build your own custom registry image from the `docker/distribution` code. +>**Note**: The examples on this page were written and tested using Ubuntu 14.04. +>If you are running Docker in a different OS, you may need to "translate" +>the commands to meet the requirements of your own environment. + ## Simple example with the official image -In this section, you create a local registry using Docker's official image. You -push an image to, and then pull the same image from, the registry. This a good -exercise for understanding the basic interactions a client has with a -local registry. +In this section, you create a container running Docker's official registry +image. You push an image to, and then pull the same image from, this registry. +This a good exercise for understanding the basic interactions a client has with +a local registry. 1. Install Docker. @@ -30,7 +34,8 @@ local registry. $ docker run hello-world - The `run` command automatically pulls the image from Docker's official images. + The `run` command automatically pulls a `hello-world` image from Docker's + official images. 3. Start a registry service on your localhost. @@ -68,11 +73,40 @@ local registry. You should see your new image in your listing. -5. Push this new image to your local registry. +6. Push this new image to your local registry. $ docker push localhost:5000/hello-mine:latest + The push refers to a repository [localhost:5000/hello-mine] (len: 1) + e45a5af57b00: Image already exists + 31cbccb51277: Image successfully pushed + 511136ea3c5a: Image already exists + Digest: sha256:a1b13bc01783882434593119198938b9b9ef2bd32a0a246f16ac99b01383ef7a + +7. Use the `curl` command and the Docker Registry Service API v2 to list your + image in the registry: + + $ curl -v -X GET http://localhost:5000/v2/hello-mine/tags/list + * Hostname was NOT found in DNS cache + * Trying 127.0.0.1... + * Connected to localhost (127.0.0.1) port 5000 (#0) + > GET /v2/hello-mine/tags/list HTTP/1.1 + > User-Agent: curl/7.35.0 + > Host: localhost:5000 + > Accept: */* + > + < HTTP/1.1 200 OK + < Content-Type: application/json; charset=utf-8 + < Docker-Distribution-Api-Version: registry/2.0 + < Date: Sun, 12 Apr 2015 01:29:47 GMT + < Content-Length: 40 + < + {"name":"hello-mine","tags":["latest"]} + * Connection #0 to host localhost left intact + + You can also get this information by entering the + `http://52.10.125.146:5000/v2/hello-mine/tags/list` address in your browser. -6. Remove all the unused images from your local environment: +8. Remove all the unused images from your local environment: $ docker rmi -f $(docker images -q -a ) @@ -86,7 +120,7 @@ local registry. registry 2.0 bbf0b6ffe923 3 days ago 545.1 MB golang 1.4 121a93c90463 5 days ago 514.9 MB -7. Try running `hello-mine`. +9. Try running `hello-mine`. $ docker run hello-mine Unable to find image 'hello-mine:latest' locally @@ -96,7 +130,7 @@ local registry. The `run` command fails because your new image doesn't exist in the Docker public registry. -8. Now, try running the image but specifying the image's registry: +10. Now, try running the image but specifying the image's registry: $ docker run localhost:5000/hello-mine @@ -128,7 +162,7 @@ factors: access and/or authentication - Do users should have full or controlled access? This can depend on whether + Should users have full or controlled access? This can depend on whether you are serving images to the public or internally to your company only. @@ -156,7 +190,7 @@ You can configure your registry features to adjust for these factors. You do this by specifying options on the command line or, more typically, by writing a registry configuration file. The configuration file is in YAML format. -Docker's official repository image it is preconfigured using the following +Docker's official repository image is preconfigured using the following configuration file: ```yaml @@ -203,7 +237,6 @@ notifications: disabled: true ``` - This configuration is very basic and you can see it would present some problems in a production. For example, the `http` section details the configuration for the HTTP server that hosts the registry. The server is not using even the most @@ -213,10 +246,10 @@ minimal transport layer security (TLS). Let's configure that in the next section In this section, you configure TLS on the server to enable communication through the `https` protocol. Enabling TLS on the server is the minimum layer of -security recommended for running a registry behind a corporate firewall. The -easiest way to do this is to build your own registry image. +security recommended for running a registry behind a corporate firewall. One way +to do this is to build your own registry image. -### Download the registry source and generated certificates +### Download the source and generate certificates 1. [Download the registry source](https://github.com/docker/distribution/releases/tag/v2.0.0). @@ -241,55 +274,21 @@ source](https://github.com/docker/distribution/releases/tag/v2.0.0). -newkey rsa:2048 -nodes -keyout certs/domain.key \ -x509 -days 365 -out certs/domain.crt + This command prompts you for basic information it needs to create the certificates. -### Add the certificates to the image +6. List the contents of the `certs` directory. -In this section, you copy the certifications from your `certs` directory into -your base image. - -1. Edit the `Dockerfile` and add a `CERTS_PATH` environment variable. - - ENV CERTS_PATH /etc/docker/registry/certs + $ ls certs + domain.crt domain.key -2. Add a line to make the `CERTS_PATH` in the filesystem. - - RUN mkdir -v $CERTS_PATH - -3. Add `RUN` instructions to hard link your new certifications into this path: - - RUN cp -lv ./certs/domain.crt $CERTS_PATH - RUN cp -lv ./certs/domain.key $CERTS_PATH - - This copies your certifications into your container. - -4. Save your work. - - At this point your Dockerfile should look like the following: - - FROM golang:1.4 - - ENV CONFIG_PATH /etc/docker/registry/config.yml - ENV CERTS_PATH /etc/docker/registry/certs - ENV DISTRIBUTION_DIR /go/src/github.com/docker/distribution - ENV GOPATH $DISTRIBUTION_DIR/Godeps/_workspace:$GOPATH - - WORKDIR $DISTRIBUTION_DIR - COPY . $DISTRIBUTION_DIR - RUN make PREFIX=/go clean binaries - RUN mkdir -pv "$(dirname $CONFIG_PATH)" - RUN mkdir -v $CERTS_PATH - RUN cp -lv ./certs/domain.crt $CERTS_PATH - RUN cp -lv ./certs/domain.key $CERTS_PATH - RUN cp -lv ./cmd/registry/config.yml $CONFIG_PATH - -5. Before you close the Dockerfile look for an instruction to copy the `config.yml` file. + When you build this container, the `certs` directory and its contents + automatically get copied also. - RUN cp -lv ./cmd/registry/config.yml $CONFIG_PATH - - This is the default registry configuration file. You'll need to edit the file - to add TLS. - -### Add TLS to the registry configuration +### Add TLS to the configuration + +The `distribution` repo includes sample registry configurations in the `cmd` +subdirectory. In this section, you edit one of these configurations to add TLS +support. 1. Edit the `./cmd/registry/config.yml` file. @@ -311,8 +310,8 @@ your base image. debug: addr: localhost:5001 tls: - certificate: /etc/docker/registry/certs/domain.crt - key: /etc/docker/registry/certs/domain.key + certificate: /go/src/github.com/docker/distribution/certs/domain.crt + key: /go/src/github.com/docker/distribution/certs/domain.key You provide the paths to the certificates in the container. If you want two-way authentication across the layer, you can add an optional `clientcas` @@ -321,7 +320,7 @@ your base image. 4. Save and close the file. -### Run your new image +### Build and run your registry image 1. Build your registry image. @@ -329,138 +328,238 @@ your base image. 2. Run your new image. - $ docker run -p 5000:5000 secure_registry + $ docker run -p 5000:5000 registry_local:latest + time="2015-04-12T03:06:18.616502588Z" level=info msg="endpoint local-8082 disabled, skipping" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry + time="2015-04-12T03:06:18.617012948Z" level=info msg="endpoint local-8083 disabled, skipping" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry + time="2015-04-12T03:06:18.617190113Z" level=info msg="using inmemory layerinfo cache" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry + time="2015-04-12T03:06:18.617349067Z" level=info msg="listening on :5000, tls" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry + time="2015-04-12T03:06:18.628589577Z" level=info msg="debug server listening localhost:5001" + 2015/04/12 03:06:28 http: TLS handshake error from 172.17.42.1:44261: remote error: unknown certificate authority - Watch the messages at startup. You should see that `tls` is running: - - ubuntu@ip-172-31-34-181:~/repos/distribution$ docker run -p 5000:5000 secure_registry - time="2015-04-05T23:56:47Z" level=info msg="endpoint local-8082 disabled, skipping" app.id=3dd802ad-3bd4-4413-b56d-90c4acff41c7 environment=development service=registry - time="2015-04-05T23:56:47Z" level=info msg="endpoint local-8083 disabled, skipping" app.id=3dd802ad-3bd4-4413-b56d-90c4acff41c7 environment=development service=registry - time="2015-04-05T23:56:47Z" level=info msg="using inmemory layerinfo cache" app.id=3dd802ad-3bd4-4413-b56d-90c4acff41c7 environment=development service=registry - time="2015-04-05T23:56:47Z" level=info msg="listening on :5000, tls" app.id=3dd802ad-3bd4-4413-b56d-90c4acff41c7 environment=development service=registry - time="2015-04-05T23:56:47Z" level=info msg="debug server listening localhost:5001" - 2015/04/05 23:57:23 http: TLS handshake error from 172.17.42.1:52057: remote error: unknown certificate authority + Watch the messages at startup. You should see that `tls` is running. 3. Use `curl` to verify that you can connect over `https`. - $ curl https://localhost:5000 + $ curl -v https://localhost:5000 + * Rebuilt URL to: https://localhost:5000/ + * Hostname was NOT found in DNS cache + * Trying 127.0.0.1... + * Connected to localhost (127.0.0.1) port 5000 (#0) + * successfully set certificate verify locations: + * CAfile: none + CApath: /etc/ssl/certs + * SSLv3, TLS handshake, Client hello (1): + * SSLv3, TLS handshake, Server hello (2): + * SSLv3, TLS handshake, CERT (11): + * SSLv3, TLS alert, Server hello (2): + * SSL certificate problem: self signed certificate + * Closing connection 0 + curl: (60) SSL certificate problem: self signed certificate + More details here: http://curl.haxx.se/docs/sslcerts.html +## Configure Nginx with a v1 and v2 registry + +This sections describes how to user `docker-compose` to run a combined version +1 and version 2.0 registry behind an `nginx` proxy. The combined registry is +accessed at `localhost:5000`. If a `docker` client has a version less than 1.6, +Nginx will route its requests to the 1.0 registry. Requests from newer clients +will route to the 2.0 registry. + +This procedure uses the same `distribution` directory you created in the last +procedure. The directory includes an example `compose` configuration. + +### Install Docker Compose + +1. Open a new terminal on the host with your `distribution` directory. + +2. Get the `docker-compose` binary. + + $ sudo wget https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` -O /usr/local/bin/docker-compose + + This command installs the binary in the `/usr/local/bin` directory. + +3. Add executable permissions to the binary. + + $ sudo chmod +x /usr/local/bin/docker-compose -## Adding a middleware configuration -This section describes how to configure storage middleware in a registry. -Middleware allows the registry to server layers via a content delivery network -(CDN). This is useful for reducing requests to the storage layer. +### Do some housekeeping -Currently, the registry supports [Amazon -Cloudfront](http://aws.amazon.com/cloudfront/). You can only use Cloudfront in -conjunction with the S3 storage driver. +1. Remove any previous images. - - - - - - - - - - - - - - - - - -
ParameterDescription
nameThe storage middleware name. Currently cloudfront is an accepted value.
disabledSet to false to easily disable the middleware.
options: - A set of key/value options to configure the middleware. -
    -
  • baseurl: The Cloudfront base URL.
  • -
  • privatekey: The location of your AWS private key on the filesystem.
  • -
  • keypairid: The ID of your Cloudfront keypair.
  • -
  • duration: The duration in minutes for which the URL is valid. Default is 20.
  • -
-
+ $ docker rmi -f $(docker images -q -a ) + + This step is a house keeping step. It prevents you from mistakenly picking up + an old image as you work through this example. + +2. Edit the `distribution/cmd/registry/config.yml` file and remove the `tls` block. -The following example illustrates these values: + If you worked through the previous example, you'll have a `tls` block. -``` -middleware: - storage: - - name: cloudfront - disabled: false - options: - baseurl: http://d111111abcdef8.cloudfront.net - privatekey: /path/to/asecret.pem - keypairid: asecret - duration: 60 -``` +4. Save any changes and close the file. +### Configure SSL ->**Note**: Cloudfront keys exist separately to other AWS keys. See ->[the documentation on AWS credentials](http://docs.aws.amazon.com/AWSSecurityCredentials/1.0/ ->AboutAWSCredentials.html#KeyPairs) for more information. +1. Change to the `distribution/contrib/compose/nginx` directory. + This directory contains configuration files for Nginx and both registries. + +2. Use SSL to generate some self-signed certificates. + + $ openssl req \ + -newkey rsa:2048 -nodes -keyout domain.key \ + -x509 -days 365 -out domain.crt + + This command prompts you for basic information it needs to create certificates. + +3. Edit the `Dockerfile`and add the following lines. -**TODO(stevvooe): Need a "best practice" configuration overview. Perhaps, we can point to a documentation section. + COPY domain.crt /etc/nginx/domain.crt + COPY domain.key /etc/nginx/domain.key + + When you are done, the file looks like the following. + + FROM nginx:1.7 + COPY nginx.conf /etc/nginx/nginx.conf + COPY registry.conf /etc/nginx/conf.d/registry.conf + COPY docker-registry.conf /etc/nginx/docker-registry.conf + COPY docker-registry-v2.conf /etc/nginx/docker-registry-v2.conf + COPY domain.crt /etc/nginx/domain.crt + COPY domain.key /etc/nginx/domain.key -# Configure nginx to deploy alongside v1 registry +4. Save and close the `Dockerfile` file. + +5. Edit the `registry.conf` file and add the following configuration. -This sections describes how to configure nginx to proxy to both a v1 and v2 -registry. Nginx will handle routing of to the correct registry based on the -URL and Docker client version. + ssl on; + ssl_certificate /etc/nginx/domain.crt; + ssl_certificate_key /etc/nginx/domain.key; + + This is an `nginx` configuration file. -## Example configuration -With v1 registry running at `localhost:5001` and v2 registry running at -`localhost:5002`. Add this to `/etc/nginx/conf.d/registry.conf`. -``` -server { - listen 5000; - server_name localhost; +6. Save and close the `registry.conf` file. - ssl on; - ssl_certificate /etc/docker/registry/certs/domain.crt; - ssl_certificate_key /etc/docker/registry/certs/domain.key; +### Build and run - client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads +1. Go up to the `distribution/contrib/compose` directory - # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) - chunked_transfer_encoding on; + This directory includes a single `docker-compose.yml` configuration. + + nginx: + build: "nginx" + ports: + - "5000:5000" + links: + - registryv1:registryv1 + - registryv2:registryv2 + registryv1: + image: registry + ports: + - "5000" + registryv2: + build: "../../" + ports: + - "5000" - 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; - } + This configuration builds a new `nginx` image as specified by the + `nginx/Dockerfile` file. The 1.0 registry comes from Docker's official public + image. Finally, the registry 2.0 image is built from the + `distribution/Dockerfile` you've used previously. - proxy_pass http://localhost:5002; - 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_read_timeout 900; - } +2. Get a registry 1.0 image. - location / { - proxy_pass http://localhost:5001; - 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 Authorization ""; # see https://github.com/docker/docker-registry/issues/170 - proxy_read_timeout 900; - } -} -``` + $ docker pull registry:0.9.1 -## Running nginx without a v1 registry -When running a v2 registry behind nginx without a v1 registry, the `/v1/` endpoint should -be explicitly configured to return a 404 if only the `/v2/` route is proxied. This -is needed due to the v1 registry fallback logic within Docker 1.5 and 1.6 which will attempt -to retrieve content from the v1 endpoint if no content was retrieved from v2. + The Compose configuration looks for this image locally. If you don't do this + step, later steps can fail. + +3. Build `nginx`, the registry 2.0 image, and + + $ docker-compose build + registryv1 uses an image, skipping + Building registryv2... + Step 0 : FROM golang:1.4 + + ... + + Removing intermediate container 9f5f5068c3f3 + Step 4 : COPY docker-registry-v2.conf /etc/nginx/docker-registry-v2.conf + ---> 74acc70fa106 + Removing intermediate container edb84c2b40cb + Successfully built 74acc70fa106 + + The commmand outputs its progress until it completes. + +4. Start your configuration with compose. + + $ docker-compose up + Recreating compose_registryv1_1... + Recreating compose_registryv2_1... + Recreating compose_nginx_1... + Attaching to compose_registryv1_1, compose_registryv2_1, compose_nginx_1 + ... + + +5. In another terminal, display the running configuration. + + $ docker ps + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + a81ad2557702 compose_nginx:latest "nginx -g 'daemon of 8 minutes ago Up 8 minutes 80/tcp, 443/tcp, 0.0.0.0:5000->5000/tcp compose_nginx_1 + 0618437450dd compose_registryv2:latest "registry cmd/regist 8 minutes ago Up 8 minutes 0.0.0.0:32777->5000/tcp compose_registryv2_1 + aa82b1ed8e61 registry:latest "docker-registry" 8 minutes ago Up 8 minutes 0.0.0.0:32776->5000/tcp compose_registryv1_1 + +### Explore a bit + +1. Check for TLS on your `nginx` server. + + $ curl -v https://localhost:5000 + * Rebuilt URL to: https://localhost:5000/ + * Hostname was NOT found in DNS cache + * Trying 127.0.0.1... + * Connected to localhost (127.0.0.1) port 5000 (#0) + * successfully set certificate verify locations: + * CAfile: none + CApath: /etc/ssl/certs + * SSLv3, TLS handshake, Client hello (1): + * SSLv3, TLS handshake, Server hello (2): + * SSLv3, TLS handshake, CERT (11): + * SSLv3, TLS alert, Server hello (2): + * SSL certificate problem: self signed certificate + * Closing connection 0 + curl: (60) SSL certificate problem: self signed certificate + More details here: http://curl.haxx.se/docs/sslcerts.html + +2. Tag the `v1` registry image. + + $ docker tag registry:latest localhost:5000/registry_one:latest + +2. Push it to the localhost. + + $ docker push localhost:5000/registry_one:latest + + If you are using the 1.6 Docker client, this pushes the image the `v2 `registry. + +4. Use `curl` to list the image in the registry. + + $ curl -v -X GET http://localhost:32777/v2/registry1/tags/list + * Hostname was NOT found in DNS cache + * Trying 127.0.0.1... + * Connected to localhost (127.0.0.1) port 32777 (#0) + > GET /v2/registry1/tags/list HTTP/1.1 + > User-Agent: curl/7.36.0 + > Host: localhost:32777 + > Accept: */* + > + < HTTP/1.1 200 OK + < Content-Type: application/json; charset=utf-8 + < Docker-Distribution-Api-Version: registry/2.0 + < Date: Tue, 14 Apr 2015 22:34:13 GMT + < Content-Length: 39 + < + {"name":"registry1","tags":["latest"]} + * Connection #0 to host localhost left intact + + This example refers to the specific port assigned to the 2.0 registry. You saw + this port earlier, when you used `docker ps` to show your running containers. -Add this location block to explicitly block v1 requests. -``` -localhost /v1/ { - return 404; -} -``` diff --git a/docs/notifications.md b/docs/notifications.md index 5e4fb964c..264a7dc8d 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -10,7 +10,7 @@ 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_](#endpoints). -![](/distribution/images/notifications.png) +![](../images/notifications.png) ## Endpoints diff --git a/docs/overview.md b/docs/overview.md index 23cef0b5c..0d97549af 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -22,7 +22,7 @@ is collection of images. Users interact with the registry by pushing images to or pulling images from the registry. The Docker Registry includes several optional features that you can configure according to your needs. -![](/distribution/images/registry.png) +![](../images/registry.png) The architecture supports a configurable storage backend. You can store images on a file system or on a service such as Amazon S3 or Microsoft Azure. The @@ -64,4 +64,3 @@ For more information and resources, please visit the [Getting Help project page] - [Storage driver model](storagedrivers.md) - [Working with notifications](notifications.md) - [Registry API v2](spec/api.md) -