Updating with new RC work
Fixing typos and adding tables Updating with testing material Tweak after read through Adding in Stephen's comments Adding in Richard's comments. Fixing the broken images closes issue #363 Another try Signed-off-by: Mary Anthony <mary@docker.com>
This commit is contained in:
parent
e57319cc60
commit
b939d6d118
6 changed files with 1309 additions and 315 deletions
|
@ -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**. |
|
| **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. |
|
| **dist** | An _experimental_ tool to provide distribution, oriented functionality without the `docker` daemon. |
|
||||||
| **specifications** | _Distribution_ related specifications are available in [docs/spec](docs/spec) |
|
| **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?
|
### How does this integrate with Docker engine?
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,147 @@
|
||||||
# Docker Compose V1 + V2 registry
|
# Docker Compose V1 + V2 registry
|
||||||
|
|
||||||
This compose configuration will setup a v1 and v2 registry behind an nginx
|
This compose configuration configures a `v1` and `v2` registry behind an `nginx`
|
||||||
proxy. By default the combined registry may be accessed at localhost:5000.
|
proxy. By default, you can access the combined registry 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.
|
|
||||||
|
|
||||||
## Prerequisites
|
The configuration does not support pushing images to `v2` and pulling from `v1`.
|
||||||
Install [docker-compose](https://github.com/docker/compose)
|
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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
## How to run
|
|
||||||
```
|
|
||||||
$ docker-compose up
|
$ 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
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
but is insufficient for production. For production you should configure and
|
||||||
build your own custom registry image from the `docker/distribution` code.
|
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
|
## Simple example with the official image
|
||||||
|
|
||||||
In this section, you create a local registry using Docker's official image. You
|
In this section, you create a container running Docker's official registry
|
||||||
push an image to, and then pull the same image from, the registry. This a good
|
image. You push an image to, and then pull the same image from, this registry.
|
||||||
exercise for understanding the basic interactions a client has with a
|
This a good exercise for understanding the basic interactions a client has with
|
||||||
local registry.
|
a local registry.
|
||||||
|
|
||||||
1. Install Docker.
|
1. Install Docker.
|
||||||
|
|
||||||
|
@ -30,7 +34,8 @@ local registry.
|
||||||
|
|
||||||
$ docker run hello-world
|
$ 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.
|
3. Start a registry service on your localhost.
|
||||||
|
|
||||||
|
@ -68,11 +73,40 @@ local registry.
|
||||||
|
|
||||||
You should see your new image in your listing.
|
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
|
$ 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
|
||||||
|
|
||||||
6. Remove all the unused images from your local environment:
|
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.
|
||||||
|
|
||||||
|
8. Remove all the unused images from your local environment:
|
||||||
|
|
||||||
$ docker rmi -f $(docker images -q -a )
|
$ docker rmi -f $(docker images -q -a )
|
||||||
|
|
||||||
|
@ -86,7 +120,7 @@ local registry.
|
||||||
registry 2.0 bbf0b6ffe923 3 days ago 545.1 MB
|
registry 2.0 bbf0b6ffe923 3 days ago 545.1 MB
|
||||||
golang 1.4 121a93c90463 5 days ago 514.9 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
|
$ docker run hello-mine
|
||||||
Unable to find image 'hello-mine:latest' locally
|
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
|
The `run` command fails because your new image doesn't exist in the Docker public
|
||||||
registry.
|
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
|
$ docker run localhost:5000/hello-mine
|
||||||
|
|
||||||
|
@ -128,7 +162,7 @@ factors:
|
||||||
access and/or authentication
|
access and/or authentication
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
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.
|
you are serving images to the public or internally to your company only.
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -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
|
this by specifying options on the command line or, more typically, by writing a
|
||||||
registry configuration file. The configuration file is in YAML format.
|
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:
|
configuration file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
@ -203,7 +237,6 @@ notifications:
|
||||||
disabled: true
|
disabled: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
This configuration is very basic and you can see it would present some problems
|
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
|
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
|
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
|
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
|
the `https` protocol. Enabling TLS on the server is the minimum layer of
|
||||||
security recommended for running a registry behind a corporate firewall. The
|
security recommended for running a registry behind a corporate firewall. One way
|
||||||
easiest way to do this is to build your own registry image.
|
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
|
1. [Download the registry
|
||||||
source](https://github.com/docker/distribution/releases/tag/v2.0.0).
|
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 \
|
-newkey rsa:2048 -nodes -keyout certs/domain.key \
|
||||||
-x509 -days 365 -out certs/domain.crt
|
-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
|
$ ls certs
|
||||||
your base image.
|
domain.crt domain.key
|
||||||
|
|
||||||
1. Edit the `Dockerfile` and add a `CERTS_PATH` environment variable.
|
When you build this container, the `certs` directory and its contents
|
||||||
|
automatically get copied also.
|
||||||
|
|
||||||
ENV CERTS_PATH /etc/docker/registry/certs
|
### Add TLS to the configuration
|
||||||
|
|
||||||
2. Add a line to make the `CERTS_PATH` in the filesystem.
|
The `distribution` repo includes sample registry configurations in the `cmd`
|
||||||
|
subdirectory. In this section, you edit one of these configurations to add TLS
|
||||||
RUN mkdir -v $CERTS_PATH
|
support.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
1. Edit the `./cmd/registry/config.yml` file.
|
1. Edit the `./cmd/registry/config.yml` file.
|
||||||
|
|
||||||
|
@ -311,8 +310,8 @@ your base image.
|
||||||
debug:
|
debug:
|
||||||
addr: localhost:5001
|
addr: localhost:5001
|
||||||
tls:
|
tls:
|
||||||
certificate: /etc/docker/registry/certs/domain.crt
|
certificate: /go/src/github.com/docker/distribution/certs/domain.crt
|
||||||
key: /etc/docker/registry/certs/domain.key
|
key: /go/src/github.com/docker/distribution/certs/domain.key
|
||||||
|
|
||||||
You provide the paths to the certificates in the container. If you want
|
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`
|
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.
|
4. Save and close the file.
|
||||||
|
|
||||||
|
|
||||||
### Run your new image
|
### Build and run your registry image
|
||||||
|
|
||||||
1. Build your registry image.
|
1. Build your registry image.
|
||||||
|
|
||||||
|
@ -329,138 +328,238 @@ your base image.
|
||||||
|
|
||||||
2. Run your new 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:
|
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
|
|
||||||
|
|
||||||
3. Use `curl` to verify that you can connect over `https`.
|
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
|
### Do some housekeeping
|
||||||
|
|
||||||
This section describes how to configure storage middleware in a registry.
|
1. Remove any previous images.
|
||||||
Middleware allows the registry to server layers via a content delivery network
|
|
||||||
(CDN). This is useful for reducing requests to the storage layer.
|
|
||||||
|
|
||||||
Currently, the registry supports [Amazon
|
$ docker rmi -f $(docker images -q -a )
|
||||||
Cloudfront](http://aws.amazon.com/cloudfront/). You can only use Cloudfront in
|
|
||||||
conjunction with the S3 storage driver.
|
|
||||||
|
|
||||||
<table>
|
This step is a house keeping step. It prevents you from mistakenly picking up
|
||||||
<tr>
|
an old image as you work through this example.
|
||||||
<th>Parameter</th>
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>name</code></td>
|
|
||||||
<td>The storage middleware name. Currently <code>cloudfront</code> is an accepted value.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>disabled<code></td>
|
|
||||||
<td>Set to <code>false</code> to easily disable the middleware.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>options:</code></td>
|
|
||||||
<td>
|
|
||||||
A set of key/value options to configure the middleware.
|
|
||||||
<ul>
|
|
||||||
<li><code>baseurl:</code> The Cloudfront base URL.</li>
|
|
||||||
<li><code>privatekey:</code> The location of your AWS private key on the filesystem. </li>
|
|
||||||
<li><code>keypairid:</code> The ID of your Cloudfront keypair. </li>
|
|
||||||
<li><code>duration:</code> The duration in minutes for which the URL is valid. Default is 20. </li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
The following example illustrates these values:
|
2. Edit the `distribution/cmd/registry/config.yml` file and remove the `tls` block.
|
||||||
|
|
||||||
```
|
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.
|
||||||
|
|
||||||
>**Note**: Cloudfront keys exist separately to other AWS keys. See
|
### Configure SSL
|
||||||
>[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.
|
||||||
|
|
||||||
**TODO(stevvooe): Need a "best practice" configuration overview. Perhaps, we can point to a documentation section.
|
This directory contains configuration files for Nginx and both registries.
|
||||||
|
|
||||||
|
2. Use SSL to generate some self-signed certificates.
|
||||||
|
|
||||||
# Configure nginx to deploy alongside v1 registry
|
$ openssl req \
|
||||||
|
-newkey rsa:2048 -nodes -keyout domain.key \
|
||||||
|
-x509 -days 365 -out domain.crt
|
||||||
|
|
||||||
This sections describes how to configure nginx to proxy to both a v1 and v2
|
This command prompts you for basic information it needs to create certificates.
|
||||||
registry. Nginx will handle routing of to the correct registry based on the
|
|
||||||
URL and Docker client version.
|
|
||||||
|
|
||||||
## Example configuration
|
3. Edit the `Dockerfile`and add the following lines.
|
||||||
With v1 registry running at `localhost:5001` and v2 registry running at
|
|
||||||
`localhost:5002`. Add this to `/etc/nginx/conf.d/registry.conf`.
|
COPY domain.crt /etc/nginx/domain.crt
|
||||||
```
|
COPY domain.key /etc/nginx/domain.key
|
||||||
server {
|
|
||||||
listen 5000;
|
When you are done, the file looks like the following.
|
||||||
server_name localhost;
|
|
||||||
|
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
|
||||||
|
|
||||||
|
4. Save and close the `Dockerfile` file.
|
||||||
|
|
||||||
|
5. Edit the `registry.conf` file and add the following configuration.
|
||||||
|
|
||||||
ssl on;
|
ssl on;
|
||||||
ssl_certificate /etc/docker/registry/certs/domain.crt;
|
ssl_certificate /etc/nginx/domain.crt;
|
||||||
ssl_certificate_key /etc/docker/registry/certs/domain.key;
|
ssl_certificate_key /etc/nginx/domain.key;
|
||||||
|
|
||||||
client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads
|
This is an `nginx` configuration file.
|
||||||
|
|
||||||
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
|
6. Save and close the `registry.conf` file.
|
||||||
chunked_transfer_encoding on;
|
|
||||||
|
|
||||||
location /v2/ {
|
### Build and run
|
||||||
# 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy_pass http://localhost:5002;
|
1. Go up to the `distribution/contrib/compose` directory
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
This directory includes a single `docker-compose.yml` configuration.
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Running nginx without a v1 registry
|
nginx:
|
||||||
When running a v2 registry behind nginx without a v1 registry, the `/v1/` endpoint should
|
build: "nginx"
|
||||||
be explicitly configured to return a 404 if only the `/v2/` route is proxied. This
|
ports:
|
||||||
is needed due to the v1 registry fallback logic within Docker 1.5 and 1.6 which will attempt
|
- "5000:5000"
|
||||||
to retrieve content from the v1 endpoint if no content was retrieved from v2.
|
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.
|
||||||
|
|
||||||
Add this location block to explicitly block v1 requests.
|
|
||||||
```
|
|
||||||
localhost /v1/ {
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
|
@ -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
|
events. The events are queued into a registry-internal broadcast system which
|
||||||
queues and dispatches events to [_Endpoints_](#endpoints).
|
queues and dispatches events to [_Endpoints_](#endpoints).
|
||||||
|
|
||||||
![](/distribution/images/notifications.png)
|
![](../images/notifications.png)
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
|
|
|
@ -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
|
or pulling images from the registry. The Docker Registry includes several
|
||||||
optional features that you can configure according to your needs.
|
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
|
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
|
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)
|
- [Storage driver model](storagedrivers.md)
|
||||||
- [Working with notifications](notifications.md)
|
- [Working with notifications](notifications.md)
|
||||||
- [Registry API v2](spec/api.md)
|
- [Registry API v2](spec/api.md)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue