14 Private Container Registries

Set up a local, private container registry server to host container images within an organization. A private registry can also be used to mirror the Oracle Container Registry.

The registry server is a container application. The host must have an Internet connection to download the registry image from Docker Hub or, if support is required, from the Oracle Container Registry.

You can create a secure private registry, which requires you to set up TLS. When you set up TLS, you can use a self signed Certificate Authority (CA) certificate, or a certificate signed by a CA. Otherwise, the registry can be created as an insecure registry for testing and development purposes.

Note:

The registry image from Docker Hub can be used to set up both an insecure registry and a secure registry. The registry image from the Oracle Container Registry can only be used to set up a secure registry.

Creating an Insecure Registry

Create a local container registry without TLS. This can be used for testing or development. A secure registry that uses TLS is recommended for a production system.

If you create an insecure registry, you can add it to the Podman registry configuration file to avoid using the --tls-verify=false option when using the registry. For more information, see Adding Insecure Registries.

  1. Create the registry.

    Use the podman create command to create the registry. For example:

    sudo podman run -d -p 5000:5000 --name registry --restart always registry:2

    Or for a standard user:

    podman run -d -p 5000:5000 --name registry --restart always registry:2

    The -d option runs the container in the background.

    The -p option publishes the port mapping. If you're using the default ports, set this to 5000:5000. If port 5000 is already in use, assign another port, for example use 5001:5000.

    The --name option sets the name of the registry container. This is commonly set to registry.

    The container registry image is pulled from Docker Hub using the short name of registry:2, though you could also use the full image location of docker.io/library/registry:2.

    For more information on the options, use the podman run --help command.

  2. Verify the registry container is running:

    Use the podman ps command to verify the registry container is running.

    sudo podman ps

    Or for a standard user:

    podman ps

Creating a Secure Registry

Create a local container registry with TLS. A secure registry that uses TLS is recommended for a production system.

Before you begin, ensure you have considered the prerequisites:

  • The registry server requires at least 15 GB of available disk space to store registry data in /opt/registry/.

  • As a good practice, create a separate file system for the registry, preferably a Btrfs formatted file system. By using the Btrfs file system, you can easily scale the registry file system and leverage Btrfs features such as file system snapshots. For information on setting up Btrfs, see the following documents:

  • The registry host requires a valid X.509 certificate and private key to enable Transport Layer Security (TLS) with the registry, similar to using TLS for a web server. You can use either a certificate signed by a trusted Certificate Authority (CA), or a self signed certificate. A self signed certificate can be used for testing purposes. For information about creating a self signed certificate and private key, see Oracle Linux: Managing Certificates and Public Key Infrastructure.

    If the host already has an X.509 certificate, you can use it with Podman to create the private registry. If you're using the host's X.509 certificate and it was issued by an intermediate CA, combine the host's certificate with the intermediate CA's certificate to create a chained certificate. This creates a certificate that includes the both the host and intermediate CA certificate so it can be validated by Podman. Use the cat command to do this, using the format:

    sudo cat host_certificate.crt intermediate_certificate.pem > chained_certificate.crt

    For example:

    sudo cat myregistry.example.com.crt intermediate-ca.pem > domain.crt
  1. Create the required directories.

    The /opt/registry/ directory is used to store the registry data. The certs directory stores the certificate and private key, and the data directory is used to store the images pushed to the registry.

    sudo mkdir -p /opt/registry/{certs,data}
  2. Copy the certificate and key to the /opt/registry/certs/ directory.

    Use the format:

    sudo cp certfile /opt/registry/certs/domain.crt
    sudo cp keyfile /opt/registry/certs/domain.key

    Replace certfile with the full path to the host's X.509 certificate, or to the chained certificate. Replace keyfile with the full path to the host's private key. For example:

    sudo cp /etc/pki/tls/certs/registry.example.com.crt /opt/registry/certs/domain.crt
    sudo cp /etc/pki/tls/private/registry.example.com.key /opt/registry/certs/domain.key
  3. Set private key permissions.

    Set the correct file permissions for the private key.

    sudo chmod 600 /opt/registry/certs/domain.key
  4. Create the registry.

    Use the podman create command to create the registry. For example:

    sudo podman run --name registry \
    -d \
    -p 5000:5000 \
    -v /opt/registry/data:/var/lib/registry:z \
    -v /opt/registry/certs:/certs:z \
    -e "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt" \
    -e "REGISTRY_HTTP_TLS_KEY=/certs/domain.key" \
    -e REGISTRY_AUTH="" \
    registry:2

    The --name option sets the name of the registry container. This is commonly set to registry.

    The -d option runs the container in the background.

    The -p option publishes the port mapping. If you're using the default ports, set this to 5000:5000. If port 5000 is already in use, assign another port, for example use 5001:5000.

    The -v options mount local directories in the container.

    Set environment variables to use with the registry container using the -e option. Use this option to set the location of the X.509 certificate and key information.

    The container registry image is pulled from Docker Hub using the short name of registry:2, though you could also use the full image location of docker.io/library/registry:2. You can also set this to pull from the Oracle Container Registry by setting the container to container-registry.oracle.com/os/registry:latest.

    For more information on the options, use the podman run --help command.

  5. Verify the registry container is running:

    Use the podman ps command to verify the registry container is running.

    sudo podman ps
  6. Open the registry port in the firewall.

    If you're running a firewall, ensure the TCP port you want the container registry to listen on is accessible. For example:

    sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp
    sudo firewall-cmd --zone=internal --permanent --add-port=5000/tcp

    Reload the firewalld configuration:

    sudo firewall-cmd --reload
  7. Configure the registry with Podman.

    Add the container registry to the Podman configuration file on each host that needs to access the registry. For information on configuring registries, see Configuring Registries.

Distributing X.509 Certificates

If the registry host uses a self-signed X.509 certificate, you must distribute the certificate to all the hosts in the deployment for which you intend to use the local container registry.

For the root user, certificates for each registry are stored in /etc/containers/certs.d/registry_hostname:port/. For standard users, certificates can be stored in $HOME/.config/containers/certs.d/registry_hostname:port/. Change registry_hostname to the name of the registry host, and port to the port number for the container registry server (5000 by default).

Podman, Buildah, and Skopeo commands that interact with registries also often provide a --cert-dir option to specify an alternate location for these certificates.

  1. Create a certs.d directory.

    Create the appropriate certs.d location for the registry host and the user. For the root user, use the format:

    sudo mkdir -p /etc/containers/certs.d/registry_hostname:port

    For a standard user, use the format:

    mkdir -p $HOME/.config/containers/certs.d/registry_hostname:port

    Replace registry_hostname with the name of the server running the container registry. Replace port with the port number to access the registry. For example:

    sudo mkdir -p /etc/containers/certs.d/myregistry.example.com:5000

    Or for the standard user:

    mkdir -p $HOME/.config/containers/certs.d/myregistry.example.com:5000
  2. Copy the X.509 certificate from the registry host.
    sudo scp user@registry_hostname:/opt/registry/certs/domain.crt \
    /etc/containers/certs.d/registry_hostname:port/ca.crt

    Or for the standard user:

    scp user@registry_hostname:/opt/registry/certs/domain.crt \
    $HOME/.config/containers/certs.d/registry_hostname:port/ca.crt

Importing Images Into a Registry

When you have set up a private container registry, you can import images into the registry so that they can be used to deploy containers. You can pull images from a registry, such as the Oracle Container Registry, and then commit them to a local registry. You can also create custom images based on upstream images.

  1. Pull an image from a registry.

    For example, pull an image from the Oracle Container Registry:

    podman pull container-registry.oracle.com/os/oraclelinux:9-slim
  2. Tag the image.

    Tag the image so that it points to the local registry. For example:

    podman tag container-registry.oracle.com/os/oraclelinux:9-slim myregistry.example.com:5000/ol9image:v1

    In this example, myregistry.example.com:5000 is the location of the private registry. Change this to the location of the private registry. If you're using an insecure registry on the same host, you can use localhost:5000 for the registry location. The repository and tag name, ol9image:v1 in this example, must all be in lowercase to be a valid tag.

  3. Push the image to the registry.

    Push the image to the registry, for example:

    podman push myregistry.example.com:5000/ol9image:v1 

    If you're pushing to an insecure registry, include the --tls-verify=false option.

  4. Verify the image is loaded.

    Check the image is loaded to the container registry by pulling the image.

    First, remove the existing local image pushed in the previous step.

    podman image rm ol9image:v1

    Pull the image from the registry:

    podman pull myregistry.example.com:5000/ol9image:v1

    Verify the local image pulled from the registry:

    podman images

See Buildah for more information about how you can create images. When you have committed a customized image, you can tag it and push it to the local registry.