Merge pull request #837 from dmp42/4.docs-2.1

[WIP] Updating documentation for 2.1
This commit is contained in:
Aaron Lehmann 2015-08-10 14:01:52 -07:00
commit 143aae8bc5
8 changed files with 227 additions and 184 deletions

View File

@ -9,15 +9,13 @@ weight=4
+++
<![end-metadata]-->
# Registry Configuration Reference
The Registry configuration is based on a YAML file, detailed below. While it comes with sane default values out of the box, you are heavily encouraged to review it exhaustively before moving your systems to production.
## Override configuration options
## Override specific configuration options
In a typical setup where you run your Registry from the official image, you can specify any configuration variable from the environment by passing `-e` arguments to your `docker run` stanza, or from within a Dockerfile using the `ENV` instruction.
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
@ -41,7 +39,17 @@ directory.
>environment will remove all parameters related to the old storage
>configuration.
## 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, and call it `config.yml`, then:
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/config.yml:/etc/docker/registry/config.yml \
registry:2
You can (and probably should) use [this a starting point](https://github.com/docker/distribution/blob/master/cmd/registry/config-example.yml).
## List of configuration options

View File

@ -9,148 +9,128 @@ weight=3
+++
<![end-metadata]-->
# Deploying a registry server
You obviously need to [install Docker](https://docs.docker.com/installation/) (remember you need **Docker version 1.6.0 or newer**).
You need to [install Docker version 1.6.0 or newer](https://docs.docker.com/installation/).
## Getting started
## Running on localhost
Start your registry:
$ docker run -d -p 5000:5000 \
--restart=always --name registry registry:2
docker run -d -p 5000:5000 --restart=always --name registry registry:2
That's it.
You can now use it with docker.
You can now tag an image and push it:
Get any image from the hub and tag it to point to your registry:
$ docker pull ubuntu && docker tag ubuntu localhost:5000/batman/ubuntu
$ docker push localhost:5000/batman/ubuntu
docker pull ubuntu && docker tag ubuntu localhost:5000/ubuntu
Then pull it back:
... then push it to your registry:
$ docker pull localhost:5000/batman/ubuntu
docker push localhost:5000/ubuntu
## Where is my data?
... then pull it back from your registry:
By default, your registry stores its data on the local filesystem, inside the container.
docker pull localhost:5000/ubuntu
In a production environment, it's highly recommended to use [another storage backend](storagedrivers.md), by [configuring it](configuration.md).
To stop your registry, you would:
If you want to stick with the local posix filesystem, you should store your data outside of the container.
docker stop registry && docker rm -v registry
This is achieved by mounting a volume into the container:
## Storage
$ docker run -d -p 5000:5000 \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry \
-v /myregistrydata:/var/lib/registry \
--restart=always --name registry registry:2
By default, your registry data is persisted as a [docker volume](https://docs.docker.com/userguide/dockervolumes/) on the host filesystem. Properly understanding volumes is essential if you want to stick with a local filesystem storage.
## Making your Registry available
Specifically, you might want to point your volume location to a specific place in order to more easily access your registry data. To do so you can:
Now that your registry works on `localhost`, you probably want to make it available as well to other hosts.
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/data:/var/lib/registry \
registry:2
Let assume your registry is accessible via the domain name `myregistrydomain.com` (still on port `5000`).
### Alternatives
If you try to `docker pull myregistrydomain.com:5000/batman/ubuntu`, you will see the following error message:
You should usually consider using [another storage backend](https://github.com/docker/distribution/blob/master/docs/storagedrivers.md) instead of the local filesystem. Use the [storage configuration options](https://github.com/docker/distribution/blob/master/docs/configuration.md#storage) to configure an alternate storage backend.
```
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,please 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
```
Using one of these will allow you to more easily scale your registry, and leverage your storage redundancy and availability features.
If trying to reach a non `localhost` registry, Docker requires that you secure it using https, or make it explicit that you want to run an insecure registry.
## Running a domain registry
You basically have three different options to comply with that security requirement here.
While running on `localhost` has its uses, most people want their registry to be more widely available. To do so, the Docker engine requires you to secure it using TLS, which is conceptually very similar to configuring your web server with SSL.
### 1. buy a SSL certificate for your domain
### Get a certificate
This is the (highly) recommended solution.
Assuming that you own the domain `myregistrydomain.com`, and that its DNS record points to the host where you are running your registry, you first need to get a certificate from a CA.
You can buy a certificate for as cheap as 10$ a year (some registrars even offer certificates for free), and this will save you a lot of trouble.
Move and/or rename your crt file to: `certs/domain.crt` - and your key file to: `certs/domain.key`.
Assuming you now have a `domain.crt` and `domain.key` inside a directory named `certs`:
Make sure you stopped your registry from the previous steps, then start your registry again with TLS enabled:
```
# Stop your registry
docker stop registry && docker rm registry
# Start your registry with TLS enabled
docker run -d -p 5000:5000 \
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
--restart=always --name registry \
registry:2
```
A certificate issuer may supply you with an *intermediate* certificate. In this case, you must combine your certificate with the intermediate's to form a *certificate bundle*. You can do this using the `cat` command:
You should now be able to access your registry from another docker host:
```
$ cat server.crt intermediate-certificates.pem > server.with-intermediate.crt
```
docker pull ubuntu
docker tag ubuntu myregistrydomain.com:5000/ubuntu
docker push myregistrydomain.com:5000/ubuntu
docker pull myregistrydomain.com:5000/ubuntu
You then configure the registry to use your certificate bundle by providing the `REGISTRY_HTTP_TLS_CERTIFICATE` environment variable.
### Alternatives
**Pros:**
While rarely advisable, you may want to use self-signed certificates instead, or use your registry in an insecure fashion. You will find instructions [here](insecure.md).
- best solution
- work without further ado (assuming you bought your certificate from a CA that is trusted by your operating system)
## Restricting access
**Cons:**
Except for registries running on secure local networks, registries should always implement access restrictions.
- ?
### Native basic auth
### 2. instruct docker to trust your registry as insecure
The simplest way to achieve access restriction is through basic authentication (this is very similar to other web servers' basic authentication mechanism).
This basically tells Docker to entirely disregard security for your registry.
> :warning: You **cannot** use authentication with an insecure registry. You have to [configure TLS first](#running-a-domain-registry) for this to work.
1. edit the file `/etc/default/docker` so that there is a line that reads: `DOCKER_OPTS="--insecure-registry myregistrydomain.com:5000"` (or add that to existing `DOCKER_OPTS`). Restart docker.
2. restart your Docker daemon: on ubuntu, this is usually `service docker stop && service docker start`
First create a password file with one entry for the user "testuser", with password "testpassword":
**Pros:**
mkdir auth
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd
- easy to configure
Make sure you stopped your registry from the previous step, then start it again:
**Cons:**
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/auth:/auth \
-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
- very insecure
- you have to configure every docker daemon that wants to access your registry
You should now be able to:
### 3. use a self-signed certificate and configure docker to trust it
docker login myregistrydomain.com:5000
Alternatively, you can generate your own certificate:
And then push and pull images as an authenticated user.
```
mkdir -p certs && openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
```
### Alternatives
Be sure to use the name `myregistrydomain.com` as a CN.
1. You may want to leverage more advanced basic auth implementations through a proxy design, in front of the registry. You will find an example of such design in the [nginx proxy documentation](nginx.md).
Now go to solution 1 above and stop and restart your registry.
2. Alternatively, the Registry also supports delegated authentication, redirecting users to a specific, trusted token server. That approach requires significantly more investment, and only make sense if you want to fully configure ACLs and more control over the Registry integration into your global authorization and authentication systems.
Then you have to instruct every docker daemon to trust that certificate. This is done by copying the `domain.crt` file to `/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt` (don't forget to restart docker after doing so).
You will find [background information here](spec/auth/token.md), and [configuration information here](configuration.md#auth).
**Pros:**
Beware that you will have to implement your own authentication service for this to work.
- more secure than solution 2
## Managing with Compose
**Cons:**
As your registry configuration grows more complex, dealing with it can quickly become tedious.
- you have to configure every docker daemon that wants to access your registry
It's highly recommended to use [Docker Compose](https://docs.docker.com/compose/) to facilitate operating your registry.
## Using Compose
It's highly recommended to use [Docker Compose](https://docs.docker.com/compose/) to facilitate managing your Registry configuration.
Here is a simple `docker-compose.yml` that does setup your registry exactly as above, with TLS enabled.
Here is a simple `docker-compose.yml` example that condenses everything explained so far:
```
registry:
@ -162,16 +142,32 @@ registry:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- /path/registry-data:/var/lib/registry
- /path/data:/var/lib/registry
- /path/certs:/certs
- /path/auth:/auth
```
:warning: replace `/path` by whatever directory that holds your `certs` and `auth` folder from above.
You can then start your registry with a simple
$ docker-compose up -d
docker-compose up -d
## Next
You are now ready to explore [the registry configuration](configuration.md)
You will find more specific and advanced informations in the following sections:
- [Configuration reference](configuration.md)
- [Working with notifications](notifications.md)
- [Registry API](spec/api.md)
- [Storage driver model](storagedrivers.md)
<!--
- [Glossary](glossary.md)
### Development resources
- [Building the registry](building.md)
- [Architecture notes](architecture.md)
-->

View File

@ -8,7 +8,6 @@ parent="smn_registry"
+++
<![end-metadata]-->
# Docker Registry
## What it is
@ -22,7 +21,7 @@ You should use the Registry if you want to:
* tightly control where your images are being stored
* fully own your images distribution pipeline
* integrate images storage and distribution into your inhouse development workflow
* integrate image storage and distribution tightly into your in-house development workflow
## Alternatives
@ -37,27 +36,31 @@ If you really need to work with older Docker versions, you should look into the
## TL;DR
```
# Start your registry
docker run -d -p 5000:5000 registry:2
Start your registry
docker run -d -p 5000:5000 --name registry registry:2
Pull (or build) some image from the hub
# Pull (or build) some image from the hub
docker pull ubuntu
# Tag the image so that it points to your registry
Tag the image so that it points to your registry
docker tag ubuntu localhost:5000/myfirstimage
# Push it
Push it
docker push localhost:5000/myfirstimage
# Pull it back
Pull it back
docker pull localhost:5000/myfirstimage
```
## Where to go next
Simple as that? Yes. Continue on to read the [overview of the registry](introduction.md).
Now stop your registry and remove all data
docker stop registry && docker rm -v registry
## Next
You should now read the [detailed introduction about the registry](introduction.md), or jump directly to [deployment instructions](deploying.md).

74
docs/insecure.md Normal file
View File

@ -0,0 +1,74 @@
<!--[metadata]>
+++
title = "Docker Registry 2.0"
description = "Deploying an insecure Registry"
keywords = ["registry, images, repository"]
[menu.main]
parent="smn_registry"
+++
<![end-metadata]-->
# Insecure Registry
While it's highly recommended to secure your registry using a TLS certificate issued by a known CA, you may alternatively decide to use self-signed certificates, or even use your registry over plain http.
You have to understand the downsides in doing so, and the extra burden in configuration.
## Deploying a plain HTTP registry
> :warning: it's not possible to use an insecure registry with basic authentication
This basically tells Docker to entirely disregard security for your registry.
1. edit the file `/etc/default/docker` so that there is a line that reads: `DOCKER_OPTS="--insecure-registry myregistrydomain.com:5000"` (or add that to existing `DOCKER_OPTS`)
2. restart your Docker daemon: on ubuntu, this is usually `service docker stop && service docker start`
**Pros:**
- easy to configure
**Cons:**
- very insecure
- you have to configure every docker daemon that wants to access your registry
## Using 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
Generate your own certificate:
```
mkdir -p certs && openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
```
Be sure to use the name `myregistrydomain.com` as a CN.
Stop and restart your registry.
Then you have to instruct every docker daemon to trust that certificate. This is done by copying the `domain.crt` file to `/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt` (don't forget to restart docker after doing so).
Stop and restart all your docker daemons.
**Pros:**
- more secure than the insecure registry solution
**Cons:**
- you have to configure every docker daemon that wants to access your registry
## Failing...
Failing to configure docker and trying to pull from a registry that is not using TLS will result in the following message:
```
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,please 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
```

View File

@ -11,24 +11,28 @@ weight=2
# Understanding the Registry
A registry is a storage and content delivery system, holding named Docker images, available in different tagged versions. For example, the image `distribution/registry`, with tags `2.0` and `latest`.
A registry is a storage and content delivery system, holding named Docker images, available in different tagged versions.
Users interact with a registry by using docker push and pull commands. For example, `docker pull myregistry.com/stevvooe/batman:voice`.
> Example: the image `distribution/registry`, with tags `2.0` and `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 driver like S3, Microsoft Azure and Ceph are also supported. People looking into using other storage backends may do so by writing their own driver implementing the [Storage API](storagedrivers.md).
Users interact with a registry by using docker push and pull commands.
Since securing access to your hosted images is paramount, the Registry natively supports TLS. You can also enforce basic authentication through a proxy like Nginx.
> Example: `docker pull registry-1.docker.io/distribution/registry:2.1`.
The Registry GitHub repository includes reference implementations for additional authentication and authorization methods. Only very large or public deployments are expected to extend the Registry in this way.
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, Ceph Rados, 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](storagedrivers.md).
Finally, the Registry includes a robust [notification system](notifications.md), calling webhooks in response to activity, and both extensive logging and reporting. Reporting is mostly useful for large installations that want to collect metrics. Currently, New Relic and Bugsnag are supported.
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 registry-1.docker.io/library/ubuntu` command
* `docker pull myregistrydomain:port/foo/bar` instructs docker to contact the registry located at `myregistrydomain:port` to find that image
* `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](https://docs.docker.com/reference/commandline/cli/).
@ -38,22 +42,14 @@ Running your own Registry is a great solution to integrate with and complement y
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 airgap environment.
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.
## Related information
- [Deploy a registry](deploying.md)
- [Configure a registry](configuration.md)
- [Authentication](authentication.md)
- [Working with notifications](notifications.md)
- [Registry API](spec/api.md)
- [Storage driver model](storagedrivers.md)
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)

View File

@ -1,3 +1,9 @@
<!--[metadata]>
+++
draft = "true"
+++
<![end-metadata]-->
# Registry as a pull through cache
A v2 Registry can be configured as a pull through cache. In this mode a Registry responds to all normal docker pull requests but stores all content locally.

View File

@ -1,36 +1,20 @@
<!--[metadata]>
+++
title = "Authentication for the Registry"
description = "Restricting access to your registry"
title = "Authentication for the Registry with a proxy"
description = "Restricting access to your registry using a proxy"
keywords = ["registry, service, images, repository, authentication"]
[menu.main]
parent="smn_registry"
weight=6
+++
<![end-metadata]-->
# Authentication
While running an unrestricted registry is certainly ok for development, secured local networks, or test setups, you should probably implement access restriction if you plan on making your registry available to a wider audience or through public internet.
The Registry supports two different authentication methods to get your there:
* direct authentication, through the use of a proxy
* delegated authentication, redirecting to a trusted token server
The first method is recommended for most people as the most straight-forward solution.
The second method requires significantly more investment, and only make sense if you want to fully configure ACLs and more control over the Registry integration into your global authorization and authentication systems.
## Direct authentication through a proxy
# Authenticating proxy with nginx
With this method, you implement basic authentication in a reverse proxy that sits in front of your registry.
Since the Docker engine uses basic authentication to negotiate access to the Registry, securing communication between docker engines and your proxy is absolutely paramount.
While this model gives you the ability to use whatever authentication backend you want through a secondary authentication mechanism implemented inside your proxy, it also requires that you move TLS termination from the Registry to the proxy itself.
Below is a simple example of secured basic authentication (using TLS), using nginx as a proxy.
Furthermore, introducing an extra http layer in your communication pipeline will make it more complex to deploy, maintain, and debug, and will possibly create issues (typically, nginx does buffer client requests to disk, opening the door to a host of problems if you are dealing with huge images and a lot of traffic).
### Requirements
@ -42,10 +26,9 @@ At this point, it's assumed that:
* you understand Docker security requirements, and how to configure your docker engines properly
* you have installed Docker Compose
* you have a `domain.crt` and `domain.key` files, for the CN `myregistrydomain.com` (or whatever domain name you want to use)
* these files are located inside the current directory, and there is nothing else in that directory
* it's HIGHLY recommended that you get a certificate from a known CA instead of self-signed certificates
* be sure you have stopped and removed any previously running registry (typically `docker stop registry && docker rm registry`)
* inside the current directory, you have a X509 `domain.crt` and `domain.key`, for the CN `myregistrydomain.com` (or whatever domain name you want to use)
* be sure you have stopped and removed any previously running registry (typically `docker stop registry && docker rm -v registry`)
### Setting things up
@ -56,8 +39,8 @@ Ready?
Run the following:
```
mkdir auth
mkdir data
mkdir -p auth
mkdir -p data
# This is the main nginx configuration you will use
cat <<EOF > auth/registry.conf
@ -87,8 +70,8 @@ server {
}
# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
proxy_pass http://docker-registry;
@ -102,10 +85,7 @@ server {
EOF
# Now, create a password file for "testuser" and "testpassword"
echo 'testuser:$2y$05$.nIfPAEgpWCh.rpts/XHX.UOfCRNtvMmYjh6sY/AZBmeg/dQyN62q' > auth/registry.password
# Alternatively you could have achieved the same thing with htpasswd
# htpasswd -Bbc auth/registry.password testuser testpassword
htpasswd -bn testuser testpassword > auth/htpasswd
# Copy over your certificate files
cp domain.crt auth
@ -165,21 +145,3 @@ Now:
* `service docker stop && service docker start` (or any other way you use to restart docker)
* `docker-compose up -d` to bring your registry up
## Token-based delegated authentication
This is **advanced**.
You will find [background information here](./spec/auth/token.md), [configuration information here](configuration.md#auth).
Beware that you will have to implement your own authentication service for this to work (though there exist third-party open-source implementations).
# Manual Set-up
If you'd like to manually configure your HTTP server, here are a few requirements that are absolutely necessary for the docker client to be able to interface with it:
- Each response needs to have the header "Docker-Distribution-Api-Version registry/2.0" set, even (especially) if there is a 401 or 404 error response. Make sure using cURL that this header is provided. Note: If you're using Nginx, this functionality is only available since 1.7.5 using the "always" add_header directive, or when compiling with the "more_set_headers" module.
- A large enough maximum for client body size, preferably unlimited. Because images can be pretty big, the very low default maximum size of most HTTP servers won't be sufficient to be able to upload the files.
- Support for chunked transfer encoding.

View File

@ -9,8 +9,6 @@ weight=5
+++
<![end-metadata]-->
# Notifications
The Registry supports sending webhook notifications in response to events