A registry is an instance of the registry image, and runs within Docker.
By default dockerd
(docker daemon) pulls images from docker.hub, it requires an Internet connection to download images. In many cases, the server locates in a private network also have many advantages such as security policy, self-manage docker image, caching, etc.
Docker provides docker registry and docker trusted registry with some differences for hosting a private registry server.
This hands-on tutorial provides a briefly description for running a registry server. For more detail, please visit the official setup guide
This guide includes 2 steps:
- Pull and configure a local registry server which comes from github repo
- Configure docker client to fetch images from private server.
We're gonna set up a registry server runs on http://localhost:5000 and stored images at /var/lib/registry
. Once server is up, we pull a python image from docker.hub, then push to our local private server.
Use the following steps for running docker registry server in production.
dockerd
fetchs images with a secure protocol HTTPS
by default. Thus, the registry server should date with https
with various options
You have to install cfssl to your path:
sudo curl -s -L -o /bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
sudo curl -s -L -o /bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
sudo chmod +x /bin/{cfssl,cfssljson}
The following configuration is from core-os
mkdir $HOME/cert
mkdir $HOME/registry
cd $HOME/cert
echo '{"CN":"CA","key":{"algo":"rsa","size":2048}}' | cfssl gencert -initca - | cfssljson -bare ca -
echo '{"signing":{"default":{"expiry":"43800h","usages":["signing","key encipherment","server auth","client auth"]}}}' > ca-config.json
export ADDRESS=192.168.233.161,192.168.233.160,192.168.233.162 # This IP list is the white list for our cluster.
export NAME=server
echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME
export ADDRESS=
export NAME=client
echo '{"CN":"'$NAME'","hosts":[""],"key":{"algo":"rsa","size":2048}}' | cfssl gencert -config=ca-config.json -ca=ca.pem -ca-key=ca-key.pem -hostname="$ADDRESS" - | cfssljson -bare $NAME
After this step, you have the following files in current directory:
$ ls $HOME/cert/
ca-config.json
ca.csr
ca-key.pem
ca.pem
client.csr
client-key.pem
client.pem
server.csr
server-key.pem
server.pem
Start server in debug mode.
docker run -p 5443:5443 --restart=always \
--name registry \
-e REGISTRY_HTTP_SECRET=5iT35m_1nf1n1g4u \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/cert/server.pem \
-e REGISTRY_HTTP_TLS_KEY=/cert/server-key.pem \
-v $HOME/cert:/cert \
-v $HOME/registry:/var/lib/registry \
registry:2
We reconfigure docker daemon using the /etc/docker/daemon.json
file for all servers.
- Create or modify
/etc/docker/daemon.json
{ "insecure-registries":["192.168.233.160:5443"] }
Copy the client key to other docker machine.
/etc/docker/certs.d/
- 192.168.233.160/ # registry server ip without port
- ca.csr
- ca-key.pem
- ca.pem
- client.csr
- client-key.pem
- client.pe
- Restart docker daemon for all servers.
sudo systemctl restart docker
The following steps are my approaches to configure registry server. It uses registry
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
-d
daemon mode-p 5000:5000
mapping port physical → container--restart=always
run this container after docker started--name registry
container name
Now, the service is running a service at port 5000
$ docker ps
Verify:
$ docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2 d1fd7d86a825 4 months ago 33.3MB
In order to copy an image to local repo, we perform the following steps:
- Pull image from docker.hub
- Assign tag for images
- Push to local registry
$ docker pull python:alpine3.6 # pull image from docker.hub
$ docker tag python:alpine3.6 localhost:5000/python:alpine3.6 # assign tag for image
$ docker push localhost:5000/python:alpine3.6 # push to local repo
Verify uploaded image in registry
http GET localhost:5000/v2/_catalog
{
"repositories": [
"python"
]
}
Once the server is up and run. we inspect the server default location.
$ docker inspect registry
...
"Mounts":[
{
"Type":"volume",
"Name":"e71f65b9da143a99e8f391b3f5ab8903184cae58a2d3416de23a8d375775e822",
"Source":"/var/lib/docker/volumes/e71f65b9da143a99e8f391b3f5ab8903184cae58a2d3416de23a8d375775e822/_data",
"Destination":"/var/lib/registry",
"Driver":"local",
"Mode":"",
"RW":true,
"Propagation":""
}
]
...
Now, we can change the location by docker volume feature.
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
-v
map physical path/mnt/registry
→ container path/var/lib/registry
Simple solution:
- Back up by compressing physical directory.
$ tar cvf registry.tar.gz /mnt/registry
- Restore by extracting the compressed file, then run again with mapping volume.
Remove local cache
$ docker image remove python:alpine3.6
$ docker image remove localhost:5000/python:alpine3.6
Stop container
docker container stop <container_name>
Change service inside container port by specify environment variable
REGISTRY_HTTP_ADDR
with-e
flag
docker run -d \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
-p 5001:5001 \
--name registry-test \
registry:2
Configure container with volume.
$ docker volume create registry
$ docker-private-registry docker volume inspect registry
[
{
"CreatedAt": "2018-05-28T00:45:06+09:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/registry/_data",
"Name": "registry",
"Options": {},
"Scope": "local"
}
]