|
|
|
@ -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
|
|
|
|
|
</th>
|
|
|
|
|
<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.
|
|
|
|
|
</td>
|
|
|
|
|
</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
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
<table>
|
|
|
|
|
<tr>
|
|
|
|
|
<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>
|
|
|
|
|
$ 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;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|