In my previous article, I shared with you the steps I took, trying out the Quarkus guide “Quarkus – Kubernetes extension” (again 😊) and also the steps to further set up my demo environment, running in a VM, created with Vagrant and shell scripts. In order to meet the requirements for that extension, I installed OpenJDK JDK 24, Apache Maven 3.9.9 and for the Kubernetes cluster, I installed K3s (a lightweight certified Kubernetes distribution) and a Kubernetes Dashboard.
[https://technology.amis.nl/software-development/java/quarkus-supersonic-subatomic-java-trying-out-quarkus-guide-quarkus-kubernetes-extension-reinvestigated-part-1/]
Some years ago, I also wrote articles about the Quarkus Kubernetes Extension using the default public Docker image registry. This time, I wanted to try out using a local private registry.
In this article, I will take you with me on a “journey”. You can read more about the steps I took to install a local private registry in my demo environment and using it with Quarkus. I used the registry Docker Official Image, a Distribution implementation for storing and distributing of container images and artifacts.
In a next article, I will describe how I secured my local private registry and also used it with Quarkus and with K3s.
Public versus Private Docker Registries
An image registry is a centralized location for storing and sharing your container images. It can be either public or private. Docker Hub is a public registry that anyone can use and is the default registry.
While Docker Hub is a popular option, there are many other available container registries available today, including Amazon Elastic Container Registry (ECR), Azure Container Registry (ACR), and Google Container Registry (GCR). You can even run your private registry on your local system or inside your organization. For example, Harbor, JFrog Artifactory, GitLab Container registry etc.
[https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-registry/]
A public Docker registry, like Docker Hub, is open to anyone for storing and sharing Docker images, while a private registry restricts access to authorized users, often within an organization. Public registries are good for open-source projects and community sharing, while private registries are preferred for sensitive or proprietary images.
Here’s a more detailed comparison:
Public Docker Registry (e.g., Docker Hub):
- Accessibility: Anyone with a Docker Hub account can pull and push images.
- Use Cases: Suitable for open-source projects, community-driven development, and when sharing images publicly is desired.
- Examples: Docker Hub, GitHub Packages (public repositories).
- Advantages: Easy to get started, vast collection of images available, good for collaboration and sharing.
- Disadvantages: Limited control over who can access your images, potential security concerns if not properly managed, potential bandwidth limitations.
Private Docker Registry:
- Accessibility: Access is restricted to authorized users through authentication and authorization mechanisms.
- Use Cases: Organizations hosting proprietary or sensitive images, environments where security and access control are paramount.
- Examples: Amazon Elastic Container Registry (ECR), Azure Container Registry (ACR), GitLab Container Registry, Harbor, and self-hosted registries.
- Advantages: Enhanced security and control over image access, faster deployments within an organization, and potential cost savings on bandwidth if self-hosted.
- Disadvantages: Requires more setup and management, potentially higher initial costs if using a cloud-based service, requires setting up authentication and authorization.
[AI overview]
AI responses may include mistakes. Learn more
registry – Official Image | Docker Hub
Via Docker Hub, I had a look at the registry image, a Distribution implementation for storing and distributing of container images and artifacts.
This image contains an implementation of the OCI Distribution spec. See github.com/opencontainers/distribution-spec for more details about what it is.
[https://hub.docker.com/_/registry]
I had a look at the “Recommended Reading” section on the website, with the following two parts:
[https://hub.docker.com/_/registry]
- The documentation is a good place to learn more about what the registry is, how it works, and how to use it.
[https://distribution.github.io/distribution/] - Specifically, the section regarding deployment has pointers for more complex use cases than simply running a registry on localhost.
[https://distribution.github.io/distribution/about/deploying/]
As you can see in the documentation about the registry image, “Deploy a registry server” section above, 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.
[https://distribution.github.io/distribution/about/deploying/]
Installing Docker
As I described in a previous article, I had a demo environment, with Ubuntu Jammy 22.04 (LTS) as guest Operating System, within an Oracle VirtualBox appliance, with the help of Vagrant.
[https://technology.amis.nl/software-development/java/quarkus-supersonic-subatomic-java-get-started-reinvestigated/]
I used vagrant ssh to connect into the running VM.
To install Docker on Ubuntu, I followed the steps, as described in “Install Docker Engine on Ubuntu”.
Please see:
https://docs.docker.com/engine/install/ubuntu/
But first, a quick recap about Docker.
Docker Engine
Docker Engine is an open source containerization technology for building and containerizing your applications. Docker Engine acts as a client-server application with:
- A server with a long-running daemon process dockerd.
- APIs which specify interfaces that programs can use to talk to and instruct the Docker daemon.
- A command line interface (CLI) client docker.
The CLI uses Docker APIs to control or interact with the Docker daemon through scripting or direct CLI commands. Many other Docker applications use the underlying API and CLI. The daemon creates and manages Docker objects, such as images, containers, networks, and volumes.
For more details, see Docker Architecture.
[https://docs.docker.com/engine/]
Docker architecture
Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface.
[https://docs.docker.com/get-started/docker-overview/#docker-architecture]
The Docker daemon
The Docker daemon (dockerd) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes. A daemon can also communicate with other daemons to manage Docker services.
The Docker client
The Docker client (docker) is the primary way that many Docker users interact with Docker. When you use commands such as docker run, the client sends these commands to dockerd, which carries them out. The docker command uses the Docker API. The Docker client can communicate with more than one daemon.
Docker registries
A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker looks for images on Docker Hub by default. You can even run your own private registry.
When you use the docker pull or docker run commands, Docker pulls the required images from your configured registry. When you use the docker push command, Docker pushes your image to your configured registry.
Docker objects
When you use Docker, you are creating and using images, containers, networks, volumes, plugins, and other objects.
Images
An image is a read-only template with instructions for creating a Docker container.
You might create your own images or you might only use those created by others and published in a registry. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it.
Containers
A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
[https://docs.docker.com/get-started/docker-overview/#docker-architecture]
Please see the documentation, mentioned above, for more detailed information.
In my demo environment, the Docker client and daemon will run on the same system (Ubuntu) within a VM.
Uninstall conflicting packages
First, I followed the steps as described in the “Install Docker Engine on Ubuntu” documentation, “Uninstall old versions” section.
[https://docs.docker.com/engine/install/ubuntu/#uninstall-old-versions]
Before you can install Docker Engine, you need to uninstall any conflicting packages.
Your Linux distribution may provide unofficial Docker packages, which may conflict with the official packages provided by Docker. You must uninstall these packages before you install the official version of Docker Engine.
[https://docs.docker.com/engine/install/ubuntu/#uninstall-old-versions]
In order to uninstall conflicting packages, I used the following command on the Linux Command Prompt:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
With the following output:
Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'docker.io' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'docker-doc' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'docker-compose' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'docker-compose-v2' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'podman-docker' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'containerd' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'runc' is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
Images, containers, volumes, and networks stored in /var/lib/docker/ aren’t automatically removed when you uninstall Docker. If you want to start with a clean installation, and prefer to clean up any existing data, read the uninstall Docker Engine section.
[https://docs.docker.com/engine/install/ubuntu/#uninstall-old-versions]
Uninstall Docker Engine
Next, I followed the steps as described in the “Install Docker Engine on Ubuntu” documentation, “Uninstall Docker Engine” section.
[https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine]
In order to uninstall the Docker Engine, CLI, containerd, and Docker Compose packages, I used the following command on the Linux Command Prompt:
sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
With the following output:
Reading package lists... Done Building dependency tree... Done Reading state information... Done Package 'docker-ce' is not installed, so not removed E: Unable to locate package docker-ce-cli E: Unable to locate package containerd.io E: Couldn't find any package by glob 'containerd.io' E: Couldn't find any package by regex 'containerd.io' E: Unable to locate package docker-buildx-plugin E: Unable to locate package docker-compose-plugin E: Unable to locate package docker-ce-rootless-extras
Remark about apt-get remove versus purge:
- remove
remove is identical to install except that packages are removed instead of installed. Note that removing a package leaves its configuration files on the system. If a plus sign is appended to the package name (with no intervening space), the identified package will be installed instead of removed. - purge
purge is identical to remove except that packages are removed and purged (any configuration files are deleted too).
[https://manpages.ubuntu.com/manpages/lunar/man8/apt-get.8.html]
Images, containers, volumes, or custom configuration files on your host aren’t automatically removed.
[https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine]
In order to delete all images, containers, and volumes, I used the following commands on the Linux Command Prompt:
sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
In order to remove source list and keyrings, I used the following commands on the Linux Command Prompt:
sudo rm /etc/apt/sources.list.d/docker.list sudo rm /etc/apt/keyrings/docker.asc
With the following output:
rm: cannot remove '/etc/apt/sources.list.d/docker.list': No such file or directory rm: cannot remove '/etc/apt/keyrings/docker.asc': No such file or directory
You have to delete any edited configuration files manually.
[https://docs.docker.com/engine/install/ubuntu/#uninstall-docker-engine]
Install the Docker Engine using the apt repository
Next, I followed the steps as described in the “Install Docker Engine on Ubuntu” documentation, “Install using the apt repository” section.
[https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository]
Before you install Docker Engine for the first time on a new host machine, you need to set up the Docker apt repository. Afterward, you can install and update Docker from the repository.
[https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository]
I followed the steps, as described in the “Install Docker Engine on Ubuntu” documentation, “Install using the apt repository” section, part “Set up Docker’s apt repository”.
I used the following command on the Linux Command Prompt:
sudo apt-get update
With the following output:
Hit:1 https://mirrors.edge.kernel.org/ubuntu jammy InRelease Get:2 https://mirrors.edge.kernel.org/ubuntu jammy-updates InRelease [128 kB] … Get:34 https://mirrors.edge.kernel.org/ubuntu jammy-security/multiverse amd64 c-n-f Metadata [368 B] Fetched 17.3 MB in 5s (3,644 kB/s) Reading package lists... Done
Next, I used the following command on the Linux Command Prompt:
sudo apt-get install ca-certificates curl
With the following output:
Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libcurl4 The following packages will be upgraded: ca-certificates curl libcurl4 3 upgraded, 0 newly installed, 0 to remove and 216 not upgraded. Need to get 646 kB of archives. After this operation, 11.3 kB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 https://mirrors.edge.kernel.org/ubuntu jammy-updates/main amd64 ca-certificates all 20240203~22.04.1 [162 kB] Get:2 https://mirrors.edge.kernel.org/ubuntu jammy-updates/main amd64 curl amd64 7.81.0-1ubuntu1.20 [194 kB] Get:3 https://mirrors.edge.kernel.org/ubuntu jammy-updates/main amd64 libcurl4 amd64 7.81.0-1ubuntu1.20 [289 kB] Fetched 646 kB in 0s (3,242 kB/s) Preconfiguring packages ... (Reading database ... 76364 files and directories currently installed.) Preparing to unpack .../ca-certificates_20240203~22.04.1_all.deb ... Unpacking ca-certificates (20240203~22.04.1) over (20230311ubuntu0.22.04.1) ... Preparing to unpack .../curl_7.81.0-1ubuntu1.20_amd64.deb ... Unpacking curl (7.81.0-1ubuntu1.20) over (7.81.0-1ubuntu1.15) ... Preparing to unpack .../libcurl4_7.81.0-1ubuntu1.20_amd64.deb ... Unpacking libcurl4:amd64 (7.81.0-1ubuntu1.20) over (7.81.0-1ubuntu1.15) ... Setting up ca-certificates (20240203~22.04.1) ... Updating certificates in /etc/ssl/certs... rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL 14 added, 5 removed; done. Setting up libcurl4:amd64 (7.81.0-1ubuntu1.20) ... Setting up curl (7.81.0-1ubuntu1.20) ... Processing triggers for man-db (2.10.2-1) ... Processing triggers for libc-bin (2.35-0ubuntu3.6) ... Processing triggers for ca-certificates (20240203~22.04.1) ... Updating certificates in /etc/ssl/certs... 0 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. Scanning processes... Scanning linux images... Running kernel seems to be up-to-date. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host.
In order to add Docker’s official GPG key, I used the following commands on the Linux Command Prompt:
sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc
In order to add the repository to Apt sources, I used the following commands on the Linux Command Prompt:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update
With the following output:
Hit:1 https://mirrors.edge.kernel.org/ubuntu jammy InRelease Hit:2 https://mirrors.edge.kernel.org/ubuntu jammy-updates InRelease Hit:3 https://mirrors.edge.kernel.org/ubuntu jammy-backports InRelease Hit:4 https://mirrors.edge.kernel.org/ubuntu jammy-security InRelease Get:5 https://download.docker.com/linux/ubuntu jammy InRelease [48.8 kB] Get:6 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages [48.8 kB] Fetched 97.6 kB in 1s (88.9 kB/s) Reading package lists... Done
Install the Docker packages
Next, I followed the steps, as described in the “Install Docker Engine on Ubuntu” documentation, “Install using the apt repository” section, part “Install the Docker packages”.
In order to install the latest version, I used the following command on the Linux Command Prompt:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
With the following output:
Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: docker-ce-rootless-extras libltdl7 libslirp0 pigz slirp4netns Suggested packages: cgroupfs-mount | cgroup-lite The following NEW packages will be installed: containerd.io docker-buildx-plugin docker-ce docker-ce-cli docker-ce-rootless-extras docker-compose-plugin libltdl7 libslirp0 pigz slirp4netns 0 upgraded, 10 newly installed, 0 to remove and 216 not upgraded. Need to get 120 MB of archives. After this operation, 440 MB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 https://mirrors.edge.kernel.org/ubuntu jammy/universe amd64 pigz amd64 2.6-1 [63.6 kB] Get:2 https://mirrors.edge.kernel.org/ubuntu jammy/main amd64 libltdl7 amd64 2.4.6-15build2 [39.6 kB] Get:3 https://mirrors.edge.kernel.org/ubuntu jammy/main amd64 libslirp0 amd64 4.6.1-1build1 [61.5 kB] Get:4 https://mirrors.edge.kernel.org/ubuntu jammy/universe amd64 slirp4netns amd64 1.0.1-2 [28.2 kB] Get:5 https://download.docker.com/linux/ubuntu jammy/stable amd64 containerd.io amd64 1.7.27-1 [30.5 MB] Get:6 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-buildx-plugin amd64 0.23.0-1~ubuntu.22.04~jammy [34.7 MB] Get:7 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-ce-cli amd64 5:28.1.1-1~ubuntu.22.04~jammy [15.8 MB] Get:8 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-ce amd64 5:28.1.1-1~ubuntu.22.04~jammy [19.2 MB] Get:9 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-ce-rootless-extras amd64 5:28.1.1-1~ubuntu.22.04~jammy [6,094 kB] Get:10 https://download.docker.com/linux/ubuntu jammy/stable amd64 docker-compose-plugin amd64 2.35.1-1~ubuntu.22.04~jammy [13.8 MB] Fetched 120 MB in 4s (28.0 MB/s) Selecting previously unselected package pigz. (Reading database ... 76373 files and directories currently installed.) Preparing to unpack .../0-pigz_2.6-1_amd64.deb ... Unpacking pigz (2.6-1) ... Selecting previously unselected package containerd.io. Preparing to unpack .../1-containerd.io_1.7.27-1_amd64.deb ... Unpacking containerd.io (1.7.27-1) ... Selecting previously unselected package docker-buildx-plugin. Preparing to unpack .../2-docker-buildx-plugin_0.23.0-1~ubuntu.22.04~jammy_amd64.deb ... Unpacking docker-buildx-plugin (0.23.0-1~ubuntu.22.04~jammy) ... Selecting previously unselected package docker-ce-cli. Preparing to unpack .../3-docker-ce-cli_5%3a28.1.1-1~ubuntu.22.04~jammy_amd64.deb ... Unpacking docker-ce-cli (5:28.1.1-1~ubuntu.22.04~jammy) ... Selecting previously unselected package docker-ce. Preparing to unpack .../4-docker-ce_5%3a28.1.1-1~ubuntu.22.04~jammy_amd64.deb ... Unpacking docker-ce (5:28.1.1-1~ubuntu.22.04~jammy) ... Selecting previously unselected package docker-ce-rootless-extras. Preparing to unpack .../5-docker-ce-rootless-extras_5%3a28.1.1-1~ubuntu.22.04~jammy_amd64.deb ... Unpacking docker-ce-rootless-extras (5:28.1.1-1~ubuntu.22.04~jammy) ... Selecting previously unselected package docker-compose-plugin. Preparing to unpack .../6-docker-compose-plugin_2.35.1-1~ubuntu.22.04~jammy_amd64.deb ... Unpacking docker-compose-plugin (2.35.1-1~ubuntu.22.04~jammy) ... Selecting previously unselected package libltdl7:amd64. Preparing to unpack .../7-libltdl7_2.4.6-15build2_amd64.deb ... Unpacking libltdl7:amd64 (2.4.6-15build2) ... Selecting previously unselected package libslirp0:amd64. Preparing to unpack .../8-libslirp0_4.6.1-1build1_amd64.deb ... Unpacking libslirp0:amd64 (4.6.1-1build1) ... Selecting previously unselected package slirp4netns. Preparing to unpack .../9-slirp4netns_1.0.1-2_amd64.deb ... Unpacking slirp4netns (1.0.1-2) ... Setting up docker-buildx-plugin (0.23.0-1~ubuntu.22.04~jammy) ... Setting up containerd.io (1.7.27-1) ... Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /lib/systemd/system/containerd.service. Setting up docker-compose-plugin (2.35.1-1~ubuntu.22.04~jammy) ... Setting up libltdl7:amd64 (2.4.6-15build2) ... Setting up docker-ce-cli (5:28.1.1-1~ubuntu.22.04~jammy) ... Setting up libslirp0:amd64 (4.6.1-1build1) ... Setting up pigz (2.6-1) ... Setting up docker-ce-rootless-extras (5:28.1.1-1~ubuntu.22.04~jammy) ... Setting up slirp4netns (1.0.1-2) ... Setting up docker-ce (5:28.1.1-1~ubuntu.22.04~jammy) ... Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service. Created symlink /etc/systemd/system/sockets.target.wants/docker.socket → /lib/systemd/system/docker.socket. Processing triggers for man-db (2.10.2-1) ... Processing triggers for libc-bin (2.35-0ubuntu3.6) ... Scanning processes... Scanning linux images... Running kernel seems to be up-to-date. No services need to be restarted. No containers need to be restarted. No user sessions are running outdated binaries. No VM guests are running outdated hypervisor (qemu) binaries on this host.
Verify that the installation is successful by running the hello-world image
In order to verify that the installation is successful, I used the following command on the Linux Command Prompt:
sudo docker run hello-world
With the following output:
Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world e6590344b1a5: Pull complete Digest: sha256:dd01f97f252193ae3210da231b1dca0cffab4aadb3566692d6730bf93f123a48 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
The docker run command downloads a test image and runs it in a container. When the container runs, it prints a confirmation message and exits.
[https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository]
So, now I successfully installed and started Docker Engine 😊.
I also had a look at the Tip “Receiving errors when trying to run without root?”.
The docker user group exists but contains no users, which is why you’re required to use sudo to run Docker commands. Continue to Linux postinstall to allow non-privileged users to run Docker commands and for other optional configuration steps.
[https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository]
So, I navigated to the “Linux post-installation steps for Docker Engine” documentation, “Manage Docker as a non-root user” section.
Manage Docker as a non-root user
The Docker daemon binds to a Unix socket, not a TCP port. By default it’s the root user that owns the Unix socket, and other users can only access it using sudo. The Docker daemon always runs as the root user.
If you don’t want to preface the docker command with sudo, create a Unix group called docker and add users to it. When the Docker daemon starts, it creates a Unix socket accessible by members of the docker group. On some Linux distributions, the system automatically creates this group when installing Docker Engine using a package manager. In that case, there is no need for you to manually create the group.
[https://docs.docker.com/engine/install/linux-postinstall/]
I followed the steps, as described in the “Linux post-installation steps for Docker Engine” documentation, “Manage Docker as a non-root user” section.
[https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user]
In order to create the docker group, I used the following command on the Linux Command Prompt:
sudo groupadd docker
With the following output:
groupadd: group 'docker' already exists
In order to add my user (vagrant) to the docker group. I used the following command on the Linux Command Prompt:
sudo usermod -aG docker vagrant
In order to verify that I could run docker commands without sudo, I used the following command on the Linux Command Prompt:
docker run hello-world
With the following output:
docker: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/docker.sock: connect: permission denied Run 'docker run --help' for more information
In order to activate the changes to groups, I used the following command on the Linux Command Prompt:
newgrp docker
Again, in order to verify that I could run docker commands without sudo, I used the following command on the Linux Command Prompt:
docker run hello-world
With the following output:
Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
So, now I could run docker commands without sudo.
To further automate all these manual steps mentioned above, in the
env/scripts directory on my Windows laptop, I created the file docker.sh with the following content:
#!/bin/bash echo "**** Begin installing Docker Engine" #Uninstall conflicting packages for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done #Uninstall the Docker Engine, CLI, containerd, and Docker Compose packages sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras #Delete all images, containers, and volumes sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd #Remove source list and keyrings sudo rm /etc/apt/sources.list.d/docker.list sudo rm /etc/apt/keyrings/docker.asc #Set up the repository ##Update the apt package index sudo apt-get update ## Add Docker's official GPG key: sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc ## Add the repository to Apt sources: echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ##Update the apt package index sudo apt-get update -qq #Install Docker Engine ##Install the latest version of Docker Engine sudo apt-get install -yqq docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin ##Verify that Docker Engine is installed correctly by running the hello-world image sudo docker run hello-world ##use Docker as a non-root user ###Create the docker group. sudo groupadd docker ###Add your user to the docker group. sudo usermod -aG docker vagrant ###Log out and log back in so that your group membership is re-evaluated. ###If you're running Linux in a virtual machine, it may be necessary to restart the virtual machine for changes to take effect. ###Activate the changes to groups newgrp docker ###Verify that you can run docker commands without sudo. docker run hello-world echo "**** End installing Docker Engine"
Next, in my Vagrantfile, I added a Vagrant Shell provisioner to upload and execute my external script within the guest machine:
args = [] config.vm.provision "docker shell script", type: "shell", path: "scripts/docker.sh", args: args
For the demo environment to start, from the directory named env on my Windows laptop, I opened a Windows Command Prompt (cmd) and typed: vagrant up. Once the VM was running, for executing later manual steps, I used vagrant ssh to connect into the running VM.
Deploy a registry server
So, now that Docker was installed, I returned to the documentation about the registry image, “Deploy a registry server” section.
[https://distribution.github.io/distribution/about/deploying/]
Starting a local registry container
In order to start a local private registry container, I used the following command on the Linux Command Prompt:
[https://distribution.github.io/distribution/about/deploying/#run-a-local-registry]
docker run -d -p 5000:5000 --restart=always --name registry registry:3
With the following output:
Unable to find image 'registry:3' locally 3: Pulling from library/registry f18232174bc9: Pull complete e5a9c19e7b9d: Pull complete e8a894506e86: Pull complete e1822bac1992: Pull complete b5da7f963a9e: Pull complete Digest: sha256:1fc7de654f2ac1247f0b67e8a459e273b0993be7d2beda1f3f56fbf1001ed3e7 Status: Downloaded newer image for registry:3 c31829906f564dd7ace2668e33bc1123d6ba76a94fb625da2d8a3777ba20a876
My local private registry was now ready to use.
Remark about some of the used docker run flags:
-d, –detach Run container in background and print container ID
This starts a container as a background process that doesn’t occupy your terminal window.
[https://docs.docker.com/reference/cli/docker/container/run/#detach]
-p, –publish Publish a container’s port(s) to the host
This binds port 5000 of the container to TCP port 5000 on 127.0.0.1 of the host.
[https://docs.docker.com/reference/cli/docker/container/run/#publish]
–restart Restart policy to apply when a container exits
[https://docs.docker.com/reference/cli/docker/container/run/#restart]
If you want to use the registry as part of your permanent infrastructure, you should set it to restart automatically when Docker restarts or if it exits. This example uses the –restart flag to set a restart policy for the registry.
[https://distribution.github.io/distribution/about/deploying/#start-the-registry-automatically]
In order to get a list of all the docker images, I used the following command on the Linux Command Prompt:
docker image ls
With the following output:
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 3 3dec7d02aaea 2 months ago 57.7MB
hello-world latest 74cc54e27dc4 4 months ago 10.1kB
Next, I checked the list of all the docker containers:
docker container ls -a
With the following output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c31829906f56 registry:3 "/entrypoint.sh /etc…" 54 seconds ago Up 54 seconds 0.0.0.0:5000->5000/tcp registry abe8daba959c hello-world "/hello" 7 minutes ago Exited (0) 7 minutes ago brave_kapitsa 5d62734f0d55 hello-world "/hello" 7 minutes ago Exited (0) 7 minutes ago dazzling_bartik
Copying an image from Docker Hub to my local private registry
Next, I followed the steps as described in the documentation about the registry image, “Deploy a registry server” section, “Copy an image from Docker Hub to your registry” part.
[https://distribution.github.io/distribution/about/deploying/#copy-an-image-from-docker-hub-to-your-registry]
In order to copy an image from Docker Hub to my local Docker Host, I used the following command on the Linux Command Prompt:
docker pull nginx:latest
With the following output:
latest: Pulling from library/nginx 61320b01ae5e: Pull complete 670a101d432b: Pull complete 405bd2df85b6: Pull complete cc80efff8457: Pull complete 2b9310b2ee4b: Pull complete 6c4aa022e8e1: Pull complete abddc69cb49d: Pull complete Digest: sha256:fb39280b7b9eba5727c884a3c7810002e69e8f961cc373b89c92f14961d903a0 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest
Below, you see an overview of my Docker Engine at this moment:
Next, in order to create an additional tag for the existing image, I used the following command on the Linux Command Prompt:
docker tag nginx:latest localhost:5000/nginx:latest
Remarks about docker tag:
Copy an image from Docker Hub to your registry
When the first part of the tag is a hostname and port, Docker interprets this as the location of a registry, when pushing.
[https://distribution.github.io/distribution/about/deploying/#copy-an-image-from-docker-hub-to-your-registry]
Tag an image for a private registry
To push an image to a private registry and not the public Docker registry you must include the registry hostname and port (if needed).
[https://docs.docker.com/reference/cli/docker/image/tag/#tag-an-image-for-a-private-registry]
In order to get a list of all the docker images, I used the following command on the Linux Command Prompt:
docker image ls
With the following output:
REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest be69f2940aaf 7 weeks ago 192MB localhost:5000/nginx latest be69f2940aaf 7 weeks ago 192MB registry 3 3dec7d02aaea 2 months ago 57.7MB hello-world latest 74cc54e27dc4 4 months ago 10.1kB
In order to push the image to my local private registry running at localhost:5000, I used the following command on the Linux Command Prompt:
docker push localhost:5000/nginx:latest
With the following output:
The push refers to repository [localhost:5000/nginx] 941dd9dd8ee4: Pushed f6e33ee35fd0: Pushed 9fd8b974f616: Pushed a8b606cdf152: Pushed cb857378ec55: Pushed deb7d8874f38: Pushed ace34d1d784c: Pushed latest: digest: sha256:e5e2c4be5cea9bf49b2c976c65b4fca33d9d094b276a5e517d8e5748100a3c73 size: 1778
In order to remove the locally-cached nginx:latest and localhost:5000/nginx:latest images, so that I could test pulling the image from my local private registry, I used the following commands on the Linux Commands Prompt:
docker image remove nginx:latest docker image remove localhost:5000/nginx:latest
With the following output:
Untagged: nginx:latest Untagged: nginx@sha256:fb39280b7b9eba5727c884a3c7810002e69e8f961cc373b89c92f14961d903a0 Untagged: localhost:5000/nginx:latest Untagged: localhost:5000/nginx@sha256:e5e2c4be5cea9bf49b2c976c65b4fca33d9d094b276a5e517d8e5748100a3c73 Deleted: sha256:be69f2940aaf64fdf50c9c99420cbd57e10ee655ec7204df1c407e9af63d0cc1 Deleted: sha256:d4b3df3b01538a659a8990a121e2f90340dec055232275eb6e121f3af230e3c4 Deleted: sha256:8b8ba0c31936a63862b7bb3f9edd4e2721da3ccf99dc0e6dcaf289bbd212ba6f Deleted: sha256:fcef123e6b584f68369e1c45f4e582be8391b93abd1e5be6ef674ce3459ac7fd Deleted: sha256:ee697e6373f3f1a82f1a55fc29ef5ebc2c05158dcbfbeffcaf223406f429be8b Deleted: sha256:d6189b151727a846370cf1355a8b5276f6c2aa41f378cc2945205a0eb03ea861 Deleted: sha256:3c1060a9ec6601e87cbcb04366f323b6383b7f605153e7df398bc1f843e36141 Deleted: sha256:ace34d1d784c01e3f9d156687089e8f58f786e23ccd097bdbbf337d6d28b3783
In order to get a list of all the docker images, I used the following command on the Linux Command Prompt:
docker image ls
With the following output:
REPOSITORY TAG IMAGE ID CREATED SIZE registry 3 3dec7d02aaea 2 months ago 57.7MB hello-world latest 74cc54e27dc4 4 months ago 10.1kB
In order to pull the localhost:5000/nginx:latest image from my local private registry, I used the following command on the Linux Command Prompt:
docker pull localhost:5000/nginx:latest
With the following output:
latest: Pulling from nginx 3dae71ba6b94: Pull complete 670a101d432b: Pull complete 405bd2df85b6: Pull complete cc80efff8457: Pull complete 2b9310b2ee4b: Pull complete 6c4aa022e8e1: Pull complete abddc69cb49d: Pull complete Digest: sha256:e5e2c4be5cea9bf49b2c976c65b4fca33d9d094b276a5e517d8e5748100a3c73 Status: Downloaded newer image for localhost:5000/nginx:latest localhost:5000/nginx:latest
In order to get a list of all the docker images, I used the following command on the Linux Command Prompt:
docker image ls
With the following output:
REPOSITORY TAG IMAGE ID CREATED SIZE localhost:5000/nginx latest be69f2940aaf 7 weeks ago 192MB registry 3 3dec7d02aaea 2 months ago 57.7MB hello-world latest 74cc54e27dc4 4 months ago 10.1kB
So, these commands showed that, removing the locally-cached nginx:latest and localhost:5000/nginx:latest images, did not remove the localhost:5000/nginx:latest image from my local private registry.
In order to get a list of all the docker images inside my local private registry, I used the following command on the Linux Command Prompt:
curl localhost:5000/v2/_catalog
With the following output:
In order to get a list of all the tags of a docker image inside my local private registry, I used the following command on the Linux Command Prompt:
curl localhost:5000/v2/nginx/tags/list
With the following output:
{"name":"nginx","tags":["latest"]}
Remark about curl:
With my url, starting with localhost:5000, curl uses the HTTP protocol and the GET method.
If you provide a URL without a leading protocol:// scheme, curl guesses what protocol you want. It then defaults to HTTP but assumes others based on often-used hostname prefixes.
[https://curl.se/docs/manpage.html]
Remark:
Another way, to get a list of all the docker images inside my local private registry, is to use command docker exec -it local-registry sh and then navigate to directory /var/lib/registry/docker/registry/v2/repositories
Below, you see an overview of the steps with regard to the images described above:
Quarkus and Container Image extensions
So, now my local private registry was in place and I wanted to try using it, in combination with Quarkus.
Quarkus provides extensions for building (and pushing) container images.
[https://quarkus.io/guides/container-image]
As I mentioned in my previous article (in the part “Generation of Kubernetes manifests”), the Jib extension build a container image with the following name:
[https://technology.amis.nl/software-development/java/quarkus-supersonic-subatomic-java-trying-out-quarkus-guide-quarkus-kubernetes-extension-reinvestigated-part-1/]
docker.io/vagrant/kubernetes-quickstart:1.0.0-SNAPSHOT
An important thing to note about the Deployment (or StatefulSet) is that is uses yourDockerUsername/kubernetes-quickstart:1.0.0-SNAPSHOT as the container image of the Pod. The name of the image is controlled by the Jib extension and can be customized using the usual application.properties.
[https://quarkus.io/guides/deploying-to-kubernetes]
An important benefit of using the Jib extension is that it provides the ability to create a container image without having to have any dedicated client side tooling (like Docker) or running daemon processes (like the Docker daemon) when all that is needed is the ability to push to a container image registry.
In situations where all that is needed to build a container image and no push to a registry is necessary (essentially by having set quarkus.container-image.build=true and left quarkus.container-image.push unset – it defaults to false), then this extension creates a container image and registers it with the Docker daemon. This means that although Docker isn’t used to build the image, it is nevertheless necessary. Also note that using this mode, the built container image will show up when executing docker images.
[https://quarkus.io/guides/container-image#jib]
To build a container image for your project, quarkus.container-image.build=true needs to be set using any of the ways that Quarkus supports. For example for Maven:
[https://quarkus.io/guides/container-image#building]
./mvnw install -Dquarkus.container-image.build=true
To push a container image for your project, quarkus.container-image.push=true needs to be set using any of the ways that Quarkus supports. For example for Maven:
[https://quarkus.io/guides/container-image#pushing]
./mvnw install -Dquarkus.container-image.push=true
First, on my Windows laptop, in my shared folder, I navigated to kubernetes-quickstart\src\main\resources and added the file application.properties with the following content:
quarkus.container-image.registry=localhost:5000 quarkus.container-image.group=quarkus
Next, I used the following commands on the Linux Command Prompt:
cd /mnt/mysharedfolder/kubernetes-quickstart mvn clean install
This resulted in the following container image of the Pod being used in the Deployment part of the
generated target/kuberetes.yml Kubernetes manifest:
image: localhost:5000/quarkus/kubernetes-quickstart:1.0.0-SNAPSHOT
Next, I used the following command on the Linux Command Prompt:
mvn clean install -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true
With the following output:
[INFO] --- jar:3.4.1:jar (default-jar) @ kubernetes-quickstart --- [INFO] Building jar: /mnt/mysharedfolder/kubernetes-quickstart/target/kubernetes-quickstart-1.0.0-SNAPSHOT.jar [INFO] [INFO] --- quarkus:3.22.3:build (default) @ kubernetes-quickstart --- [INFO] [io.quarkus.kubernetes.deployment.PropertyUtil] Kubernetes manifests are generated with 'The container port http' having default value '8080'. The app and manifests will get out of sync if the property 'quarkus.http.port' is changed at runtime. [INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Starting (local) container image build for jar using jib. [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] Base image 'registry.access.redhat.com/ubi9/openjdk-21-runtime:1.21' does not use a specific image digest - build may not be reproducible [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Using base image with digest: sha256:360822c35c5741f542ab78fe123e6c4d9b68e0113a88d6e0250bb1f377b17f29 [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will be retried [WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] GET https://localhost:5000/v2/ failed and will NOT be retried [ERROR] [io.quarkus.container.image.jib.deployment.JibProcessor] I/O error for image [localhost:5000/quarkus/kubernetes-quickstart]: [ERROR] [io.quarkus.container.image.jib.deployment.JibProcessor] javax.net.ssl.SSLException [ERROR] [io.quarkus.container.image.jib.deployment.JibProcessor] Unsupported or unrecognized SSL message [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 01:32 min [INFO] Finished at: 2025-06-05T15:37:04Z [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal io.quarkus.platform:quarkus-maven-plugin:3.22.3:build (default) on project kubernetes-quickstart: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [ERROR] [error]: Build step io.quarkus.container.image.jib.deployment.JibProcessor#buildFromJar threw an exception: java.lang.RuntimeException: Unable to create container image [ERROR] at io.quarkus.container.image.jib.deployment.JibProcessor.containerize(JibProcessor.java:258) [ERROR] at io.quarkus.container.image.jib.deployment.JibProcessor.buildFromJar(JibProcessor.java:185) [ERROR] at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:735) [ERROR] at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:856) [ERROR] at io.quarkus.builder.BuildContext.run(BuildContext.java:255) [ERROR] at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) [ERROR] at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675) [ERROR] at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654) [ERROR] at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627) [ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594) [ERROR] at java.base/java.lang.Thread.run(Thread.java:1447) [ERROR] at org.jboss.threads.JBossThread.run(JBossThread.java:499) [ERROR] Caused by: com.google.cloud.tools.jib.api.InsecureRegistryException: Failed to verify the server at https://localhost:5000/v2/ because only secure connections are allowed. [ERROR] at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.call(RegistryEndpointCaller.java:179) [ERROR] at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.call(RegistryEndpointCaller.java:114) [ERROR] at com.google.cloud.tools.jib.registry.RegistryClient.callRegistryEndpoint(RegistryClient.java:623) [ERROR] at com.google.cloud.tools.jib.registry.RegistryClient.doBearerAuth(RegistryClient.java:318) [ERROR] at com.google.cloud.tools.jib.registry.RegistryClient.doPushBearerAuth(RegistryClient.java:308) [ERROR] at com.google.cloud.tools.jib.builder.steps.AuthenticatePushStep.call(AuthenticatePushStep.java:66) [ERROR] at com.google.cloud.tools.jib.builder.steps.AuthenticatePushStep.call(AuthenticatePushStep.java:35) [ERROR] at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:128) [ERROR] at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:74) [ERROR] at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:80) [ERROR] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1095) [ERROR] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:619) [ERROR] at java.base/java.lang.Thread.run(Thread.java:1447) [ERROR] Caused by: javax.net.ssl.SSLException: Unsupported or unrecognized SSL message [ERROR] at java.base/sun.security.ssl.SSLSocketInputRecord.handleUnknownRecord(SSLSocketInputRecord.java:462) [ERROR] at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:175) [ERROR] at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111) [ERROR] at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506) [ERROR] at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421) [ERROR] at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455) [ERROR] at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426) [ERROR] at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436) [ERROR] at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384) [ERROR] at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142) [ERROR] at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376) [ERROR] at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393) [ERROR] at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) [ERROR] at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) [ERROR] at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) [ERROR] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) [ERROR] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) [ERROR] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) [ERROR] at com.google.api.client.http.apache.v2.ApacheHttpRequest.execute(ApacheHttpRequest.java:73) [ERROR] at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1012) [ERROR] at com.google.cloud.tools.jib.http.FailoverHttpClient.call(FailoverHttpClient.java:349) [ERROR] at com.google.cloud.tools.jib.http.FailoverHttpClient.call(FailoverHttpClient.java:266) [ERROR] at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.call(RegistryEndpointCaller.java:138) [ERROR] ... 12 more [ERROR] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
As you can see in the output above, the following error message is shown:
[ERROR] Caused by: com.google.cloud.tools.jib.api.InsecureRegistryException: Failed to verify the server at https://localhost:5000/v2/ because only secure connections are allowed.
So, only secure connections are allowed. Quarkus uses the HTTPS protocol, to connect to my local private registry. So, I had to secure it using TLS.
But, more about that you can read in my next article in the series of articles about Quarkus.
I conclude this article.
Some years ago, I also wrote articles about the Quarkus Kubernetes Extension using the default public Docker image registry. This time, I wanted to try out using a local private registry.
In this article, I shared with you the steps I took, to install a local private registry in my demo environment and using it with Quarkus. I used the registry Docker Official Image, a Distribution implementation for storing and distributing of container images and artifacts.
Feel free, among my other articles on this subject, to read:
- “Quarkus – Supersonic Subatomic Java, trying out Quarkus guide “Quarkus – Kubernetes extension” (part 1)”, September 27, 2020
In this article, you can read more about the steps I took, trying out the Quarkus code guide “Quarkus – Kubernetes extension”, and more specific the steps related to using custom labels and annotations. - “Quarkus – Supersonic Subatomic Java, trying out some Quarkus code guides (part2)”, October 3, 2020
In this article, you can read more about the steps I took, trying out the Quarkus code guide “Quarkus – Kubernetes extension”, and more specific the steps related to customizing the namespace, the service account name, the number of replicas and the type of service. - “Quarkus – Supersonic Subatomic Java, trying out Quarkus guide “Quarkus – Kubernetes extension (part 3)”, October 10, 2020
In this article, you can read more about the steps I took, trying out the Quarkus code guide “Quarkus – Kubernetes extension”, and more specific the steps related the automatic deployment of the generated resources to a target platform, in my case K3s (lightweight certified Kubernetes distribution).