forked from distribution/distribution
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Revert "Remove old documentation source, add README on migration"
This reverts commit da8bcbb. Signed-off-by: Sebastiaan van Stijn <[email protected]>
- Loading branch information
Showing
35 changed files
with
2,941 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM docs/base:oss | ||
MAINTAINER Docker Docs <[email protected]> | ||
|
||
ENV PROJECT=registry | ||
|
||
# To get the git info for this repo | ||
COPY . /src | ||
RUN rm -rf /docs/content/$PROJECT/ | ||
COPY . /docs/content/$PROJECT/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
.PHONY: all default docs docs-build docs-shell shell test | ||
|
||
# to allow `make DOCSDIR=docs docs-shell` (to create a bind mount in docs) | ||
DOCS_MOUNT := $(if $(DOCSDIR),-v $(CURDIR)/$(DOCSDIR):/$(DOCSDIR)) | ||
|
||
# to allow `make DOCSPORT=9000 docs` | ||
DOCSPORT := 8000 | ||
|
||
# Get the IP ADDRESS | ||
DOCKER_IP=$(shell python -c "import urlparse ; print urlparse.urlparse('$(DOCKER_HOST)').hostname or ''") | ||
HUGO_BASE_URL=$(shell test -z "$(DOCKER_IP)" && echo localhost || echo "$(DOCKER_IP)") | ||
HUGO_BIND_IP=0.0.0.0 | ||
|
||
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null) | ||
GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g") | ||
DOCKER_DOCS_IMAGE := registry-docs$(if $(GIT_BRANCH_CLEAN),:$(GIT_BRANCH_CLEAN)) | ||
|
||
DOCKER_RUN_DOCS := docker run --rm -it $(DOCS_MOUNT) -e AWS_S3_BUCKET -e NOCACHE | ||
|
||
# for some docs workarounds (see below in "docs-build" target) | ||
GITCOMMIT := $(shell git rev-parse --short HEAD 2>/dev/null) | ||
|
||
default: docs | ||
|
||
docs: docs-build | ||
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP) | ||
|
||
docs-draft: docs-build | ||
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 -e DOCKERHOST "$(DOCKER_DOCS_IMAGE)" hugo server --buildDrafts="true" --port=$(DOCSPORT) --baseUrl=$(HUGO_BASE_URL) --bind=$(HUGO_BIND_IP) | ||
|
||
docs-shell: docs-build | ||
$(DOCKER_RUN_DOCS) -p $(if $(DOCSPORT),$(DOCSPORT):)8000 "$(DOCKER_DOCS_IMAGE)" bash | ||
|
||
docs-build: | ||
docker build -t "$(DOCKER_DOCS_IMAGE)" . | ||
|
||
test: docs-build | ||
$(DOCKER_RUN_DOCS) "$(DOCKER_DOCS_IMAGE)" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<!--[metadata]> | ||
+++ | ||
title = "Compatibility" | ||
description = "describes get by digest pitfall" | ||
keywords = ["registry, manifest, images, tags, repository, distribution, digest"] | ||
[menu.main] | ||
parent="smn_registry_ref" | ||
weight=9 | ||
+++ | ||
<![end-metadata]--> | ||
|
||
# Registry Compatibility | ||
|
||
## 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 | ||
will cause the Engine to receive a manifest it cannot use and the pull will fail.* | ||
|
||
## 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. The | ||
registry 2.3 supports all three manifest types and in order to be compatible | ||
with older Docker engines will, in certain cases, do an on-the-fly | ||
transformation of a manifest before serving the JSON in the response. | ||
|
||
This conversion has some implications for pulling manifests by digest and this | ||
document enumerate 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 will no longer match. | ||
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 will always store and | ||
serve _Schema 1_ manifests. The Docker Engine 1.10 will first | ||
attempt 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.9 and Older | ||
|
||
The Docker Engine will construct a _Schema 1_ manifest which the | ||
registry will persist to disk. | ||
|
||
When the manifest is pulled by digest or tag with any docker version, a | ||
_Schema 1_ manifest will be returned. | ||
|
||
### Manifest Push with Docker 1.10 | ||
|
||
The docker engine will construct a _Schema 2_ manifest which the | ||
registry will persist to disk. | ||
|
||
When the manifest is pulled by digest or tag with Docker Engine 1.10, a | ||
_Schema 2_ manifest will be returned. The 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 will not happen in the registry. If this were to happen | ||
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 will cause the Engine to receive a manifest it cannot use and the | ||
pull will fail. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
<!--[metadata]> | ||
+++ | ||
title = "Deploying a registry server" | ||
description = "Explains how to deploy a registry" | ||
keywords = ["registry, on-prem, images, tags, repository, distribution, deployment"] | ||
[menu.main] | ||
parent="smn_registry" | ||
weight=3 | ||
+++ | ||
<![end-metadata]--> | ||
|
||
# Deploying a registry server | ||
|
||
You need to [install Docker version 1.6.0 or newer](/engine/installation/index.md). | ||
|
||
## Running on localhost | ||
|
||
Start your registry: | ||
|
||
docker run -d -p 5000:5000 --restart=always --name registry registry:2 | ||
|
||
You can now use it with docker. | ||
|
||
Get any image from the hub and tag it to point to your registry: | ||
|
||
docker pull ubuntu && docker tag ubuntu localhost:5000/ubuntu | ||
|
||
... then push it to your registry: | ||
|
||
docker push localhost:5000/ubuntu | ||
|
||
... then pull it back from your registry: | ||
|
||
docker pull localhost:5000/ubuntu | ||
|
||
To stop your registry, you would: | ||
|
||
docker stop registry && docker rm -v registry | ||
|
||
## Storage | ||
|
||
By default, your registry data is persisted as a [docker volume](/engine/tutorials/dockervolumes.md) on the host filesystem. Properly understanding volumes is essential if you want to stick with a local filesystem storage. | ||
|
||
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: | ||
|
||
docker run -d -p 5000:5000 --restart=always --name registry \ | ||
-v `pwd`/data:/var/lib/registry \ | ||
registry:2 | ||
|
||
### Alternatives | ||
|
||
You should usually consider using [another storage backend](./storage-drivers/index.md) instead of the local filesystem. Use the [storage configuration options](./configuration.md#storage) to configure an alternate storage backend. | ||
|
||
Using one of these will allow you to more easily scale your registry, and leverage your storage redundancy and availability features. | ||
|
||
## Running a domain registry | ||
|
||
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. | ||
|
||
### Get a certificate | ||
|
||
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. | ||
|
||
Create a `certs` directory: | ||
|
||
mkdir -p certs | ||
|
||
Then move and/or rename your crt file to: `certs/domain.crt`, and your key file to: `certs/domain.key`. | ||
|
||
Make sure you stopped your registry from the previous steps, then start your registry again with TLS enabled: | ||
|
||
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 \ | ||
registry:2 | ||
|
||
You should now be able to access your registry from another docker host: | ||
|
||
docker pull ubuntu | ||
docker tag ubuntu myregistrydomain.com:5000/ubuntu | ||
docker push myregistrydomain.com:5000/ubuntu | ||
docker pull myregistrydomain.com:5000/ubuntu | ||
|
||
#### Gotcha | ||
|
||
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: | ||
|
||
cat domain.crt intermediate-certificates.pem > certs/domain.crt | ||
|
||
### 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). | ||
|
||
### Alternatives | ||
|
||
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). | ||
|
||
## 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) | ||
|
||
If any of these are different, the registry will have trouble serving requests. | ||
As an example, if you're using the filesystem driver, all registry instances | ||
must have access to the same filesystem root, which means they should be in | ||
the same machine. For other drivers, such as s3 or azure, they should be | ||
accessing the same resource, and will likely share an identical configuration. | ||
The _HTTP Secret_ coordinates uploads, so also must be the same across | ||
instances. Configuring different redis instances will work (at the time | ||
of writing), but will not be optimal if the instances are not shared, causing | ||
more requests to be 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 will secure 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 will always return 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). | ||
|
||
> **Warning**: You **cannot** use authentication with an insecure registry. You have to [configure TLS first](#running-a-domain-registry) for this to work. | ||
First create a password file with one entry for the user "testuser", with password "testpassword": | ||
|
||
mkdir auth | ||
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd | ||
|
||
Make sure you stopped your registry from the previous step, then start it again: | ||
|
||
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 | ||
|
||
You should now be able to: | ||
|
||
docker login myregistrydomain.com:5000 | ||
|
||
And then push and pull images as an authenticated user. | ||
|
||
#### Gotcha | ||
|
||
Seeing X509 errors is usually a sign you are trying to use self-signed certificates, and failed to [configure your docker daemon properly](insecure.md). | ||
|
||
### Alternatives | ||
|
||
1. You may want to leverage more advanced basic auth implementations through a proxy design, in front of the registry. You will find examples of such patterns in the [recipes list](recipes/index.md). | ||
|
||
2. Alternatively, the Registry also supports delegated authentication, redirecting users to a specific, trusted token server. That approach requires significantly more investment, and only makes sense if you want to fully configure ACLs and more control over the Registry integration into your global authorization and authentication systems. | ||
|
||
You will find [background information here](spec/auth/token.md), and [configuration information here](configuration.md#auth). | ||
|
||
Beware that you will have to implement your own authentication service for this to work, or leverage a third-party implementation. | ||
|
||
## Managing with Compose | ||
|
||
As your registry configuration grows more complex, dealing with it can quickly become tedious. | ||
|
||
It's highly recommended to use [Docker Compose](/compose/index.md) to facilitate operating your registry. | ||
|
||
Here is a simple `docker-compose.yml` example that condenses everything explained so far: | ||
|
||
``` | ||
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 | ||
``` | ||
|
||
> **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 | ||
|
||
## Next | ||
|
||
You will find more specific and advanced informations 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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<!--[metadata]> | ||
+++ | ||
title = "Deprecated Features" | ||
description = "describes deprecated functionality" | ||
keywords = ["registry, manifest, images, signatures, repository, distribution, digest"] | ||
[menu.main] | ||
parent="smn_registry_ref" | ||
weight=8 | ||
+++ | ||
<![end-metadata]--> | ||
|
||
# Docker Registry Deprecation | ||
|
||
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. |
Oops, something went wrong.