Podman - Local Container Registry
If you want to use containers, you need to pull images from a container registry. This is the place where container images live. But, how do you run your own registry? For your local network or development purposes, this is really useful!
If you want to use containers, you need to pull images from a container registry. This is the place where container images live. But, how do you run your own registry? For your local network or development purposes, this is really useful!
Container Registry
A container registry is the place, where images can be uploaded and downloaded. In fact, this is the most useful thing in the current container world.
You build your application, bundle it and upload the ready-to-use image somewhere. Others can download it and deploy it on their own machine. Today, there are many registry services available - Google, Amazon and Azure offer their own solution. Another registry is included in GitLab and GitHub, Pulp also offers one for self-hosting. Harbor is a dedicated registry server, and then there is also quay.io. But the most known is the Docker Registry.
Running such a registry on your own has many reasons and benefits. You may have security concerns or just don't want to upload something to a public registry. The easiest way is to use the official docker registry container.
So, let's have a look how you can run it with Podman on your server. If you work a lot with containers, this might also be a nice addition for the Fedora - Home Server.
Local Docker Registry
A friend of mine asked me about this topic and I also did a small poll over at LinkedIn to see, which registry you are using. It seems like the Docker Registry is still a thing, and therefore I decided to start with it. It is also the easiest one.
Without any further explanation, let's go.
Deployment
The easiest way to deploy the registry is by running the below command.
# Run the registry
$ podman container run -dt -p 5000:5000 --name registry docker.io/library/registry:2
# Check if it is running
$ podman container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8e77acc1c6e docker.io/library/registry:2 /etc/docker/regis... 3 seconds ago Up 3 seconds ago 0.0.0.0:5000->5000/tcp registry
This is a very simple example and suitable for testing. We should add at least some persistent storage. This can be done either with a named volume or a desired path. So, let's add some persistent storage.
# Stop and Remove the running container
$ podman container rm -f registry
# Start again with a named volume
$ podman container run -dt -p 5000:5000 --name registry --volume registry:/var/lib/registry:Z docker.io/library/registry:2
This should do the trick, and you can check the volume with Podman.
# Check volumes
$ podman volume ls
DRIVER VOLUME NAME
local registry
# Inspect volume
$ podman volume inspect registry
[
{
"Name": "registry",
"Driver": "local",
"Mountpoint": "/home/dschier/.local/share/containers/storage/volumes/registry/_data",
"CreatedAt": "2022-07-04T21:19:17.888305425+02:00",
"Labels": {},
"Scope": "local",
"Options": {},
"MountCount": 0,
"NeedsCopyUp": true
}
]
As you can, the data will be stored in my home directory and therefore, I can restart and even remove the container. If I start a new one and re-use the same volume, I can access already stored images.
Testing
To test the functionality, we can download an image and upload it to our local registry.
# Download an image
$ podman image pull docker.io/library/alpine
# Relable an image
$ podman image tag docker.io/library/alpine:latest localhost:5000/alpine:latest
# Upload to the local registry
$ podman image push localhost:5000/alpine:latest --tls-verify=false
Getting image source signatures
Copying blob 24302eb7d908 done
Copying config e66264b987 done
Writing manifest to image destination
Storing signatures
Since the test registry has no valid certificate, we need to add the --tls-verify=false
option to our command. Afterwards, you can also search in the registry.
# Search all images in the local registry
$ podman image search localhost:5000/ --tls-verify=false
NAME DESCRIPTION
localhost:5000/alpine
Now, you can remove your local image and pull it again from your local registry, if you want.
# Remove local image
$ podman image rm localhost:5000/alpine docker.io/library/alpine
# Check images
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/registry 2 773dbf02e42e 5 weeks ago 24.6 MB
# Download the image from the local registry
$ podman image pull localhost:5000/alpine:latest --tls-verify=false
# Check images
$ podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/registry 2 773dbf02e42e 5 weeks ago 24.6 MB
localhost:5000/alpine latest e66264b98777 6 weeks ago 5.81 MB
This was easy enough, I assume.
Cleanup
If you are done with everything, it might be a good idea to clean up the images, volumes and containers.
# Remove container
$ podman container rm -f registry
# Remove volume
$ podman volume rm registry
# Remove image
$ podman image rm docker.io/library/registry:2
Production Setup
The above setup shows a nice example for a home server or development use case. For production, you should add authentication, a proper certificate and maybe tune the published ports.
This topic can be a bit annoying, but the Docker folks have documented it properly.
There are also hundreds of configuration options to make the registry work with cloud services, other storage options and much more.
Docs & Links
Conclusion
This already sums it up today. I hope you will have some fun with your new registry. In some future article, I will demonstrate the same scenario with another registry server, and I am also looking into a comparison of different registries.
Which registry do you use? What do you prefer? Let me know if there is something special you want to know about.