---
title: Charmhub | Deploy Docker Registry using Charmhub - The Open Operator Collection
description: Deploy the latest version of Docker Registry on any cloud. Registry for
  docker images
url: https://charmhub.io/docker-registry
---

# Docker Registry

[Canonical Kubernetes](https://charmhub.io/publisher/containers "View all packages from Canonical Kubernetes")

* [Canonical Kubernetes](https://charmhub.io/publisher/containers "View all packages from Canonical Kubernetes")

Platform:

jammy

24.04

22.04

20.04

18.04

16.04

stable 95bea90

```
juju deploy docker-registry
```

[Learn to deploy on juju >](https://juju.is/docs/juju/manage-applications)

---

Share your thoughts on this charm with the community on discourse.

[Join the discussion](https://discourse.charmhub.io/)

This charm provides a registry for storage and distribution of docker images.
See <https://docs.docker.com/registry/> for details.

## [Deployment](https://charmhub.io/docker-registry#p-17659-deployment)

The registry is deployed as a stand alone application and supports integration
with clients that implement the [docker-registry](https://github.com/juju-solutions/interface-docker-registry) interface.

### [Standalone Registry](https://charmhub.io/docker-registry#p-17659-standalone-registry)

For testing purposes, a simple, insecure registry can be deployed with:

```
juju deploy docker-registry
```

### [Secure Registry with TLS](https://charmhub.io/docker-registry#p-17659-secure-registry-with-tls)

This charm supports TLS via the `tls-certificates` relation. This can
be enabled by integrating it with a TLS provider, such as `easyrsa`:

```
juju deploy docker-registry
juju deploy easyrsa

juju integrate easyrsa docker-registry
```

> Note: For Juju 2.9.X `add-relation` command must be used instead of `integrate`.

This charm also supports configuration-based TLS, which does not require a
relation to a TLS provider. Instead, transfer required files and configure
this charm as follows:

```
juju scp /my/local/ca.pem docker-registry/0:/home/ubuntu/ca.pem
juju scp /my/local/cert.crt docker-registry/0:/home/ubuntu/cert.crt
juju scp /my/local/cert.key docker-registry/0:/home/ubuntu/cert.key

juju config docker-registry \
  tls-ca-path=/home/ubuntu/ca.pem \
  tls-cert-path=/home/ubuntu/cert.crt \
  tls-key-path=/home/ubuntu/cert.key
```

Finally, custom TLS data may be provided as base64-encoded config options to
the charm. The configured `tls-*-blob` data will be written to corresponding
configured `tls-*-path` files:

```
juju config docker-registry \
  tls-ca-blob=$(base64 /path/to/ca) \
  tls-cert-blob=$(base64 /path/to/cert) \
  tls-key-blob=$(base64 /path/to/key)
```

### [Proxied Registry](https://charmhub.io/docker-registry#p-17659-proxied-registry)

This charm supports an `http` proxy relation that allows operators to
control how the registry is exposed on the network. This is achieved by
integrating it with a proxy provider, such as `haproxy`:

```
juju deploy docker-registry
juju deploy haproxy

juju integrate haproxy docker-registry
```

When multiple `docker-registry` units are deployed, the proxy will be
configured with one unit chosen as the primary proxied service with remaining
units configured as backups. This provides a highly available deployment that
will fail over to a backup if the primary service becomes unavailable.

> Note: HA deployments require the proxy to be in `active-passive` peering
> mode, which is the default for `haproxy`.

#### TLS/SSL

TLS is supported between `haproxy` and `docker-registry`, though some manual
configuration is required. You will need to transfer the registry CA certificate
to the proxy so the registry certificate can be verified. The path to the
CA must match on both registry and proxy units. For example:

```
juju exec --unit haproxy/$UNIT_NUM 'mkdir -p /etc/docker/registry'
juju exec --unit haproxy/$UNIT_NUM 'chown ubuntu:ubuntu /etc/docker/registry'
juju scp docker-registry/$UNIT_NUM:/etc/docker/registry/ca.crt ./ca.crt
juju scp ./ca.crt haproxy/$UNIT_NUM:/etc/docker/registry
```

### [Kubernetes Integration](https://charmhub.io/docker-registry#p-17659-kubernetes-integration)

See the [Private Docker Registry](https://www.ubuntu.com/kubernetes/docs/docker-registry) documentation for details on
integrating this charm with Kubernetes.

## [Actions](https://charmhub.io/docker-registry#p-17659-actions)

### [Adding Images](https://charmhub.io/docker-registry#p-17659-adding-images)

To make an image available in the deployed registry, it must be tagged and
pushed. This charm provides the `push` action to do this:

```
juju run docker-registry/0 push \
  image=<image> pull=<True|False> tag=<optional-tag-name>
```

This action will always tag and push a local image to the registry. By
specifying `pull=True` (the default), the action will first pull the
given `image` and subsequently tag/push it.

The default image tag is `net_loc/name:version`, where `net_loc` is the
`http-host` config option or `http[s]://[private-ip]:[port]` if config is not
set. The image tag can be overridden by specifying the `tag` action parameter.

### [Listing Images](https://charmhub.io/docker-registry#p-17659-listing-images)

List images known to the registry with the `images` action:

```
juju run docker-registry/0 images \
  options=<extra-args> repository=<repository[:tag]>
```

This runs `docker images` on the registry machine. The optional `options` and
`repository` parameters are passed through to the underlying command. For
example, show non-truncated output with numeric image IDs:

```
juju run docker-registry/0 images \
  options="--no-trunc --quiet"
```

### [Removing Images](https://charmhub.io/docker-registry#p-17659-removing-images)

Remove images from the registry with the `rmi` action:

```
juju run docker-registry/0 rmi \
  options=<extra-args> image=<image [image...]>
```

This runs `docker rmi` on the registry machine. The image name (or space
separated names) must be specified using the `image` parameter. The optional
`options` parameter is passed through to the underlying command. For
example, remove the ubuntu:18.04 image without deleting untagged parents:

```
juju run docker-registry/0 rmi \
  options="--no-prune" image="ubuntu:18.04"
```

### [Starting/Stopping](https://charmhub.io/docker-registry#p-17659-startingstopping)

The registry is configured to start automatically with the dockerd system
service. It can also be started or stopped with charm actions as follows:

```
juju run docker-registry/0 stop
juju run docker-registry/0 start
```

### [Authentication](https://charmhub.io/docker-registry#p-17659-authentication)

This charm supports basic (htpasswd) as well as token-based authentication.
Configure either method as follows:

```
juju config docker-registry \
  auth-basic-user='admin' \
  auth-basic-password='redrum'

juju config docker-registry \
  auth-token-issuer='auth.example.com' \
  auth-token-realm='myorg' \
  auth-token-root-certs='$(base64 /path/to/file)' \
  auth-token-service='myapp'
```

### [Delete by digest](https://charmhub.io/docker-registry#p-17659-delete-by-digest)

The recommended way to delete images from the registry is to use the `rmi`
action. If necessary, this charm can be configured to
[allow deletion](https://docs.docker.com/registry/configuration/#delete) of blobs and manifests by digest by setting
the `storage-delete` config option to `true`:

```
juju config docker-registry storage-delete=true
```

### [Read-Only Mode](https://charmhub.io/docker-registry#p-17659-read-only-mode)

The registry can be switched to [read-only mode](https://docs.docker.com/registry/configuration/#readonly) by setting
the `storage-read-only` config option to `true`:

```
juju config docker-registry storage-read-only=true
```

This may be useful when performing maintenance or deploying an environment
with complex authentication requirements.

As an example, consider a scenario that requires unauthenticated pull
and authenticated push access to the registry. This can be achieved by
deploying this charm twice with the same storage backend (for example,
a Swift object storage cluster):

```
juju deploy docker-registry public --config <storage-swift-opts>
juju deploy docker-registry private --config <storage-swift-opts>
```

Configure the unauthenticated public registry to be read-only, and enable
authentication for the private registry:

```
juju config public storage-read-only=true
juju config private <auth-opts>
```

With a common storage backend and appropriate configuration, unauthenticated
public users have a read-only view of the images pushed by authenticated
private users.

### [S3 Storage](https://charmhub.io/docker-registry#p-17659-s3-storage)

The charm supports S3 or S3-compatible storage(like [RADOS](https://docs.ceph.com/en/reef/rados/) in CEPH), which may be configured in the following way:

```
juju config docker-registry \
  storage-s3-region=<region> \
  storage-s3-bucket=<bucket-name> \
  storage-s3-secretkey=<secret-key> \
  storage-s3-accesskey=<access-key>
```

Please note that the options above are required. All extra options can be found in [configuration.yaml](https://github.com/canonical/docker-registry-charm/blob/master/src/config.yaml) or on the charmhub configuration [page](https://charmhub.io/docker-registry/configuration?channel=latest/edge).

### [Swift Storage](https://charmhub.io/docker-registry#p-17659-swift-storage)

> **Note**: Please note that Swift driver is [deprecated](https://github.com/distribution/distribution/pull/3982) and is not supported in new distribution versions.

The charm supports Swift configuration options that can be used to store
images in a Swift backend:

```
juju config docker-registry \
  storage-swift-authurl=<url> \
  storage-swift-container=<container> \
  storage-swift-password=<pass> \
  storage-swift-region=<region> \
  storage-swift-tenant=<tenant> \
  storage-swift-username=<user>
```

> Note: If any of the above config options are set, then they must all be set. Optional params are noted below.

It is possible to configure the swift backend with an OpenStack domain name for Identity v3. To enable this, set the following optional config parameter:

```
storage-swift-domain=<val>
```

Also note that if the swift container is empty, requests to the registry may
return 503 errors like the following:

```
{"errors":[{"code":"UNAVAILABLE","message":"service unavailable","detail":"health check failed: please see /debug/health"}]}
```

Per [Registry becomes permanently unavailable after 30 seconds, using S3 driver · Issue #2292 · distribution/distribution · GitHub](https://github.com/docker/distribution/issues/2292), upload an empty file
called “files” at the root of the container to workaround the issue.

For the swift driver configuration see [here for more details.](https://github.com/docker/docker.github.io/blob/master/registry/storage-drivers/swift.md)

---

[Help improve this document in the forum](https://discourse.charmhub.io/t/docker-registry-docs-index/6180) ([guidelines](https://discourse.charmhub.io/t/how-to-write-docs-our-documentation-guidelines-for-contributors/1245)). Last updated 10 months ago.
