Estimated reading time: 18 minutes
RabbitMQ is an open source multi-protocol messaging broker. Jenny D is correct in that by default Docker container doesn't allow access to system clock. However, on Linux, if you're fine with your container having access to this capability, you can allow this capability using '-cap-add=SYSTIME' option of 'docker run' command when creating you container. Microenv.com — Create fake REST API for developers with possibility to generate code and app in docker container. News API — Search news on the web with code, get JSON results. Developers get 3,000 queries free each month. Storage customization Customize the storage location. By default, your registry data is persisted as a docker volume on the host filesystem. If you want to store your registry contents at a specific location on your host filesystem, such as if you have an SSD or SAN mounted into a particular directory, you might decide to use a bind mount instead.
This page contains information about hosting your own registry using theopen source Docker Registry. For information about Docker Hub, which offers ahosted registry with additional features such as teams, organizations, webhooks, automated builds, etc, see Docker Hub.
Before you can deploy a registry, you need to install Docker on the host.A registry is an instance of the registry
image, and runs within Docker.
This topic provides basic information about deploying and configuring aregistry. For an exhaustive list of configuration options, see theconfiguration reference.
If you have an air-gapped datacenter, seeConsiderations for air-gapped registries.
Run a local registry
Use a command like the following to start the registry container:
The registry is now ready to use.
Warning: These first few examples show registry configurations that areonly appropriate for testing. A production-ready registry must be protected byTLS and should ideally use an access-control mechanism. Keep reading and thencontinue to the configuration guide to deploy aproduction-ready registry.
Copy an image from Docker Hub to your registry
You can pull an image from Docker Hub and push it to your registry. Thefollowing example pulls the ubuntu:16.04
image from Docker Hub and re-tags itas my-ubuntu
, then pushes it to the local registry. Finally, theubuntu:16.04
and my-ubuntu
images are deleted locally and themy-ubuntu
image is pulled from the local registry.
Pull the
ubuntu:16.04
image from Docker Hub.Tag the image as
localhost:5000/my-ubuntu
. This creates an additional tagfor the existing image. When the first part of the tag is a hostname andport, Docker interprets this as the location of a registry, when pushing.Push the image to the local registry running at
localhost:5000
:Remove the locally-cached
ubuntu:16.04
andlocalhost:5000/my-ubuntu
images, so that you can test pulling the image from your registry. Thisdoes not remove thelocalhost:5000/my-ubuntu
image from your registry.Pull the
localhost:5000/my-ubuntu
image from your local registry.
Stop a local registry
To stop the registry, use the same docker container stop
command as with any othercontainer.
To remove the container, use docker container rm
.
Basic configuration
To configure the container, you can pass additional or modified options to thedocker run
command.
The following sections provide basic guidelines for configuring your registry.For more details, see the registry configuration reference.
Start the registry automatically
If you want to use the registry as part of your permanent infrastructure, youshould set it to restart automatically when Docker restarts or if it exits.This example uses the --restart always
flag to set a restart policy for theregistry.
Customize the published port
If you are already using port 5000, or you want to run multiple localregistries to separate areas of concern, you can customize the registry’sport settings. This example runs the registry on port 5001 and also names itregistry-test
. Remember, the first part of the -p
value is the host portand the second part is the port within the container. Within the container, theregistry listens on port 5000
by default.
If you want to change the port the registry listens on within the container, youcan use the environment variable REGISTRY_HTTP_ADDR
to change it. This commandcauses the registry to listen on port 5001 within the container:
Storage customization
Customize the storage location
By default, your registry data is persisted as a docker volumeon the host filesystem. If you want to store your registry contents at a specificlocation on your host filesystem, such as if you have an SSD or SAN mounted intoa particular directory, you might decide to use a bind mount instead. A bind mountis more dependent on the filesystem layout of the Docker host, but more performantin many situations. The following example bind-mounts the host directory/mnt/registry
into the registry container at /var/lib/registry/
.
Customize the storage back-end
By default, the registry stores its data on the local filesystem, whether youuse a bind mount or a volume. You can store the registry data in an Amazon S3bucket, Google Cloud Platform, or on another storage back-end by usingstorage drivers. For more information, seestorage configuration options.
Run an externally-accessible registry
Running a registry only accessible on localhost
has limited usefulness. Inorder to make your registry accessible to external hosts, you must first secureit using TLS.
This example is extended in Run the registry as aservice below.
Get a certificate
These examples assume the following:
- Your registry URL is
https://myregistry.domain.com/
. - Your DNS, routing, and firewall settings allow access to the registry’s hoston port 443.
- You have already obtained a certificate from a certificate authority (CA).
If you have been issued an intermediate certificate instead, seeuse an intermediate certificate.
Create a
certs
directory.Copy the
.crt
and.key
files from the CA into thecerts
directory.The following steps assume that the files are nameddomain.crt
anddomain.key
.Stop the registry if it is currently running.
Restart the registry, directing it to use the TLS certificate. This commandbind-mounts the
certs/
directory into the container at/certs/
, and setsenvironment variables that tell the container where to find thedomain.crt
anddomain.key
file. The registry runs on port 443, the default HTTPS port.Docker clients can now pull from and push to your registry using itsexternal address. The following commands demonstrate this:
Use an intermediate certificate
A certificate issuer may supply you with an intermediate certificate. In thiscase, you must concatenate your certificate with the intermediate certificate toform a certificate bundle. You can do this using the cat
command:
You can use the certificate bundle just as you use the domain.crt
file inthe previous example.
Support for Let’s Encrypt
The registry supports using Let’s Encrypt to automatically obtain abrowser-trusted certificate. For more information on Let’s Encrypt, seehttps://letsencrypt.org/how-it-works/and the relevant section of theregistry configuration.
Use an insecure registry (testing only)
It is possible to use a self-signed certificate, or to use our registryinsecurely. Unless you have set up verification for your self-signedcertificate, this is for testing only. See run an insecure registry.
Run the registry as a service
Swarm services provide several advantages overstandalone containers. They use a declarative model, which means that you definethe desired state and Docker works to keep your service in that state. Servicesprovide automatic load balancing scaling, and the ability to control thedistribution of your service, among other advantages. Services also allow you tostore sensitive data such as TLS certificates insecrets.
The storage back-end you use determines whether you use a fully scaled serviceor a service with either only a single node or a node constraint.
If you use a distributed storage driver, such as Amazon S3, you can use afully replicated service. Each worker can write to the storage back-endwithout causing write conflicts.
If you use a local bind mount or volume, each worker node writes to itsown storage location, which means that each registry contains a differentdata set. You can solve this problem by using a single-replica service and anode constraint to ensure that only a single worker is writing to the bindmount.
The following example starts a registry as a single-replica service, which isaccessible on any swarm node on port 80. It assumes you are using the sameTLS certificates as in the previous examples.
First, save the TLS certificate and key as secrets:
Next, add a label to the node where you want to run the registry.To get the node’s name, use docker node ls
. Substitute your node’s name fornode1
below. Osx mojave download link.
Next, create the service, granting it access to the two secrets and constrainingit to only run on nodes with the label registry=true
. Besides the constraint,you are also specifying that only a single replica should run at a time. Theexample bind-mounts /mnt/registry
on the swarm node to /var/lib/registry/
within the container. Bind mounts rely on the pre-existing source directory,so be sure /mnt/registry
exists on node1
. You might need to create it beforerunning the following docker service create
command.
By default, secrets are mounted into a service at /run/secrets/<secret-name>
.
You can access the service on port 443 of any swarm node. Docker sends therequests to the node which is running the service.
Load balancing considerations
One may want to use a load balancer to distribute load, terminate TLS orprovide high availability. While a full load balancing setup is outside thescope of this document, there are a few considerations that can make the processsmoother.
The most important aspect is that a load balanced cluster of registries mustshare the same resources. For the current version of the registry, this meansthe following must be the same:
- Storage Driver
- HTTP Secret
- Redis Cache (if configured)
Differences in any of the above cause problems serving requests.As an example, if you’re using the filesystem driver, all registry instancesmust have access to the same filesystem root, onthe same machine. For other drivers, such as S3 or Azure, they should beaccessing the same resource and share an identical configuration.The HTTP Secret coordinates uploads, so also must be the same acrossinstances. Configuring different redis instances works (at the timeof writing), but is not optimal if the instances are not shared, becausemore requests are directed to the backend.
Important/Required HTTP-Headers
Getting the headers correct is very important. For all responses to anyrequest 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 realmsand fallback to version 1 registries, if necessary. Confirming this is setupcorrectly can help avoid problems with fallback.
In the same train of thought, you must make sure you are properly sending theX-Forwarded-Proto
, X-Forwarded-For
, and Host
headers to their “client-side”values. Failure to do so usually makes the registry issue redirects to internalhostnames or downgrading from https to http.
A properly secured registry should return 401 when the “/v2/” endpoint is hitwithout credentials. The response should include a WWW-Authenticate
challenge, providing guidance on how to authenticate, such as with basic author a token service. If the load balancer has health checks, it is recommendedto configure it to consider a 401 response as healthy and any other as down.This secures your registry by ensuring that configuration problems withauthentication don’t accidentally expose an unprotected registry. If you’reusing a less sophisticated load balancer, such as Amazon’s Elastic LoadBalancer, that doesn’t allow one to change the healthy response code, healthchecks can be directed at “/”, which always returns a 200 OK
response.
Restricting access
Except for registries running on secure local networks, registries should alwaysimplement 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).This example uses native basic authentication using htpasswd
to store thesecrets.
Warning:You cannot use authentication with authentication schemes that sendcredentials as clear text. You mustconfigure TLS first forauthentication to work.
Create a password file with one entry for the user
testuser
, with passwordtestpassword
:Stop the registry.
Start the registry with basic authentication.
Try to pull an image from the registry, or push an image to the registry.These commands fail.
Log in to the registry.
Provide the username and password from the first step.
Test that you can now pull an image from the registry or push an image tothe registry.
X509 errors: X509 errors usually indicate that you are attempting to usea self-signed certificate without configuring the Docker daemon correctly.See run an insecure registry.
More advanced authentication
You may want to leverage more advanced basic auth implementations by using aproxy in front of the registry. See the recipes list.
The registry also supports delegated authentication which redirects users to aspecific trusted token server. This approach is more complicated to set up, andonly makes sense if you need to fully configure ACLs and need more control overthe registry’s integration into your global authorization and authenticationsystems. Refer to the following background information andconfiguration information here.
This approach requires you to implement your own authentication system orleverage a third-party implementation.
Deploy your registry using a Compose file
If your registry invocation is advanced, it may be easier to use a Dockercompose file to deploy it, rather than relying on a specific docker run
invocation. Use the following example docker-compose.yml
as a template.
Replace /path
with the directory which contains the certs/
and auth/
directories.
Start your registry by issuing the following command in the directory containingthe docker-compose.yml
file:
Considerations for air-gapped registries
You can run a registry in an environment with no internet connectivity.However, if you rely on any images which are not local, you need to consider thefollowing:
You may need to build your local registry’s data volume on a connectedhost where you can run
docker pull
to get any images which are availableremotely, and then migrate the registry’s data volume to the air-gappednetwork.Certain images, such as the official Microsoft Windows base images, are notdistributable. This means that when you push an image based on one of theseimages to your private registry, the non-distributable layers are notpushed, but are always fetched from their authorized location. This is finefor internet-connected hosts, but not in an air-gapped set-up.
You can configure the Docker daemon to allow pushing non-distributable layers to private registries.This is only useful in air-gapped set-ups in the presence ofnon-distributable images, or in extremely bandwidth-limited situations.You are responsible for ensuring that you are in compliance with the terms ofuse for non-distributable layers.
Edit the
daemon.json
file, which is located in/etc/docker/
on Linuxhosts andC:ProgramDatadockerconfigdaemon.json
on Windows Server.Assuming the file was previously empty, add the following contents:The value is an array of registry addresses, separated by commas.
Save and exit the file.
Restart Docker.
Restart the registry if it does not start automatically.
When you push images to the registries in the list, theirnon-distributable layers are pushed to the registry.
Warning: Non-distributable artifacts typically have restrictions onhow and where they can be distributed and shared. Only use this featureto push artifacts to private registries and ensure that you are incompliance with any terms that cover redistributing non-distributableartifacts.
Next steps
More specific and advanced information is available in the following sections:
registry, on-prem, images, tags, repository, distribution, deploymentEstimated reading time: 20 minutes
About configs
Docker swarm service configs allow you to store non-sensitive information,such as configuration files, outside a service’s image or running containers.This allows you to keep your images as generic as possible, without the need tobind-mount configuration files into the containers or use environment variables.
Configs operate in a similar way to secrets, except that they arenot encrypted at rest and are mounted directly into the container’s filesystemwithout the use of RAM disks. Configs can be added or removed from a service atany time, and services can share a config. You can even use configs inconjunction with environment variables or labels, for maximum flexibility.Config values can be generic strings or binary content (up to 500 kb in size).
Note: Docker configs are only available to swarm services, not tostandalone containers. To use this feature, consider adapting your containerto run as a service with a scale of 1.
Configs are supported on both Linux and Windows services.
Windows support
Docker includes support for configs on Windows containers, but there are differencesin the implementations, which are called out in the examples below. Keep thefollowing notable differences in mind:
Config files with custom targets are not directly bind-mounted into Windowscontainers, since Windows does not support non-directory file bind-mounts.Instead, configs for a container are all mounted in
C:ProgramDataDockerinternalconfigs
(an implementation detail whichshould not be relied upon by applications) within the container. Symboliclinks are used to point from there to the desired target of the config withinthe container. The default target isC:ProgramDataDockerconfigs
.When creating a service which uses Windows containers, the options to specifyUID, GID, and mode are not supported for configs. Configs are currently onlyaccessible by administrators and users with
system
access within thecontainer.On Windows, create or update a service using
--credential-spec
with theconfig://<config-name>
format. This passes the gMSA credentials filedirectly to nodes before a container starts. No gMSA credentials are writtento disk on worker nodes. For more information, refer toDeploy services to a swarm.
How Docker manages configs
When you add a config to the swarm, Docker sends the config to the swarm managerover a mutual TLS connection. The config is stored in the Raft log, which isencrypted. The entire Raft log is replicated across the other managers, ensuringthe same high availability guarantees for configs as for the rest of the swarmmanagement data.
When you grant a newly-created or running service access to a config, the configis mounted as a file in the container. The location of the mount point withinthe container defaults to /<config-name>
in Linux containers. In Windowscontainers, configs are all mounted into C:ProgramDataDockerconfigs
andsymbolic links are created to the desired location, which defaults toC:<config-name>
.
You can set the ownership (uid
and gid
) for the config, using either thenumerical ID or the name of the user or group. You can also specify the filepermissions (mode
). These settings are ignored for Windows containers.
- If not set, the config is owned by the user running the containercommand (often
root
) and that user’s default group (also oftenroot
). - If not set, the config has world-readable permissions (mode
0444
), unless aumask
is set within the container, in which case the mode is impacted bythatumask
value.
You can update a service to grant it access to additional configs or revoke itsaccess to a given config at any time.
A node only has access to configs if the node is a swarm manager or if it isrunning service tasks which have been granted access to the config. When acontainer task stops running, the configs shared to it are unmounted from thein-memory filesystem for that container and flushed from the node’s memory.
If a node loses connectivity to the swarm while it is running a task containerwith access to a config, the task container still has access to its configs, butcannot receive updates until the node reconnects to the swarm.
You can add or inspect an individual config at any time, or list allconfigs. You cannot remove a config that a running service isusing. See Rotate a config for a way toremove a config without disrupting running services.
To update or roll back configs more easily, consider adding a versionnumber or date to the config name. This is made easier by the ability to controlthe mount point of the config within a given container.
To update a stack, make changes to your Compose file, then re-run dockerstack deploy -c <new-compose-file> <stack-name>
. If you use a new config inthat file, your services start using them. Keep in mind that configurationsare immutable, so you can’t change the file for an existing service.Instead, you create a new config to use a different file
You can run docker stack rm
to stop the app and take down the stack. Thisremoves any config that was created by docker stack deploy
with the same stackname. This removes all configs, including those not referenced by services andthose remaining after a docker service update --config-rm
.
Read more about docker config
commands
Use these links to read about specific commands, or continue to theexample about using configs with a service.
Examples
This section includes graduated examples which illustrate how to useDocker configs.
Note: These examples use a single-Engine swarm and unscaled services forsimplicity. The examples use Linux containers, but Windows containers alsosupport configs.
Defining and using configs in compose files
The docker stack
command supports defining configs in a Compose file.However, the configs
key is not supported for docker compose
. Seethe Compose file reference for details.
Simple example: Get started with configs
This simple example shows how configs work in just a few commands. For areal-world example, continue toAdvanced example: Use configs with a Nginx service.
Add a config to Docker. The
docker config create
command reads standardinput because the last argument, which represents the file to read theconfig from, is set to-
.Create a
redis
service and grant it access to the config. By default,the container can access the config at/my-config
, butyou can customize the file name on the container using thetarget
option.Verify that the task is running without issues using
docker service ps
. Ifeverything is working, the output looks similar to this:Get the ID of the
redis
service task container usingdocker ps
, so thatyou can usedocker container exec
to connect to the container and read the contentsof the config data file, which defaults to being readable by all and has thesame name as the name of the config. The first command below illustrateshow to find the container ID, and the second and third commands use shellcompletion to do this automatically.Try removing the config. The removal fails because the
redis
service isrunning and has access to the config.Remove access to the config from the running
redis
service by updating theservice.Repeat steps 3 and 4 again, verifying that the service no longer has accessto the config. The container ID is different, because the
service update
command redeploys the service.Stop and remove the service, and remove the config from Docker.
Simple example: Use configs in a Windows service
This is a very simple example which shows how to use configs with a MicrosoftIIS service running on Docker for Windows running Windows containers onMicrosoft Windows 10. It is a naive example that stores the webpage in a config.
This example assumes that you have PowerShell installed.
Save the following into a new file
index.html
.If you have not already done so, initialize or join the swarm.
Save the
index.html
file as a swarm config namedhomepage
.Create an IIS service and grant it access to the
homepage
config.Access the IIS service at
http://localhost:8000/
. It should servethe HTML content from the first step.Remove the service and the config.
Example: Use a templated config
To create a configuration in which the content will be generated using atemplate engine, use the --template-driver
parameter and specify the enginename as its argument. The template will be rendered when container is created.
Save the following into a new file
index.html.tmpl
.Save the
index.html.tmpl
file as a swarm config namedhomepage
. Provideparameter--template-driver
and specifygolang
as template engine.Create a service that runs Nginx and has access to the environment variableHELLO and to the config.
Verify that the service is operational: you can reach the Nginx server, andthat the correct output is being served.
Advanced example: Use configs with a Nginx service
This example is divided into two parts.The first part is all about generatingthe site certificate and does not directly involve Docker configs at all, butit sets up the second part, where you storeand use the site certificate as a series of secrets and the Nginx configurationas a config. The example shows how to set options on the config, such as thetarget location within the container and the file permissions (mode
).
Generate the site certificate
Generate a root CA and TLS certificate and key for your site. For productionsites, you may want to use a service such as Let’s Encrypt
to generate theTLS certificate and key, but this example uses command-line tools. This stepis a little complicated, but is only a set-up step so that you havesomething to store as a Docker secret. If you want to skip these sub-steps,you can use Let’s Encrypt togenerate the site key and certificate, name the files site.key
andsite.crt
, and skip toConfigure the Nginx container.
Generate a root key.
Generate a CSR using the root key.
Configure the root CA. Edit a new file called
root-ca.cnf
and pastethe following contents into it. This constrains the root CA to only signleaf certificates and not intermediate CAs.Sign the certificate.
Generate the site key.
Generate the site certificate and sign it with the site key.
Configure the site certificate. Edit a new file called
site.cnf
andpaste the following contents into it. This constrains the sitecertificate so that it can only be used to authenticate a server andcan’t be used to sign certificates.Sign the site certificate.
The
site.csr
andsite.cnf
files are not needed by the Nginx service, butyou need them if you want to generate a new site certificate. Protecttheroot-ca.key
file.
Add Ssl To Docker Container Tote
Configure the Nginx container
Produce a very basic Nginx configuration that serves static files over HTTPS.The TLS certificate and key are stored as Docker secrets so that theycan be rotated easily.
In the current directory, create a new file called
site.conf
with thefollowing contents:Create two secrets, representing the key and the certificate. You can storeany file as a secret as long as it is smaller than 500 KB. This allows youto decouple the key and certificate from the services that use them.In these examples, the secret name and the file name are the same.
Save the
site.conf
file in a Docker config. The first parameter is thename of the config, and the second parameter is the file to read it from.List the configs:
Create a service that runs Nginx and has access to the two secrets and theconfig. Set the mode to
0440
so that the file is only readable by itsowner and that owner’s group, not the world.Within the running containers, the following three files now exist:
/run/secrets/site.key
/run/secrets/site.crt
/etc/nginx/conf.d/site.conf
Verify that the Nginx service is running.
Verify that the service is operational: you can reach the Nginxserver, and that the correct TLS certificate is being used.
Unless you are going to continue to the next example, clean up after runningthis example by removing the
nginx
service and the stored secrets andconfig.
You have now configured a Nginx service with its configuration decoupled fromits image. You could run multiple sites with exactly the same image butseparate configurations, without the need to build a custom image at all.
Example: Rotate a config
To rotate a config, you first save a new config with a different name than theone that is currently in use. You then redeploy the service, removing the oldconfig and adding the new config at the same mount point within the container.This example builds upon the previous one by rotating the site.conf
configuration file.
Add Ssl To Docker Containers
Edit the
site.conf
file locally. Addindex.php
to theindex
line, andsave the file.Create a new Docker config using the new
site.conf
, calledsite-v2.conf
.Update the
nginx
service to use the new config instead of the old one.Verify that the
nginx
service is fully re-deployed, usingdocker service ps nginx
. When it is, you can remove the oldsite.conf
config.To clean up, you can remove the
nginx
service, as well as the secrets andconfigs.
You have now updated your nginx
service’s configuration without the need torebuild its image.