github.com/npaton/distribution@v2.3.1-rc.0+incompatible/docs/deploying.md (about) 1 <!--[metadata]> 2 +++ 3 title = "Deploying a registry server" 4 description = "Explains how to deploy a registry" 5 keywords = ["registry, on-prem, images, tags, repository, distribution, deployment"] 6 [menu.main] 7 parent="smn_registry" 8 weight=3 9 +++ 10 <![end-metadata]--> 11 12 # Deploying a registry server 13 14 You need to [install Docker version 1.6.0 or newer](https://docs.docker.com/installation/). 15 16 ## Running on localhost 17 18 Start your registry: 19 20 docker run -d -p 5000:5000 --restart=always --name registry registry:2 21 22 You can now use it with docker. 23 24 Get any image from the hub and tag it to point to your registry: 25 26 docker pull ubuntu && docker tag ubuntu localhost:5000/ubuntu 27 28 ... then push it to your registry: 29 30 docker push localhost:5000/ubuntu 31 32 ... then pull it back from your registry: 33 34 docker pull localhost:5000/ubuntu 35 36 To stop your registry, you would: 37 38 docker stop registry && docker rm -v registry 39 40 ## Storage 41 42 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. 43 44 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: 45 46 docker run -d -p 5000:5000 --restart=always --name registry \ 47 -v `pwd`/data:/var/lib/registry \ 48 registry:2 49 50 ### Alternatives 51 52 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. 53 54 Using one of these will allow you to more easily scale your registry, and leverage your storage redundancy and availability features. 55 56 ## Running a domain registry 57 58 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. 59 60 ### Get a certificate 61 62 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. 63 64 Create a `certs` directory: 65 66 mkdir -p certs 67 68 Then move and/or rename your crt file to: `certs/domain.crt`, and your key file to: `certs/domain.key`. 69 70 Make sure you stopped your registry from the previous steps, then start your registry again with TLS enabled: 71 72 docker run -d -p 5000:5000 --restart=always --name registry \ 73 -v `pwd`/certs:/certs \ 74 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ 75 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ 76 registry:2 77 78 You should now be able to access your registry from another docker host: 79 80 docker pull ubuntu 81 docker tag ubuntu myregistrydomain.com:5000/ubuntu 82 docker push myregistrydomain.com:5000/ubuntu 83 docker pull myregistrydomain.com:5000/ubuntu 84 85 #### Gotcha 86 87 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: 88 89 cat domain.crt intermediate-certificates.pem > certs/domain.crt 90 91 ### Alternatives 92 93 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). 94 95 ## Load Balancing Considerations 96 97 One may want to use a load balancer to distribute load, terminate TLS or 98 provide high availability. While a full load balancing setup is outside the 99 scope of this document, there are a few considerations that can make the process 100 smoother. 101 102 The most important aspect is that a load balanced cluster of registries must 103 share the same resources. For the current version of the registry, this means 104 the following must be the same: 105 106 - Storage Driver 107 - HTTP Secret 108 - Redis Cache (if configured) 109 110 If any of these are different, the registry will have trouble serving requests. 111 As an example, if you're using the filesystem driver, all registry instances 112 must have access to the same filesystem root, which means they should be in 113 the same machine. For other drivers, such as s3 or azure, they should be 114 accessing the same resource, and will likely share an identical configuration. 115 The _HTTP Secret_ coordinates uploads, so also must be the same across 116 instances. Configuring different redis instances will work (at the time 117 of writing), but will not be optimal if the instances are not shared, causing 118 more requests to be directed to the backend. 119 120 Getting the headers correct is very important. For all responses to any 121 request under the "/v2/" url space, the `Docker-Distribution-API-Version` 122 header should be set to the value "registry/2.0", even for a 4xx response. 123 This header allows the docker engine to quickly resolve authentication realms 124 and fallback to version 1 registries, if necessary. Confirming this is setup 125 correctly can help avoid problems with fallback. 126 127 In the same train of thought, you must make sure you are properly sending the 128 `X-Forwarded-Proto`, `X-Forwarded-For` and `Host` headers to their "client-side" 129 values. Failure to do so usually makes the registry issue redirects to internal 130 hostnames or downgrading from https to http. 131 132 A properly secured registry should return 401 when the "/v2/" endpoint is hit 133 without credentials. The response should include a `WWW-Authenticate` 134 challenge, providing guidance on how to authenticate, such as with basic auth 135 or a token service. If the load balancer has health checks, it is recommended 136 to configure it to consider a 401 response as healthy and any other as down. 137 This will secure your registry by ensuring that configuration problems with 138 authentication don't accidentally expose an unprotected registry. If you're 139 using a less sophisticated load balancer, such as Amazon's Elastic Load 140 Balancer, that doesn't allow one to change the healthy response code, health 141 checks can be directed at "/", which will always return a `200 OK` response. 142 143 ## Restricting access 144 145 Except for registries running on secure local networks, registries should always implement access restrictions. 146 147 ### Native basic auth 148 149 The simplest way to achieve access restriction is through basic authentication (this is very similar to other web servers' basic authentication mechanism). 150 151 > **Warning**: You **cannot** use authentication with an insecure registry. You have to [configure TLS first](#running-a-domain-registry) for this to work. 152 153 First create a password file with one entry for the user "testuser", with password "testpassword": 154 155 mkdir auth 156 docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd 157 158 Make sure you stopped your registry from the previous step, then start it again: 159 160 docker run -d -p 5000:5000 --restart=always --name registry \ 161 -v `pwd`/auth:/auth \ 162 -e "REGISTRY_AUTH=htpasswd" \ 163 -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ 164 -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ 165 -v `pwd`/certs:/certs \ 166 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ 167 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ 168 registry:2 169 170 You should now be able to: 171 172 docker login myregistrydomain.com:5000 173 174 And then push and pull images as an authenticated user. 175 176 #### Gotcha 177 178 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). 179 180 ### Alternatives 181 182 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.md). 183 184 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. 185 186 You will find [background information here](spec/auth/token.md), and [configuration information here](configuration.md#auth). 187 188 Beware that you will have to implement your own authentication service for this to work, or leverage a third-party implementation. 189 190 ## Managing with Compose 191 192 As your registry configuration grows more complex, dealing with it can quickly become tedious. 193 194 It's highly recommended to use [Docker Compose](https://docs.docker.com/compose/) to facilitate operating your registry. 195 196 Here is a simple `docker-compose.yml` example that condenses everything explained so far: 197 198 ``` 199 registry: 200 restart: always 201 image: registry:2 202 ports: 203 - 5000:5000 204 environment: 205 REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt 206 REGISTRY_HTTP_TLS_KEY: /certs/domain.key 207 REGISTRY_AUTH: htpasswd 208 REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd 209 REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm 210 volumes: 211 - /path/data:/var/lib/registry 212 - /path/certs:/certs 213 - /path/auth:/auth 214 ``` 215 216 > **Warning**: replace `/path` by whatever directory that holds your `certs` and `auth` folder from above. 217 218 You can then start your registry with a simple 219 220 docker-compose up -d 221 222 ## Next 223 224 You will find more specific and advanced informations in the following sections: 225 226 - [Configuration reference](configuration.md) 227 - [Working with notifications](notifications.md) 228 - [Advanced "recipes"](recipes.md) 229 - [Registry API](spec/api.md) 230 - [Storage driver model](storagedrivers.md) 231 - [Token authentication](spec/auth/token.md)