It is now possible to bisect CVEs (zli cve diff) between two image tags/versions in the same repository. Furthermore, a CVE query for a particular image tag can return a detailed description of CVEs.
It is now possible to bisect CVEs (zli cve diff) between two image tags/versions in the same repository. Furthermore, a CVE query for a particular image tag can return a detailed description of CVEs.
Support for hot reloading of LDAP credentials file¶
Since v2.0.0, LDAP credentials have been specified in a separate file. Starting with this version, the file is watched and changes applied without restarting zot.
Support is added for OCI Distribution Spec v1.1.0-rc3 and OCI Image Spec v1.1.0-rc4. The OCI changes are summarized here. These specifications allow arbitrary artifact types and references so that software supply chain use cases can be supported (SBOMs, signatures, etc). Currently, oras and regclient support this spec.
Using the new zot GUI, you can browse a zot registry for container images and artifacts. The web interface provides the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.
When creating authorization policies, you can assign multiple users to a named group. A group-specific authorization policy can then be defined, specifying allowed access and actions for the group.
Configuration syntax change: In the previous release, authorization policies were defined directly under the accessControl key in the zot configuration file. With the new ability to create authorization groups, it becomes necessary to add a new repositories key below accessControl. Beginning with zot v2.0.0, the set of authorization policies are now defined under the repositories key.
Deduplication, a storage space saving feature, now runs or reverts at startup depending on whether the feature is enabled or disabled. You can trigger deduplication by enabling it and then restarting zot.
In the zot GUI, you can bookmark an image so that it can be easily found later. Bookmarked images appear in search queries when the bookmarked option is enabled.
You can perform a global search for a digest (SHA hash) using either the UI or the CLI. This function is useful when an issue is found in a layer that is used by multiple images. In the UI Search box, for example, begin typing sha256: followed by a partial or complete digest value to see a dropdown list of images that contain the layer with the digest value.
A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. In addition to supporting direct GraphQL queries through the API, zot hosts the GraphQL Playground, which provides an interactive graphical environment for GraphQL queries.
You can adjust the background scheduler based on your deployment requirements for tasks that are handled in the background, such as garbage collection. See Configuring zot.
The two types of state (images and image metadata) can both now be on remote storage so that zot process lifecycle and its storage can be managed and scaled independently.
When two or more image tags point to the same image digest and the image is deleted by digest causes data loss and dangling references. A new behavior-based policy called detectManifestCollision was added to prevent this.
\ No newline at end of file
diff --git a/v2.1.0/pdf/document.pdf b/v2.1.0/pdf/document.pdf
index 743398d..9b57e29 100644
Binary files a/v2.1.0/pdf/document.pdf and b/v2.1.0/pdf/document.pdf differ
diff --git a/v2.1.0/search/search_index.json b/v2.1.0/search/search_index.json
index 9cae58f..b80a264 100644
--- a/v2.1.0/search/search_index.json
+++ b/v2.1.0/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"admin-guide/admin-configuration/","title":"Configuring zot","text":"
The registry administrator configures zot primarily through settings in the configuration file.
Using the information in this guide, you can compose a configuration file with the settings and features you require for your zot registry server.
Before launching zot with a new configuration, we recommend that you verify the syntax of your configuration as described in Verifying the configuration file.
The configuration file is a JSON or YAML file that contains all configuration settings for zot functions such as:
network
storage
authentication
authorization
logging
metrics
synchronization with other registries
clustering
The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:
zot serve config.json
The instructions and examples in this guide use zot as the name of the zot executable file. The examples do not include the path to the executable file.
When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. This initial file is similar to the following example:
The configuration file contains the Distribution Specification version (distSpecVersion). The structure and content of other attributes are described in the later sections of this guide.
Additional registry features that are not a part of the Distribution Specification are allowed to be added as Extensions.
With a full (not minimal) zot image, the following extension features can be enabled and configured under an extensions attribute in the configuration file as shown in the following example.
The extension features are available only with a full zot image. With a minimal zot image, the extensions section is ignored if present.
The following features are configured under the extensions attribute.
Metrics
Sync
Search
Scrub
Lint
ImageTrust
UI
An extension feature is usually enabled by the presence of the feature\u2019s attribute under extensions. An extension feature can then be disabled by either omitting the feature attribute or by including an enable attribute with a value of false.
Two API-only extensions, User Preferences and Mgmt, are not enabled or configured under the extensions section of the configuration file. These API-only extensions are enabled as follows:
Mgmt is enabled when the Search extension is enabled.
User Preferences is enabled when both the Search and UI extensions are enabled.
"},{"location":"admin-guide/admin-configuration/#enabling-and-disabling-extensions","title":"Enabling and disabling extensions","text":"
Following is an example of enabling or disabling a feature in the extensions section. The scrub feature is enabled in these two configurations:
New functionality can be added to the zot registry by developing custom extensions for integration into zot. For information about developing extensions, see Developing New Extensions.
The following table lists the configurable attributes.
Attribute Description address The IP address of the zot server. port The port number of the zot server. realm The security policy domain defined for the server. tls The included attributes in this section specify the Transport Layer Security (TLS) settings for the server. cert The path and filename of the server\u2019s SSL/TLS certificate. key The path and filename of the server\u2019s registry key."},{"location":"admin-guide/admin-configuration/#storage","title":"Storage","text":"
Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.
Filesystem storage is configured with the storage attribute in the zot configuration file, as shown in the following simple example.
With zot, you have the option to store your registry image files either in local filesystem storage or in cloud storage, such as an Amazon Simple Storage Service (S3) bucket.
zot can store and serve files from one or more local directories (folders). A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.
Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.
Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.
Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.
Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.
After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. The zot configuration model allows for enabling and disabling garbage collection (gc). The model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs.
The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.
For detailed information about configuring local or remote storage and storage features for your zot registry, see Storage Planning with zot.
"},{"location":"admin-guide/admin-configuration/#security-and-hardening","title":"Security and hardening","text":""},{"location":"admin-guide/admin-configuration/#authentication","title":"Authentication","text":"
zot supports authentication by the following methods:
TLS mutual authentication
Basic local authentication using an htpasswd file
LDAP authentication
Bearer (OAuth2) authentication using an HTTP Bearer token
For detailed information about configuring authentication for your zot registry, see User Authentication and Authorization with zot.
User identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific repository paths.
For detailed information about configuring access control policies for your zot registry, see User Authentication and Authorization with zot.
"},{"location":"admin-guide/admin-configuration/#preventing-automated-attacks-with-failure-delay","title":"Preventing automated attacks with failure delay","text":"
Use the auth and failDelay attributes under http in the configuration file to delay the response to an authentication failure. A delayed response helps to prevent automated attacks. The configuration is shown in the following example.
The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.
In this example, the Rate attribute directly under Ratelimit sets a global rate limit of ten API calls per second. You can optionally override the global limit for specific API Methods. In this example, API GET calls are limited to five per second.
zot supports a range of monitoring tools including the following:
Logging
Logging for zot operations is configured with the log attribute in the configuration file.
Metrics
Metrics data is available in a Prometheus format. A full zot image with extensions includes a node exporter. A minimal zot image can use an external node exporter such as zxp.
Benchmarking
The zot project includes the zb tool, which allows you to benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification.
Performance profiling
Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.
When zot is deployed in a Kubernetes setup, a site reliability engineering (SRE) operator can monitor service level indicators (SLI) such as metrics and logs. Metrics will appear in Prometheus using the zot metrics extension, while logs will appear in the Elasticsearch stack (ELK stack) using Filebeat.
For detailed information about the monitoring tools, see Monitoring the registry.
For detailed information about benchmarking, see Benchmarking zot with zb.
For detailed information about performance profiling, see Performance Profiling in zot.
To ensure high-availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a loadbalancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Loadbalancing across many zot replicas can also increase aggregate network throughput.
For detailed information about clustering with zot, see zot Clustering.
"},{"location":"admin-guide/admin-configuration/#syncing-and-mirroring-registries","title":"Syncing and mirroring registries","text":"
A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync extension feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Synchronization between registries can be implemented by periodic polling of the upstream registry or synchronization can occur on demand, when a user pulls an image from the downstream registry.
As with git, wherein every clone is a full repository, you can configure a local zot instance to be a full OCI mirror registry. This allows for a fully distributed disconnected container image build pipeline.
For detailed information about syncing and mirroring, see OCI Registry Mirroring With zot.
The following table lists the configurable attributes of the lint extension.
Attribute Description enable If this attribute is missing, incoming image linting is disabled by default. Linting can be enabled by including this attribute and setting it to true. mandatoryAnnotations A list of annotations that are required to be present in the image being pushed to the repository.
If the mandatory annotations option is configured when you push an image, linter will verify that the mandatory annotations list present in the configuration is also found in the manifest's annotations list. If any annotations are missing, the push is denied.
"},{"location":"admin-guide/admin-configuration/#verifying-the-signatures-of-uploaded-images","title":"Verifying the signatures of uploaded images","text":"
The trust extension provides a mechanism to verify image signatures using certificates and public keys.
To enable image signature verification, you must add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:
You must also upload public keys (for cosign) or certificates (for notation) that can be used to verify the image signatures.
For detailed information about configuring image signature verification, see Verifying image signatures.
"},{"location":"admin-guide/admin-configuration/#enabling-the-registrys-graphical-user-interface","title":"Enabling the registry's graphical user interface","text":"
Using the zot graphical user interface (GUI), a user can browse a zot registry for container images and artifacts.
To configure zot's GUI, add the ui attribute under extensions in the configuration file, as shown in the following example:
The following table lists the configurable attributes of the ui extension.
Attribute Description enable If this attribute is missing, the zot GUI is disabled by default. The GUI can be enabled by including this attribute and setting it to true."},{"location":"admin-guide/admin-configuration/#scrubbing-the-image-registry","title":"Scrubbing the image registry","text":"
To check the integrity of the filesystem and the data in the registry, you can schedule a periodic scrub operation. The scrub process traverses the filesystem, verifying that all data blocks are readable. While running, the process may slightly reduce the registry performance.
To enable scrubbing, add the scrub attribute under extensions in the configuration file, as shown in the following example:
The following table lists the configurable attributes for scrubbing the registry.
Attribute Description enable If this attribute is missing, registry scrubbing is enabled by default. Scrubbing can be disabled by setting this attribute to false. interval The time interval between periodic scrub operations. This value must be at least two hours (2h)."},{"location":"admin-guide/admin-configuration/#scheduling-background-tasks","title":"Scheduling background tasks","text":"
Some zot functions, such as garbage collection and registry synchronization, run as background tasks. These tasks are queued and executed by the scheduler.
The scheduler is by default allowed to simultaneously run a maximum number of tasks equal to four times the number of CPUs available to the zot process. For most users, there should be no need to modify this maximum number. If such a need arises, you can configure a new maximum number of simultaneous tasks in the numWorkers property of the scheduler attribute in the configuration file, as shown in the following example.
"},{"location":"admin-guide/admin-configuration/#enhanced-searching-and-querying-images","title":"Enhanced searching and querying images","text":"
While basic searching is always enabled for images in the zot registry, you can enable enhanced registry searching and filtering using graphQL.
Add the search attribute under extensions in the configuration file to enable and configure the enhanced search extension, as shown in the following example.
The following table lists the configurable attributes for enhanced search.
Attribute Description enable If this attribute is missing, enhanced search is enabled by default. Enhanced search can be disabled by setting this attribute to false. cve Extends enhanced search to allow searching of Common Vulnerabilities and Exposures (CVE). updateInterval Sets the interval at which the searchable database of CVE items is refreshed."},{"location":"admin-guide/admin-configuration/#setting-user-preferences","title":"Setting user preferences","text":"
The user preferences extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.
The user preferences extension is enabled by default when the search and ui extensions are enabled. There are no other configuration file fields for this extension.
A userprefs API endpoint accepts as a query parameter an action to perform along with any other required parameters for the specified action. The actions currently implemented do not require an HTTP payload, nor do they return any related data other than an HTTP response code.
"},{"location":"admin-guide/admin-configuration/#verifying-the-configuration-file","title":"Verifying the configuration file","text":"
Before launching zot, verify the syntax of your configuration file using the following command:
zot verify <configfile>
Verifying the configuration file protects against operator errors and any conflicts arising from zot release version changes.
After verifying your configuration file, you can launch zot with the following command:
zot serve <configfile>
"},{"location":"admin-guide/admin-getting-started/","title":"Getting Started with zot Administration","text":"
This document helps you to deploy an appropriate zot image or to build zot if desired.
After deploying zot, proceed to Configuring zot to choose and configure the features you need.
"},{"location":"admin-guide/admin-getting-started/#installing-zot","title":"Installing zot","text":""},{"location":"admin-guide/admin-getting-started/#how-to-get-zot","title":"How to get zot","text":"
The zot project is hosted on GitHub at project-zot. From GitHub, you can download zot executable binary images or full source code.
zot is officially supported on Linux and Apple MacOS platforms, using Intel or ARM processors. However, development should be possible on any platform that supports the golang toolchain.
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS freebsd amd64 Intel-based FreeBSD* freebsd arm64 ARM-based FreeBSD*
* NOTE: While binary images are available for FreeBSD, building container images is not supported at this time.
Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.
Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.
You can launch a zot binary as a container service using a container management tool such as Podman, Docker, or Helm.
You can launch zot as a host-level service by downloading a binary image and running it as a systemd service.
You can copy or clone the full zot source code and build an image with custom build flags.
"},{"location":"admin-guide/admin-getting-started/#deploying-a-zot-binary-image","title":"Deploying a zot binary image","text":"
Executable binary images for supported server platforms and architectures are available from the zot package repository in GitHub.
You can download the appropriate binary image and run it directly on your server, or you can use a container management tool such as Podman, runc, Helm, or Docker to fetch and deploy the image in a container on your server.
For convenience, you can rename the binary image file to simply zot.
"},{"location":"admin-guide/admin-getting-started/#example-deploying-with-a-container-manager","title":"Example: Deploying with a container manager","text":"
Using a container manager such as Podman, runc, Helm, or Docker, you can install a zot binary image, as in the following examples.
Using podman
podman run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest\n\npodman run -p 5000:5000 ghcr.io/project-zot/zot-minimal-linux-amd64:latest\n
Click here to view an example of deploying using podman.
Using docker
docker run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest\n
Each of these example commands pulls a zot binary image from the GitHub Container Registry (ghcr.io) and launches a zot image registry at http://localhost:5000.
Click here to view an example of deploying using docker.
"},{"location":"admin-guide/admin-getting-started/#building-zot-from-source","title":"Building zot from source","text":""},{"location":"admin-guide/admin-getting-started/#prerequisites","title":"Prerequisites","text":""},{"location":"admin-guide/admin-getting-started/#install-golang","title":"Install golang","text":"
Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.
You must use a golang version of at least the minimum specified in go.mod or the build will fail.
"},{"location":"admin-guide/admin-getting-started/#building-an-executable-binary-from-source","title":"Building an executable binary from source","text":"
Download or clone the full zot project from GitHub at project-zot. To clone the zot project from GitHub, use this command:
To build zot, execute the make command in the zot directory using the following general syntax:
make OS=os ARCH=architecture {binary | binary-minimal}
The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.
The binary option builds the full zot binary image with all extensions.
The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.
For example, to build a zot image with extensions for an Intel-based linux server, use the following command:
make OS=linux ARCH=amd64 binary\n
The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-linux-amd64-minimal.
For convenience, you can rename the binary image file to simply zot.
"},{"location":"admin-guide/admin-getting-started/#building-a-zot-container-image-from-source","title":"Building a zot container image from source","text":"
with Stacker
Using the settings in stacker.yaml, you can build a container image that runs the latest zot by running the following command:
make binary-stacker\n
with Docker
A sample Dockerfile is provided on the zot project page in GitHub. You can edit the sample file with your specific values, such as the desired operating system, hardware architecture, and full or minimal build, as in this example:
ARG OS=linux\nARG ARCH=amd64\n\nRUN make COMMIT=$COMMIT OS=$OS ARCH=$ARCH clean binary-minimal\n
Using your edited Dockerfile, you can build a container image that runs the latest zot by running the following command:
make image\n
"},{"location":"admin-guide/admin-getting-started/#deploying-the-container-image","title":"Deploying the container image","text":"
Deploy the image using your container manager, such as Podman, runc, Helm, or Docker, as in these examples:
with Podman
podman run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest\n
with Docker
docker run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest\n
A container image built with the sample Dockerfile and deployed with the example command results in a running registry at http://localhost:5000. Registry content is stored at .registry, which is bind mounted to /var/lib/registry in the container. By default, auth is disabled. As part of the build, a YAML configuration file is created at /etc/zot/config.yml in the container.
You can override the configuration file with custom configuration settings in the deployment command and in a local configuration file as shown in this example:
The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:
zot serve config.yml
For convenience, you can rename the binary image file to simply zot.The instructions and examples in this guide use zot as the name of the zot executable file and do not include the path to the executable file.
You configure zot primarily through adding and modifying settings in the zot configuration file. The configuration file is a JSON or YAML file that contains all configuration settings for zot functions.
When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. You can modify the initial file or you can create a new file.
Follow the instructions in Configuring zot, to compose a configuration file with the settings and features you require for your zot registry server.
"},{"location":"articles/authn-authz/","title":"User Authentication and Authorization with zot","text":"
A robust set of authentication/authorization options are supported:
Authentication
TLS, including mTLS
Username/password or token-based user authentication
LDAP
htpasswd
OAuth2 with bearer token
Authorization
Powerful identity-based access controls for repositories or specific repository paths
OpenID/OAuth2 social login with Google, GitHub, GitLab, and dex
The zot configuration model supports both authentication and authorization. Authentication credentials allow access to zot HTTP APIs. Authorization policies provide fine-grained control of the actions each authenticated user can perform in the registry.
Because authentication credentials are passed over HTTP, it is imperative that TLS be enabled. You can enable and configure TLS authentication in the zot configuration file, as shown in the following example.
When basic HTTP authentication is used, the username and password credentials are joined by a colon (:), base64 encoded, and passed in the HTTP Authorization header.
To avoid passing the username and password credentials for every HTTP request, a zot client can use bearer token-based authentication. In this method, the client first authenticates with a token server and receives a short-lived token. The client then passes this token in the HTTP Authorization header, specifying Bearer as the authentication scheme.
Configure bearer authentication in the zot configuration file as shown in this example.
The following table lists the configurable attributes.
Attribute Description realm A string typically related to the authentication scheme (BASIC and BEARER). service The name of the authentication service. cert The path and filename of the server\u2019s SSL/TLS certificate."},{"location":"articles/authn-authz/#mutual-tls-authentication","title":"Mutual TLS authentication","text":"
zot supports basic TLS and password-less mutual TLS authentication (mTLS). Specifying a cacert file in the TLS section of the zot configuration file enables mTLS. The cacert parameter is used to validate the client-side TLS certificates.
The following table lists the configurable attributes.
Attribute Description cert The path and filename of the server\u2019s SSL/TLS certificate. key The path and filename of the server\u2019s registry key. cacert The path and filename of the server\u2019s cacerts file, which contains trusted certificate authority (CA) certificates."},{"location":"articles/authn-authz/#preventing-automated-attacks-with-failure-delay","title":"Preventing automated attacks with failure delay","text":"
To help prevent automated attacks, you can add a delayed response to an authentication failure. Configure the failDelay attribute in the configuration file as shown in the following example.
The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.
You can implement server-side authentication for zot using htpasswd or LDAP or both.
When both htpasswd and LDAP configuration are specified, LDAP authentication is given preference. Because htpasswd authentication is strictly local and requires no remote service, htpasswd serves as a fail-safe authentication mechanism should LDAP become unavailable.
zot supports integration with an LDAP-based authentication service such as Microsoft Windows Active Directory (AD). Enable and configure LDAP authentication in the zot configuration file, as shown in the following example.
The following table lists the configurable attributes for LDAP authentication.
Attribute Description credentialsFile The path to a file containing the bind credentials for LDAP. address The IP address or hostname of the LDAP server. port The port number used by the LDAP service. startTLS Set to true to enable TLS communication with the LDAP server. baseDN Starting location within the LDAP directory for performing user searches. userAttribute Attribute name used to obtain the username. userGroupAttribute Attribute name used to obtain groups to which a user belongs. skipVerify Skip TLS verification. subtreeSearch Set to true to expand the scope for search to include subtrees of the base DN.
To allow for separation of configuration and credentials, the credentials for the LDAP server are specified in a separate file, as shown in the following example.
The following table lists the configurable attributes of the LDAP credentials file.
Attribute Description bindDN Base Distinguished Name for the LDAP search. bindPassword Password of the bind LDAP user."},{"location":"articles/authn-authz/#htpasswd","title":"htpasswd","text":"
Enable and configure htpasswd authentication in the zot configuration file, as shown in the following example.
For strong security, make sure to use the -B option, specifying the bcrypt hashing algorithm. This is the only algorithm supported by zot for htpasswd.
Enable htpasswd authentication and configure the path to the htpasswd authentication in the zot configuration file.
With an access scheme that relies solely on authentication, any authenticated user would be given complete access to the registry. To better control access, zot supports identity-based repository-level access control (authorization) policies. The access control policy is a function of repository, user, and the action being performed on that repository.
"},{"location":"articles/authn-authz/#access-control-policies","title":"Access control policies","text":"
Five identity-based types of access control policies are supported:
Policy type Attribute Access allowed Default defaultPolicy The default policy specifies what actions are allowed if a user is authenticated but does match any user-specific policy. User-specific users, actions A user-specific policy specifies access and actions for explicitly named users. Group-specific groups, actions A group-specific policy specifies access and actions for explicitly named groups. Anonymous anonymousPolicy An anonymous policy specifies what an unauthenticated user is allowed to do. This is an appropriate policy when you want to grant open read-only access to one or more repositories. Admin adminPolicy The admin policy is a global access control policy that grants privileges to perform actions on any repository.
Access control is organized by repositories, users, and their actions. Most users of a particular repository will have similar access control requirements and can be served by a repository-specific defaultPolicy. Should a user require an exception to the default policy, a user-specific or group-specific override policy can be configured.
With an anonymousPolicy, a repository can allow anonymous actions which do not require user authentication. Finally, one or more users can be designated as administrators, to whom the global adminPolicy applies.
A user's access to a particular repository is evaluated first by whether a user-specific policy exists, then by group-specific policies, and then (in order) by default and admin policies.
A group-specific policy can be applied within any type of access policy, including default or admin policies. The group policy name can also be used with LDAP.
User identity or group identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific paths.
When you define policies for specific repository paths, the paths can be specified explicitly or by using glob patterns with simple or recursive wildcards. When a repository path matches more than one path description, authorization is granted based on the policy of the longest (most specific) path matched. For example, if policies are defined for path descriptions ** and repos2/repo, the repos2/repo path will match both ** and repos2/repo descriptions. In this case, the repos2/repo policy will be applied because it is longer.
Note that ** effectively defines the default policy, as it matches any path not matched by any other per-repository policy. To override all other policies, you can specify a global admin policy.
Always include the read action in any policy that you define. The create, update, and delete actions cannot be used without the read action.
"},{"location":"articles/authn-authz/#example-access-control-configuration","title":"Example: Access control configuration","text":"
Use the accessControl attribute in the configuration file to define a set of identity-based authorization policies, as shown in the following example.
The default policy (**) gives all authenticated users the ability to read or create content, while giving user \"charlie\" and those in \"group2\" the additional ability to update content.
The policy for tmp/** matches all repositories under tmp recursively and allows all authenticated users to read, create, or update content in those repositories. Unauthenticated users have read-only access to these repositories.
The policy for infra/* matches all repositories directly under infra. Separate policies are defined for specific users, along with a default read-only policy for all other users.
The policy for repos2/repo matches only that specific repository.
An admin policy (adminPolicy) gives the user \"admin\" global authorization to read, create, update, or delete content in any repository, overriding all other policies.
In releases prior to zot v2.0.0, authorization policies were defined directly under the accessControl key in the zot configuration file. Beginning with v2.0.0, the set of authorization policies are now defined under a new repositories key.
"},{"location":"articles/authn-authz/#social-login-using-openidoauth2","title":"Social login using OpenID/OAuth2","text":"
Social login is an authentication/authorization method in which your existing credentials for another site or service can be used to log in to a service such as zot. For example, you can log in to zot using your GitHub account credentials, and zot will contact GitHub to verify your identity using OAuth 2.0 and OpenID Connect (OIDC) protocols.
Several social login providers are supported by zot:
github
google
gitlab
oidc (for example, dex)
The following example shows the zot configuration for these providers:
"},{"location":"articles/authn-authz/#using-google-github-or-gitlab","title":"Using Google, GitHub, or GitLab","text":"
A client logging into zot by social login must specify a supported OpenID/OAuth2 provider as a URL query parameter. A client logging in using Google, GitHub, or GitLab must additionally specify a callback URL for redirection to a zot page after a successful authentication.
The login URL using Google, GitHub, or GitLab uses the following format:
dex is an identity service that uses OpenID Connect (OIDC) to drive authentication for client apps, such as zot. While this section shows how to use dex with zot, zot supports other OIDC services as well.
Like zot, dex uses a configuration file for setup. To specify zot as a client in dex, configure a staticClients entry in the dex configuration file with a zot callback, such as the following example in the dex configuration file:
For detailed information about configuring dex service, see the dex Getting Started documentation.
"},{"location":"articles/authn-authz/#using-openidoauth2-when-zot-is-behind-a-proxy-or-load-balancer","title":"Using OpenID/OAuth2 when zot is behind a proxy or load balancer","text":"
When the zot registry is running behind a proxy or load balancer, you must provide an external URL for OpenID/OAuth2 clients to redirect back to zot. This externalUrl attribute is the URL of the registry, as shown in this example:
"},{"location":"articles/benchmarking-with-zb/","title":"Benchmarking zot with zb","text":"
The zb tool is useful for benchmarking OCI registry workloads in scenarios such as the following:
comparing configuration changes
comparing software versions
comparing hardware/deployment environments
comparing with other registries
With the zb tool, you can benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification published by the Open Container Initiative (OCI).
We recommend installing and benchmarking with zb when you install zot.
"},{"location":"articles/benchmarking-with-zb/#how-to-get-zb","title":"How to get zb","text":"
The zb project is hosted with zot on GitHub at project-zot. From GitHub, you can download the zb binary or you can build zb from the source. You can also directly run the released docker image.
"},{"location":"articles/benchmarking-with-zb/#supported-platforms-and-architectures","title":"Supported platforms and architectures","text":"
zb is supported for the following operating systems and platform architectures:
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS"},{"location":"articles/benchmarking-with-zb/#downloading-zb-binaries","title":"Downloading zb binaries","text":"
Download the executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.
The binary image is named using the target platform and architecture from the Supported platforms and architectures table. For example, the binary for an Intel-based MacOS server is zb-darwin-amd64.
"},{"location":"articles/benchmarking-with-zb/#building-zb-from-source","title":"Building zb from source","text":"
To build the zb binary, copy or clone the zot project from GitHub and execute the make bench command in the zot directory. Use the same command options that you used to build zot, as shown:
make OS=os ARCH=architecture bench
For example, the following command builds zb for an Intel-based MacOS server:
make OS=darwin ARCH=amd64 bench
In this example, the resulting executable file is zb-darwin-amd64 in the zot/bin directory.
A sample Dockerfile for zb is available at Dockerfile-zb.
The original filename of the executable file will reflect the build options, such as zb-linux-amd64. For convenience, you can rename the executable to simply zb.
The instructions and examples in this guide use zb as the name of the executable file.
To view the usage and options of zb, run the command with the --help option:
bin/zb --help
Command output:
Usage:\n zb <url> [flags]\n\n Flags:\n -A, --auth-creds string \u00a0 \u00a0 \u00a0Use colon-separated BASIC auth creds\n -c, --concurrency int \u00a0 \u00a0 \u00a0 \u00a0Number of multiple requests to make at a time (default 1)\n \u00a0 -h, --help \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 help for zb\n \u00a0 -o, --output-format string \u00a0 Output format of test results: stdout (default), json, ci-cd\n \u00a0 -r, --repo string \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Use specified repo on remote registry for test data\n \u00a0 -n, --requests int \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Number of requests to perform (default 1)\n \u00a0 -s, --src-cidr string \u00a0 \u00a0 \u00a0 \u00a0Use specified cidr to obtain ips to make requests from, src-ips and src-cidr are mutually exclusive\n \u00a0 -i, --src-ips string \u00a0 \u00a0 \u00a0 \u00a0 Use colon-separated ips to make requests from, src-ips and src-cidr are mutually exclusive\n \u00a0 -v, --version \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Show the version and exit\n \u00a0 -d, --working-dir string \u00a0 \u00a0 Use specified directory to store test data\n
Registry URL: http://localhost:8080\n\n Concurrency Level: 2\n Total requests: 100\n Working dir:\n\n ========\n Test name: Get Catalog\n Time taken for tests: 45.397205ms\n Complete requests: 100\n Failed requests: 0\n Requests per second: 2202.7788\n\n 2xx responses: 100\n\n min: 402.259\u00b5s\n max: 3.295887ms\n p50: 855.045\u00b5s\n p75: 971.709\u00b5s\n p90: 1.127389ms\n p99: 3.295887ms\n\n ========\n Test name: Push Monolith 1MB\n Time taken for tests: 952.336383ms\n Complete requests: 100\n Failed requests: 0\n Requests per second: 105.00491\n\n 2xx responses: 100\n\n min: 11.125673ms\n max: 26.375356ms\n p50: 18.917253ms\n p75: 21.753441ms\n p90: 24.02137ms\n p99: 26.375356ms\n\n ...\n
"},{"location":"articles/building-ci-cd-pipeline/","title":"Building an OCI-native Container Image CI/CD Pipeline","text":"
An OCI-native secure container image build/delivery pipeline using the following tools:
stacker for building OCI images
zot as a vendor-neutral OCI image registry server
skopeo for performing repository interactions
cosign for container signing and verification
cri-o for deploying container images
cosigned for validating container images before deployment
The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.
This document describes a step-by-step procedure towards achieving an OCI-native secure software supply chain using zot in collaboration with other open source tools. The following diagram shows a portion of the CI/CD pipeline.
stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout.
zot is a production-ready vendor-neutral OCI image registry server purely based on the OCI Distribution Specification. If stacker is used to build the OCI image, it can also be used to publish the built image to an OCI registry.
cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes.
zot is compatible with kubernetes/cri-o using docker:// transport, which is the default.
High availability of the zot registry is supported by the following features:
Stateless zot instances to simplify scale out
Shared remote storage
Bare-metal and Kubernetes deployments
To ensure high availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a load balancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Load balancing across many zot replicas can also increase aggregate network throughput.
Beginning with zot release v2.1.0, you can design a highly scalable cluster that does not require configuring the load balancer to direct repository queries to specific zot instances within the cluster. See Scale-out clustering. Scale-out clustering is the preferred method if you are running v2.1.0 or later.
Clustering is supported in both bare-metal and Kubernetes environments.
The remote backend storage must be S3 API-compatible.
In a stateless clustering scheme, the image data is stored in the remote storage backend and the registry cache is disabled by turning off deduplication.
The OCI Distribution Specification imposes certain rules about the HTTP URI paths to which various ecosystem tools must conform. Consider these rules when setting the HTTP prefixes during load balancing and ingress gateway configuration.
Clustering is supported by using multiple stateless zot replicas with shared S3 storage and an HAProxy (with sticky session) load balancing traffic to the replicas. Each replica is responsible for one or more repositories.
"},{"location":"articles/clustering/#haproxy-configuration","title":"HAProxy configuration","text":"Click here to view a sample HAProxy configuration.
"},{"location":"articles/clustering/#zot-s3-configuration","title":"zot S3 configuration","text":"Click here to view a sample zot configuration for S3.
"},{"location":"articles/graphql/","title":"Using GraphQL for Enhanced Searches","text":"
A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. You can submit a GraphQL structured query as an API call or you can use a browser to access the GraphQL Playground, an interactive graphical environment for GraphQL queries.
"},{"location":"articles/graphql/#how-to-use-graphql-for-search-queries","title":"How to use GraphQL for search queries","text":"
GraphQL is a query language for APIs. A GraphQL server, as implemented in zot's registry search engine, executes GraphQL queries that match schema recognized by the server. In response, the server returns a structure containing the requested information. The schema currently recognized by zot are those that correspond to the queries listed in What GraphQL queries are supported.
To learn more about GraphQL, see these resources:
Introduction to GraphQL
The Fullstack Tutorial for GraphQL
To perform a search, compose a GraphQL structured query for a specific search and deliver it to zot using one of the methods described in the following sections.
For examples of GraphQL queries supported in zot, see Examples of zot searches using GraphQL.
"},{"location":"articles/graphql/#using-the-search-api-directly","title":"Using the search API directly","text":"
You can submit a GraphQL structured query as the HTML data payload in a direct API call using a shell tool such as cURL or Postman. GraphQL queries are sent to the zot search extension API:
/v2/_zot/ext/search\n
The following example submits a zot GraphQL query using cURL:
In the GraphQL Playground, you can construct and submit a query structure and you can view the query response in a graphical environment in the browser. You can also inspect the schema.
"},{"location":"articles/graphql/#what-graphql-queries-are-supported","title":"What GraphQL queries are supported","text":"Supported queries graphQL query Input Output Description Search images by digest ImageListForDigest digest image list Searches all repositories in the registry and returns list of images that matches given digest (manifest, config or layers) Search images affected by a given CVE id CVEListForImage CVE id image list Searches the entire registry and returns list of images affected by given CVE List CVEs for a given image CVEListForImage image CVE list Scans given image and returns list of CVEs affecting the image List images not affected by a given CVE id ImagesListWithCVEFixed repository, CVE id image list Scans all images in a given repository and returns list of latest (by date) images not affected by the given CVE Latest image from all repos RepoListWithNewestImage none repo summary list Returns the latest image from all the repos in the registry List all images with expanded information for a given repository ExpandedRepoInfo repository repo info List expanded repo information for all images in repo, alongside a repo summary All images in repo ImageList repository image list Returns all images in the specified repo Global search GlobalSearch query image summary / repo summary / layer summary Will return what's requested in the query argument Derived image list DerivedImageList image image list Returns a list of images that depend on the image specified in the argument Base image list BaseImageList image image list Returns a list of images that the specified image depends on Get details of a specific image Image image image summary Returns details about a specific image Get referrers of a specific image Referrers repo, digest, type artifact manifests Returns a list of artifacts of given type referring to a specific repo and digests"},{"location":"articles/graphql/#examples-of-zot-searches-using-graphql","title":"Examples of zot searches using GraphQL","text":"
These examples show only the GraphQL query without details on how to send them to a server. See How to use GraphQL for search queries.
The query structures shown in these examples request all fields allowed by the schema for the particular query type. The schema allows you to request a subset of the data, if desired, omitting any fields that you don't need.
"},{"location":"articles/graphql/#list-cves-of-given-image","title":"List CVEs of given image","text":"
{\n \"data\": {\n \"CVEListForImage\": {\n \"Tag\": \"3.17\",\n \"Page\": {\n \"TotalCount\": 9,\n \"ItemCount\": 1\n },\n \"CVEList\": [\n {\n \"Id\": \"CVE-2023-5363\",\n \"Title\": \"openssl: Incorrect cipher key and IV length processing\",\n \"Description\": \"Issue summary: A bug has been identified in the processing of key and\\ninitialisation vector (IV) lengths. This can lead to potential truncation\\nor overruns during the initialisation of some symmetric ciphers.\\n\\nImpact summary: A truncation in the IV can result in non-uniqueness,\\nwhich could result in loss of confidentiality for some cipher modes.\\n\\nWhen calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or\\nEVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after\\nthe key and IV have been established. Any alterations to the key length,\\nvia the \\\"keylen\\\" parameter or the IV length, via the \\\"ivlen\\\" parameter,\\nwithin the OSSL_PARAM array will not take effect as intended, potentially\\ncausing truncation or overreading of these values. The following ciphers\\nand cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.\\n\\nFor the CCM, GCM and OCB cipher modes, truncation of the IV can result in\\nloss of confidentiality. For example, when following NIST's SP 800-38D\\nsection 8.2.1 guidance for constructing a deterministic IV for AES in\\nGCM mode, truncation of the counter portion could lead to IV reuse.\\n\\nBoth truncations and overruns of the key and overruns of the IV will\\nproduce incorrect results and could, in some cases, trigger a memory\\nexception. However, these issues are not currently assessed as security\\ncritical.\\n\\nChanging the key and/or IV lengths is not considered to be a common operation\\nand the vulnerable API was recently introduced. Furthermore it is likely that\\napplication developers will have spotted this problem during testing since\\ndecryption would fail unless both peers in the communication were similarly\\nvulnerable. For these reasons we expect the probability of an application being\\nvulnerable to this to be quite low. However if an application is vulnerable then\\nthis issue is considered very serious. For these reasons we have assessed this\\nissue as Moderate severity overall.\\n\\nThe OpenSSL SSL/TLS implementation is not affected by this issue.\\n\\nThe OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because\\nthe issue lies outside of the FIPS provider boundary.\\n\\nOpenSSL 3.1 and 3.0 are vulnerable to this issue.\",\n \"Severity\": \"HIGH\",\n \"PackageList\": [\n {\n \"Name\": \"libcrypto3\",\n \"InstalledVersion\": \"3.0.8-r0\",\n \"FixedVersion\": \"3.0.12-r0\"\n },\n {\n \"Name\": \"libssl3\",\n \"InstalledVersion\": \"3.0.8-r0\",\n \"FixedVersion\": \"3.0.12-r0\"\n }\n ]\n }\n ]\n }\n }\n}\n
"},{"location":"articles/graphql/#search-images-affected-by-a-given-cve-id","title":"Search images affected by a given CVE id","text":"
"},{"location":"articles/graphql/#list-all-images-with-expanded-information-for-a-given-repository","title":"List all images with expanded information for a given repository","text":"
{\n \"data\": {\n \"Image\": {\n \"RepoName\": \"mariadb\",\n \"Tag\": \"latest\",\n \"LastUpdated\": \"2022-10-18T14:56:33.1993083+03:00\",\n \"Digest\": \"sha256:49a299f5c4b1af5bc2aa6cf8e50ab5bad85db4d0095745369acfc1934ece99d0\",\n \"Description\": \"MariaDB Server is a high performing open source relational database, forked from MySQL.\"\n }\n }\n}\n
"},{"location":"articles/graphql/#get-referrers-of-a-specific-image","title":"Get referrers of a specific image","text":"
"},{"location":"articles/high-availability/","title":"Deploying a Highly Available zot Registry","text":"
A highly available zot registry can be easily implemented using zot's registry synchronization feature.
In the zot configuration, the sync extension allows a zot instance to mirror another zot instance with various container image download policies, including on-demand and periodic downloads. You can use the zot sync function combined with a load balancer such as HAProxy to implement a highly available registry.
Two failover configurations are possible:
Active/standby
Registry requests are sent by the load balancer to the active zot instance, while a standby instance mirrors the active. If the load balancer detects a failure of the active instance, it then sends requests to the standby instance.
Active/active
Registry requests are load-balanced between two zot instances, each of which mirrors the other.
The highly available zot registry described in this article differs from zot clustering. Although zot clustering provides a level of high availability, the instances share common storage, whose failure would affect all instances. In the method described in this article, each instance has its own storage, providing an additional level of safety.
For details of configuring the sync extension, see OCI Registry Mirroring With zot.
"},{"location":"articles/high-availability/#configuring-an-activestandby-registry","title":"Configuring an active/standby registry","text":"
An active/standby zot registry can be implemented between two zot instances by configuring the sync extension in the standby instance to mirror the other instance. In this scheme:
a load balancer such as HAProxy is deployed for active/passive load balancing of the zot instances
each zot instance is configured as a standalone registry with its own storage
the standby zot instance has its sync extension enabled to periodically synchronize with (mirror) the active instance
With periodic synchronization, a window of failure exists between synchronization actions. For example, if an image is posted to the active instance soon after the standby has synchronized with the active, and then the active fails, the standby will not have the new image. To minimize this exposure, we recommend keeping the synchronization period as small as practical.
"},{"location":"articles/high-availability/#configuring-an-activeactive-registry","title":"Configuring an active/active registry","text":"
An active/active zot registry can be implemented between two zot instances by configuring the sync extension in each instance to point to the other instance. In this scheme:
a load balancer such as HAProxy or a DNS-based routing scheme is deployed for load balancing between zot instances
path-based routing must be implemented
each zot instance is configured as a standalone registry with its own storage
each zot instance has its sync extension enabled to periodically synchronize with the other instance
With periodic synchronization, a window of failure exists between synchronization actions. For example, if an image is posted to instance A soon after instance B has synchronized with instance A, and then instance A fails, instance B will not have the new image. To minimize this exposure, we recommend keeping the synchronization period as small as practical.
Immutable image tag support is achieved by leveraging authorization policies.
It is considered best practice to avoid changing the content once a software version has been released. While zot does not have an explicit configuration flag to make image tags immutable, the same effect can be achieved with authorization as follows.
"},{"location":"articles/immutable-tags/#immutable-for-all-users","title":"Immutable For All Users","text":"
By setting the defaultPolicy to \"read\" and \"create\" for a particular repository, images can be pushed (once) and pulled but further updates are rejected.
"},{"location":"articles/immutable-tags/#immutable-with-overrides","title":"Immutable With Overrides","text":"
As in the example above, with defaultPolicy set to \"read\" and \"create\" for a particular repository, images can be pushed (once) and pulled, but further updates are rejected. Exceptions can be made for some users, and user-specific policies can be added to allow \"update\" operations as shown below.
"},{"location":"articles/kind-deploy/","title":"Using kind for Deployment Testing","text":"
Use kind to try out zot deployment with Kubernetes.
This article describes how to create a kind cluster that includes a local zot registry.
"},{"location":"articles/kind-deploy/#deploying-the-cluster-and-registry","title":"Deploying the cluster and registry","text":"
The procedure described installs a kind cluster with a zot registry at localhost:5001 and then loads and runs a \"hello\" app to test the installation. Although the procedure is given as a series of steps, you can find a complete shell script to perform these steps at the end of this article.
This article is based on Create A Cluster And Registry, which you can find on the kind website.
"},{"location":"articles/kind-deploy/#step-1-prepare-the-environment","title":"Step 1: Prepare the environment","text":"
The following packages must be installed:
docker
kubernetes
kind
containerd
skopeo
Execute the following shell commands to set environment variables.
set -o errexit\n\n# set no_proxy if applicable\nif [ ! -z \"${no_proxy}\" ]; then \n echo \"Updating no_proxy environment variables\";\n export no_proxy=${no_proxy},kind-registry;\n export NO_PROXY=${no_proxy};\nfi\n
"},{"location":"articles/kind-deploy/#step-2-create-a-registry-container","title":"Step 2: Create a registry container","text":"
Create a kind-registry container, pulling a zot binary from the GitHub Container Registry (ghcr.io).
This example pulls zot-minimal-linux-amd64:latest, a minimal (no extensions) zot image for an AMD-based linux server.
Other available images are described at the zot releases page in GitHub. You can also specify a release by replacing latest with an available release number.
"},{"location":"articles/kind-deploy/#step-3-create-the-kind-cluster","title":"Step 3: Create the kind cluster","text":"
Create a cluster with the local registry enabled.
# enable the local registry in containerd\ncat <<EOF | kind create cluster --config=-\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n- |-\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"localhost:${reg_port}\"]\n endpoint = [\"http://${reg_name}:5000\"]\nEOF\n
"},{"location":"articles/kind-deploy/#step-4-connect-the-registry-to-the-cluster-network","title":"Step 4: Connect the registry to the cluster network","text":"
Connect the registry to the \"kind\" network so that it can communicate with other resources in the same network.
"},{"location":"articles/kind-deploy/#step-5-document-the-local-registry","title":"Step 5: Document the local registry","text":"
Create a ConfigMap that specifies how to interact with the local registry. This ConfigMap follows the KEP-1755 Standard for communicating a local registry.
"},{"location":"articles/kind-deploy/#step-6-deploy-and-test","title":"Step 6: Deploy and test","text":"
Use skopeo to copy (pull) a \"hello\" app from the Google Container Registry (gcr.io) into the new zot registry. Using kubectl, deploy the app from the new local zot registry as \"hello-server\" and monitor the deployment for initial availability.
# copy an image\nskopeo copy --format=oci --dest-tls-verify=false \\\ndocker://gcr.io/google-samples/hello-app:1.0 \\\ndocker://localhost:5001/hello-app:1.0\n\n# deploy the image\nkubectl create deployment hello-server --image=localhost:5001/hello-app:1.0\n\n# check for availability\necho \"Waiting for deployment/hello-server to be ready ...\"\nkubectl wait deployment -n default hello-server \\\n --for condition=Available=True --timeout=90s\n
"},{"location":"articles/kind-deploy/#reference-a-complete-script","title":"Reference: A complete script","text":"
The following script executes all of the preceding steps.
Click here to view the entire script
#!/bin/sh\nset -o errexit\n\n# Reference: https://kind.sigs.k8s.io/docs/user/local-registry/\n\n# set no_proxy if applicable\nif [ ! -z \"${no_proxy}\" ]; then \n echo \"Updating no_proxy env var\";\n export no_proxy=${no_proxy},kind-registry;\n export NO_PROXY=${no_proxy};\nfi\n\n# create registry container unless it already exists\nreg_name='kind-registry'\nreg_port='5001'\nif [ \"$(docker inspect -f '{{.State.Running}}' \"${reg_name}\" 2>/dev/null || true)\" != 'true' ]; then\n docker run \\\n -d --restart=always -p \"127.0.0.1:${reg_port}:5000\" --name \"${reg_name}\" \\\n ghcr.io/project-zot/zot-minimal-linux-amd64:latest\nfi\n\n# create a cluster with the local registry enabled in containerd\ncat <<EOF | kind create cluster --config=-\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n- |-\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"localhost:${reg_port}\"]\n endpoint = [\"http://${reg_name}:5000\"]\nEOF\n\n# connect the registry to the cluster network if not already connected\nif [ \"$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' \"${reg_name}\")\" = 'null' ]; then\n docker network connect \"kind\" \"${reg_name}\"\nfi\n\n# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry\n#\n# document the local registry\ncat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: local-registry-hosting\n namespace: kube-public\ndata:\n localRegistryHosting.v1: |\n host: \"localhost:${reg_port}\"\n help: \"https://kind.sigs.k8s.io/docs/user/local-registry/\"\nEOF\n\n# copy an image\nskopeo copy --format=oci --dest-tls-verify=false docker://gcr.io/google-samples/hello-app:1.0 docker://localhost:5001/hello-app:1.0\n\n# deploy the image\nkubectl create deployment hello-server --image=localhost:5001/hello-app:1.0\n\n# check for availability\necho \"Waiting for deployment/hello-server to be ready ...\"\nkubectl wait deployment -n default hello-server --for condition=Available=True --timeout=90s\n\n# cleanup\necho \"Press a key to begin cleanup ...\"\nread KEYPRESS\nkind delete cluster\ndocker stop kind-registry\ndocker rm kind-registry\n
"},{"location":"articles/mirroring/","title":"OCI Registry Mirroring With zot","text":"
A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry (gcr.io).
A key use case for zot is to act as a mirror for upstream registries. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Because synchronized images are stored in zot's local storage, registry mirroring allows for a fully distributed disconnected container image build pipeline. Container image operations terminate in local zot storage, which may reduce network latency and costs.
Because zot is a OCI-only registry, any upstream image stored in the Docker image format is converted to OCI format when downloading to zot. In the conversion, some non-OCI attributes may be lost. Signatures, for example, are removed due to the incompatibility between formats.
For mirroring an upstream registry, two common use cases are a fully mirrored or a pull through (on-demand) cache registry.
As with git, wherein every clone is a full repository, you can configure your local zot instance to be a fully mirrored OCI registry. For this mode, configure zot for synchronization by periodic polling, not on-demand. Zot copies and caches a full copy of every image on the upstream registry, updating the cache whenever polling discovers a change in content or image version at the upstream registry.
For a pull through cache mirrored registry, configure zot for on-demand synchronization. When an image is first requested from the local zot registry, the image is downloaded from the upstream registry and cached in local storage. Subsequent requests for the same image are served from zot's cache. Images that have not been requested are not downloaded. If a polling interval is also configured, zot periodically polls the upstream registry for changes, updating any cached images if changes are detected.
Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only on-demand mirroring with Docker Hub.
"},{"location":"articles/mirroring/#migrating-or-updating-a-registry-using-mirroring","title":"Migrating or updating a registry using mirroring","text":"
Mirroring zot using the sync feature allows you to easily migrate a registry. In situations such as the following, zot mirroring provides an easy solution.
Migrating an existing zot or non-zot registry to a new location.
Provided that the source registry is OCI-compliant for image pulls, you can mirror the registry to a new zot registry, delete the old registry, and reroute network traffic to the new registry.
Updating (or downgrading) a zot registry.
To minimize downtime during an update, or to avoid any incompatibilities between zot releases that would preclude an in-place update, you can bring up a new zot registry with the desired release and then migrate from the existing registry.
To ensure a complete migration of the registry contents, set a polling interval in the configuration of the new zot registry and set prefix to **, as shown in this example:
"},{"location":"articles/mirroring/#basic-configuration-for-mirroring-with-sync","title":"Basic configuration for mirroring with sync","text":"
The sync feature of zot is an extension of the OCI-compliant registry implementation. You can configure the sync feature under the extensions section of the zot configuration file, as shown in this example:
A list of one or more URLs to an upstream image registry. If the main URL fails, the sync process will try the next URLs in the listed order.
onDemand
false: Pull all images not found in the local registry.
true: Pull any image not found in the local registry only when the image is requested by a user.
pollInterval
The period in seconds between polling of a remote registry. If no value is specified, no periodic polling will occur. If a value is set and the content attributes are configured, periodic synchronization is enabled and will run at the specified value.Note: Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only onDemand mirroring with Docker Hub.
tlsVerify
false: TLS will not be verified.
true: (Default) The TLS connection to the destination registry will be verified.
certDir
If a path is specified, use certificates (*.crt, *.cert, *.key files) at this path when connecting to the destination registry or daemon. If no path is specified, use the default certificates directory.
maxRetries
The maximum number of retries if an error occurs during either an on-demand or periodic synchronization. If no value is specified, no retries will occur.
retryDelay
The interval in seconds between retries. This attribute is mandatory when maxRetries is configured.
onlySigned
false: Synchronize signed or unsigned images.
true: Synchronize only signed images (either notary or cosign).
content
The included attributes in this section specify which content will be pulled. If this section is not populated, periodic polling will not occur. The included attributes can also filter which on-demand images are pulled.
prefix
On the remote registry, the path from which images will be pulled. This path can be a string that exactly matches the remote path, or it can be a glob pattern. For example, the path can include a wildcard (*) or a recursive wildcard (**).
tags
The included attributes in this optional section specify how remote images will be selected for synchronization based on image tags.
tags.regex
Specifies a regular expression for matching image tags. Images whose tags do not match the expression are not pulled.
tags.semver
Specifies whether image tags are to be filtered by semantic versioning (semver) compliance.
false: Do not filter by semantic versioning.
true: Filter by semantic versioning.
destination
Specifies the local path in which pulled images are to be stored.
stripPrefix
Specifies whether the prefix path from the remote registry will be retained or replaced when the image is stored in the zot registry.
false: Retain the source prefix, append it to the destination path.
true: Remove the source prefix.
Note: If the source prefix was specified with meta-characters (such as **), only the prefix segments that precede the meta-characters are removed. Any remaining path segments are appended to the destination path.
"},{"location":"articles/mirroring/#configuration-examples-for-mirroring","title":"Configuration examples for mirroring","text":""},{"location":"articles/mirroring/#example-multiple-repositories-with-polled-mirroring","title":"Example: Multiple repositories with polled mirroring","text":"
The following is an example of sync configuration for mirroring multiple repositories with polled mirroring.
The configuration in this example will result in the following behavior:
Only signed images (notation and cosign) are synchronized.
The sync communication is secured using certificates in certDir.
This registry synchronizes with upstream registry every 6 hours.
On-demand mirroring is disabled.
Based on the content filtering options, this registry synchronizes these images:
From /repo1/repo, images with tags that begin with \"4.\" and are semver compliant. Files are stored locally in /repo1/repo on localhost.
From /repo2/repo, images with all tags. Because stripPrefix is enabled, files are stored locally in /repo2. For example, docker://upstream/repo2/repo:v1 is stored as docker://local/repo2:v1.
From /repo3/repo, images with all tags. Files are stored locally in /repo3/repo.
"},{"location":"articles/mirroring/#example-multiple-registries-with-on-demand-mirroring","title":"Example: Multiple registries with on-demand mirroring","text":"
The following is an example of sync configuration for mirroring multiple registries with on-demand mirroring.
With this zot configuration, the sync behavior is as follows:
This initial user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/docker-images/alpine <dest>causes zot to synchronize the content with the docker.io registry: docker.io/library/alpine:latestto the zot registry: localhost:8080/docker-images/alpine:latestbefore delivering the content to the requestor at <dest>.
This initial user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/k8s-images/kube-proxy:v1.19.2 <dest>causes zot to synchronize the content with the gcr.io registry: k8s.gcr.io/kube-proxy:v1.19.2 to the zot registry: localhost:8080/k8s-images/kube-proxy:v1.19.2before delivering the content to the requestor at <dest>.
You can use this command: curl http://localhost:8080/v2/_catalogto display the local repositories:
With this zot configuration, the sync behavior is as follows:
This user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/kube-proxy/kube-proxy:v1.19.2 <dest>causes zot to synchronize the content with this remote registry: k8s.gcr.io/kube-proxy:v1.19.2to the zot registry: localhost:8080/kube-proxy/kube-proxy:v1.19.2before delivering the content to the requestor at <dest>.
You can use this command: curl http://localhost:8080/v2/_catalogto display the local repositories:
In zot storage, the requested content is located here: /tmp/zot/kube-proxy/kube-proxy/kube-proxy/This subpath is created from the following path components:
/tmp/zot is the rootDirectory of the zot registry
kube-proxy is the rootDirectory of the storage subpath
kube-proxy is the sync destination parameter
kube-proxy is the repository name
"},{"location":"articles/monitoring/","title":"Monitoring the registry","text":"
zot supports a range of monitoring tools including logging, metrics, and benchmarking.
The following sections describe how to configure logging and monitoring with zot. You can use zot's benchmarking tool to test your configuration and deployment, as described in Benchmarking zot with zb.
The available methods for collecting metrics varies depending on whether your zot installation is a minimal (distribution-spec-only) image or a full image including extensions.
"},{"location":"articles/monitoring/#enabling-metrics-for-a-full-zot-image-with-extensions","title":"Enabling metrics for a full zot image with extensions","text":"
Add the metrics attribute under extensions in the configuration file to enable and configure metrics, as shown in the following example.
The following table lists the configurable attributes for metrics collection.
Attribute Description enable If this attribute is missing, metrics collection is enabled by default. Metrics collection can be disabled by setting this attribute to false. prometheus Attributes under prometheus contain configuration settings for the Prometheus node exporter. path The server path on which metrics will be exposed."},{"location":"articles/monitoring/#collecting-metrics-from-a-minimal-zot-image-using-a-node-exporter","title":"Collecting metrics from a minimal zot image using a node exporter","text":"
Although a minimal zot image does not contain a node exporter, it exposes internal metrics in a Prometheus format for collection by a separate node exporter tool such as zxp. The zot companion binary zxp is a node exporter that can be deployed with a minimal zot image in order to scrape metrics from the zot server.
Metrics are automatically enabled in the zot server upon first scrape from the node exporter and the metrics are automatically disabled when the node exporter has not performed any scraping for some period. No extra zot configuration is needed for this behavior.
You can download the zxp executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.
The binary image is named using the target platform and architecture. For example, the binary for an Intel-based MacOS server is zxp-darwin-amd64. To configure the zxp example image, run this command:
zxp-darwin-amd64 config zxp-config-file
For convenience, you can rename the binary image file to simply zxp.
A sample Dockerfile for zxp is available at Dockerfile-zxp.
The configuration file of zxp contains connection details for the zot server from which it will scrape metrics. The following JSON structure is an example of the zxp-config-file contents:
The zxp module does not have Prometheus integration.
The zxp module is not needed with a full zot image.
"},{"location":"articles/pprofiling/","title":"Performance Profiling in zot","text":"
Use zot's built-in profiling tools to collect and analyze runtime performance.
The profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.
If authentication is enabled, only a zot admin user can access the APIs for profiling.
All examples in this article assume that the zot registry is running at localhost:8080.
"},{"location":"articles/pprofiling/#what-data-is-available","title":"What data is available?","text":"
The zot source code incorporates golang's pprof package of runtime analysis tools to collect data for the following performance-related profiles:
Profile Description allocs A sampling of all past memory allocations. block Stack traces that led to blocking on synchronization primitives. cmdline The command line invocation of the current program. goroutine Stack traces of all current goroutines. Use debug=2 as a URL query parameter to export in the same format as an unrecovered panic. heap A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample. mutex Stack traces of holders of contended mutexes. profile CPU usage profile. You can specify the duration in the seconds URL query parameter. After receiving the profile file, use the go tool pprof command to investigate the profile. threadcreate Stack traces that led to the creation of new OS threads. trace A trace of execution of the current program. You can specify the duration in the seconds URL query parameter. After you get the trace file, use the go tool trace command to investigate the trace.
To return a current HTML-format profile list along with a count of currently available records for each profile, use the following API command:
/v2/_zot/pprof/\n
If authentication is enabled, only an admin user can access this API.
"},{"location":"articles/pprofiling/#how-do-i-export-profile-data","title":"How do I export profile data?","text":"
To collect and export any available profile, use the following API command format:
This command example creates an output data file named \"cpu.prof\".
The query parameter ?seconds=<number> specifies the number of seconds to gather the profile data. If this parameter is not specified, the default is 30 seconds.
In this example, the raw output data is redirected to a file named \"cpu.prof\". Alternatively, you can use curl -O to create a file with the default profile name (in this case, \"profile\"). If no output file is specified by either a cURL flag or an output redirection, the cURL command fails with \"Failure writing output to destination\".
The command output file is in a machine-readable format that can be interpreted by performance analyzers.
"},{"location":"articles/pprofiling/#analyzing-the-cpu-usage-profile-using-go-tool-pprof","title":"Analyzing the CPU usage profile using go tool pprof","text":"
Go's pprof package provides a variety of presentation formats for analyzing runtime performance.
For detailed information, see the pprof documentation.
"},{"location":"articles/pprofiling/#generating-a-pprof-web-presentation","title":"Generating a pprof web presentation","text":"
When an HTTP port is specified as a command flag, the go tool pprof command installs and opens a local web server that provides a web interface for viewing and analyzing the profile data. This example opens a localhost page at port 9090 for viewing the CPU usage data captured in the profile file named \"cpu.prof\".
$ go tool pprof -http=:9090 cpu.prof\nServing web UI on http://localhost:9090\n
The pprof web view offers several options for viewing and interpreting the collected performance data. Select VIEW to see the available options:
A Flame Graph can be very useful for analyzing CPU usage:
"},{"location":"articles/pprofiling/#generating-a-graphic-image","title":"Generating a graphic image","text":"
The pprof package can generate graphic representations of profile data in many formats. This example generates a PNG file representing the CPU usage in the \"cpu.prof\" file.
$ go tool pprof -png cpu.prof\nGenerating report in profile001.png\n
"},{"location":"articles/pprofiling/#opening-a-pprof-interactive-session","title":"Opening a pprof interactive session","text":"
This example opens an interactive session with pprof and executes the pprof top command, which displays the top ten modules by CPU usage during the profiling capture window.
"},{"location":"articles/pprofiling/#analyzing-the-trace-profile-using-go-tool-trace","title":"Analyzing the trace profile using go tool trace","text":"
You can collect trace data with the trace profile, as in this example:
Retention policies are configured in the storage section of the zot configuration file under the retention attribute. One or more policies can be grouped under the policies attribute.
By default, if no retention policies are defined, all tags are retained.
If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed. To avoid unintended removals, we recommend defining a default policy, as described in Configuration notes.
The following table lists the attributes available in the retention policy configuration.
Attribute Value Description dryRun boolean If true, will log a removal action without actually removing the image. Default is false. delay time Remove untagged and referrers only if they are older than the specified <time> hours, such as 24h. policies list A list of policies. repositories list A list of glob patterns to match repositories. deleteReferrers boolean If true, delete manifests with a missing Subject. Default is false. deleteUntagged boolean If true, delete untagged manifests. Default is true. keepTags list Criteria for tags to retain always. mostRecentlyPushedCount count Retains the top <count> most recently pushed tags. mostRecentlyPulledCount count Retains the top <count> most recently pulled tags. pushedWithin time Retains the tags pushed during the last <time> hours, such as 24h. pulledWithin time Retains the tags pulled during the last <time> hours, such as 24h. patterns regex See Notes."},{"location":"articles/retention/#configuration-notes","title":"Configuration notes","text":"
A repository will apply the first policy it matches.
If a repository matches no policy, the repository and all its tags are retained.
If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed.
If keepTags is present but empty, all tags are retained.
When multiple rules are configured, a tag is retained if it meets at least one rule.
When you specify a regex pattern combined with one or more rules, the rules are applied only to those tags matching the regex.
When you specify a regex pattern with no rules other than the default, all tags matching the pattern are retained.
In the repositories list, a single asterisk (/*) matches all first-level items in the repository. A double asterisk (/**) matches all recursively.
We recommend defining a default keepTags policy, such as the following example, as the last policy in the policy list. All tags that don't match the preceding policies will be retained by this default policy:
A cluster of zot instances can be easily scaled with no repo-specific intelligence in the load balancing scheme, using:
Stateless zot instances to simplify scale out
Shared remote storage
zot release v2.1.0 or later
Beginning with zot release v2.1.0, a new \"scale-out\" architecture greatly reduces the configuration required when deploying large numbers of zot instances. As before, multiple identical zot instances run simultaneously using the same shared reliable storage, but with improved scale and performance in large deployments. A highly scalable cluster can be architected by automatically sharding based on repository name so that each zot instance is responsible for a subset of repositories.
In a cloud deployment, the shared backend storage (such as AWS S3) and metadata storage (such as DynamoDB) can also be easily scaled along with the zot instances.
For high availability clustering with earlier zot releases, see zot Clustering.
For easy scaling of instances (replicas), the following conditions must be met:
All zot replicas must be running zot release v2.1.0 (or later) with identical configurations.
All zot replicas in the cluster use remote storage at a single shared S3 backend. There is no local caching in the zot replicas.
Each zot replica in the cluster has its own IP address, but all replicas use the same port number.
"},{"location":"articles/scaleout/#how-it-works","title":"How it works","text":"
Each repo is served by one zot replica, and that replica is solely responsible for serving all images of that repo. A repo in storage can be written to only by the zot replica responsible for that repo.
When a zot replica in the cluster receives an image push or pull request for a repo, the receiving replica hashes the repo path and consults a hash table to determine which replica is responsible for the repo.
If the hash indicates that another replica is responsible, the receiving replica forwards the request to the responsible replica and then acts as a proxy, returning the response to the requestor.
If the hash indicates that the current (receiving) replica is responsible, the request is handled locally.
For better resistance to collisions and preimage attacks, zot uses SipHash as the hashing algorithm.
Either of the following two schemes can be used to reach the cluster.
"},{"location":"articles/scaleout/#using-a-single-entry-point-load-balancer","title":"Using a single entry point load balancer","text":"
When a single entry point load balancer such as HAProxy is deployed, the number of zot replicas can easily be expanded by simply adding the IP addresses of the new replicas in the load balancer configuration.
When the load balancer receives an image push or pull request for a repo, it forwards the request to any replica in the cluster. No repo-specific programming of the load balancer is needed because the load balancer does not need to know which replica owns which repo. The replicas themselves can determine this.
Because the scale-out architecture greatly simplifies the role of the load balancer, it may be possible to eliminate the load balancer entirely. A scheme such as DNS-based routing can be implemented, exposing the zot replicas directly to the clients.
In these examples, clustering is supported by using multiple stateless zot replicas with shared S3 storage and an HAProxy (with sticky session) load balancer forwarding traffic to the replicas.
"},{"location":"articles/scaleout/#cluster-member-configuration","title":"Cluster member configuration","text":"
In the replica configuration, each replica must have a list of its peers configured in the \"members\" section of the JSON structure. This is a list of reachable addresses or hostnames. Each replica owns one of these addresses.
The replica must also have a hash key for hashing the repo path of the image request and a TLS certificate for authenticating with its peers.
Click here to view a sample cluster configuration for each replica. See the \"cluster\" section in the JSON structure.
The HAProxy load balancer uses a simple round-robin balancing scheme and delivers a cookie to the requestor to maintain a sticky session connection to the assigned replica.
Click here to view a sample HAProxy configuration.
"},{"location":"articles/scaleout/#when-a-replica-fails","title":"When a replica fails","text":"
The scale-out clustering scheme described in this article is not self-healing when a replica fails. In case of a replica failure, only those repositories that are mapped to the failed replica are affected. If the error is not transient, the cluster must be resized and restarted to exclude that replica.
With an HAProxy load balancer, we recommend implementing an HAProxy circuit breaker to monitor and protect the cluster.
"},{"location":"articles/scaleout/#cve-repository-in-a-zot-cluster-environment","title":"CVE repository in a zot cluster environment","text":"
CVE scanning is not supported for cloud deployments. In the scale-out clustering scheme described in this article, CVE scanning is disabled. In this case, we recommend implementing a CVE repository with a zot instance outside of the cluster using a local disk for storage and Trivy as the detection engine.
The sync feature of zot, either on demand or periodic, is compatible with scale-out clustering. In this case, the repo names are hashed to a particular replica and only that replica will perform the sync.
An overview of zot build-time and runtime security hardening features, including:
Build-time hardening such as PIE-mode builds
Minimal-build option for smaller attack surface
Open Source Security Foundation best practices for CI/CD
Non-root deployment
Robust authentication/authorization options
The zot project takes a defense-in-depth approach to security, applying industry-standard best practices at various stages. Recognizing that security hardening and product features are sometimes in conflict with each other, we also provide flexibility both at build and deployment time.
The zot binary is built with PIE build-mode enabled to take advantage of ASLR support in modern operating systems such as Linux ASLR. While zot is intended to be a long-running service (without frequent restarts), it prevents attackers from developing a generic attack that depends on predictable memory addresses across multiple zot deployments.
Functionality in zot is broadly organized as a core Distribution Specification implementation and additional features as extensions. The rationale behind this approach is to minimize or control library dependencies that get included in the binary and consequently the attack surface.
We currently build and release two image flavors:
minimal, which is a minimal Distribution Specification conformant registry, and
full, which incorporates the minimal build and all extensions
The minimal flavor is for the security-minded and minimizes the number of dependencies and libraries. The full flavor is for the functionality-minded with the caveat that the attack surface of the binary is potentially broader. However by no means are these the only options. Our build (via the Makefile) provides the flexibility to pick and choose extensions in order to build a binary between minimal and full. For example,
make EXTENSIONS=search binary
produces a zot binary with only the search feature enabled.
zot is an open source project and all code submissions are open and transparent. Every pull request (PR) submitted to the project repository must be reviewed by the code owners. We have additional CI/CD workflows monitoring for unreviewed commits.
All PRs must pass the full CI/CD pipeline checks including unit, functional, and integration tests, code quality and style checks, and performance regressions. In addition, all binaries produced are subjected to further security scans to detect any known vulnerabilities.
All interactions with zot are over HTTP APIs, and htpasswd-based local authentication, LDAP, mutual TLS, and token-based authentication mechanisms are supported. We strongly recommend enabling a suitable mechanism for your deployment use case in order to prevent unauthorized access. See the provided authentication examples.
Following authentication, it is further possible to allow or deny actions by a user on a particular repository stored on the zot registry. See the provided access control examples.
We understand that no software is perfect and in spite of our best efforts, security bugs may be found. Refer to our security policy for taking a responsible course of action when reporting security bugs.
"},{"location":"articles/storage/","title":"Storage Planning with zot","text":"
zot supports the following features to provide OCI standards-based, vendor-agnostic image storage:
Data handling in zot revolves around two main principles: that data and APIs on the wire conform to the OCI Distribution Specification and that data on the disk conforms to the OCI Image Layout Specification. As a result, any client that is compliant with the Distribution Specification can read from or write to a zot registry. Furthermore, the actual storage is simply an OCI Image Layout. With only these two specification documents in hand, the entire data flow inside can be easily understood.
zot does not implement, support, or require any vendor-specific protocols, including that of Docker.
"},{"location":"articles/storage/#hosting-an-oci-image-layout","title":"Hosting an OCI image layout","text":"
Because zot supports the OCI image layout, it can readily host and serve any directories holding a valid OCI image layout even when those directories have been created elsewhere. This property of zot is suitable for use cases in which container images are independently built, stored, and transferred, but later need to be served over the network.
Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.
Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.
Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.
Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.
After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. See Configuring garbage collection for details.
The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.
zot can store and serve files from one or more local directories. A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.
Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.
zot can also store data remotely in the cloud, using the storage APIs of the cloud service. Currently, zot supports only the AWS s3 storage service.
"},{"location":"articles/storage/#example-configuration-for-remote-s3-storage","title":"Example: configuration for remote (s3) storage","text":"Click here to view a sample zot configuration for remote storage.
The following table lists the attributes of the storage configuration.
Attribute Description
rootDirectory
Location of the images stored in the server file system.
commit
For faster performance, data written by zot is retained in memory before being periodically committed to disk by the operating system. To eliminate this retention time and cause data to be written to disk immediately, set to true. This prevents data loss but reduces performance.
dedupe
If the server filesystem supports hard links, you can optimize storage space by enabling inline deduplication of layers and blobs that are shared among multiple container images. Deduplication is enabled by default. Set to false to disable deduplication.
gc
When an image is deleted, either by tag or by reference, orphaned blobs can lead to wasted storage. Garbage collection (gc) is enabled by default to reclaim this space. Set to false to disable garbage collection.
gcDelay
(Optional) If garbage collection is enabled, causes it to run once after the specified delay time. The default is 1 hour. Requires the gc attribute to be true.
gcInterval
(Optional) If garbage collection is enabled, causes periodic collection at the specified interval. Must be set based on use cases and user workloads. If no value is specified, there is no periodic collection. Requires the gc attribute to be true.
subpaths
You can store and serve images from multiple filesystems, each with their own repository paths and settings. The following example shows three subpaths.
The zot configuration model allows for enabling and disabling garbage collection (gc) and specifying a periodic interval (gcInterval) for collection.
gcgcInterval Result false n/a GC disabled omitted n/a GC enabled with 1 hour interval (default) true omitted GC enabled with 1 hour interval true 0 GC runs only once true >0 GC enabled with specified interval
The configuration model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs. The gcDelay attribute causes collection to run once after the specified delay time. This attribute has a default value of one hour (1h).
"},{"location":"articles/storage/#configuring-remote-storage-with-s3","title":"Configuring remote storage with s3","text":"
To configure an Amazon Simple Storage Service (s3) bucket for zot, use the storageDriver attribute in the zot configuration file, as shown in the following example:
The following table lists the attributes of storageDriver when configuring s3 for remote storage:
Attribute Required Description name yes Name of storage driver. Only s3 is supported for now. accesskey no Your AWS Access Key. If you use IAM roles, omit to fetch temporary credentials from IAM. secretkey no Your AWS Secret Key. If you use IAM roles, omit to fetch temporary credentials from IAM. region yes The AWS region in which your bucket exists. regionendpoint no Endpoint for S3 compatible storage services (Minio, etc). forcepathstyle no To enable path-style addressing when the value is set to true. The default is true. bucket yes The bucket name in which you want to store the registry\u2019s data. encrypt no Specifies whether the registry stores the image in encrypted format or not. A boolean value. The default is false. keyid no Optional KMS key ID to use for encryption (encrypt must be true, or this parameter is ignored). The default is none. secure no Indicates whether to use HTTPS instead of HTTP. A boolean value. The default is true. skipverify no Skips TLS verification when the value is set to true. The default is false. v4auth no Indicates whether the registry uses Version 4 of AWS\u2019s authentication. The default is true. chunksize no The S3 API requires multipart upload chunks to be at least 5MB. This value should be a number that is larger than 5 * 1024 * 1024. multipartcopychunksize no Default chunk size for all but the last S3 Multipart Upload part when copying stored objects. multipartcopymaxconcurrency no Max number of concurrent S3 Multipart Upload operations when copying stored objects. multipartcopythresholdsize no Default object size above which S3 Multipart Upload will be used when copying stored objects. rootdirectory no This is a prefix that is applied to all S3 keys to allow you to segment data in your bucket if necessary. storageclass no The S3 storage class applied to each registry file. The default is STANDARD. useragent no The User-Agent header value for S3 API operations. usedualstack no Use AWS dual-stack API endpoints. accelerate no Enable S3 Transfer Acceleration. objectacl no The S3 Canned ACL for objects. The default value is \u201cprivate\u201d. loglevel no The log level for the S3 client. The default value is off.
For more information, see the s3 storage driver docs.
In the s3 configuration file example, the s3 credentials were configured with the attributes accesskey and secretkey. As an alternative, you can omit these attributes from the configuration file and you can configure them using environment variables or a credential file.
Environment variables
zot looks for credentials in the following environment variables:
The [default] heading defines credentials for the default profile, which zot will use unless you configure it to use another profile. You can specify a profile using the AWS_PROFILE environment variable as in this example:
AWS_PROFILE=test-account\n
The credential file must be named credentials. The file must be located in the .aws/ subdirectory in the home directory of the same server that is running your zot application.
For more details about specifying s3 credentials, see the AWS documentation.
A cache driver is used to store duplicate blobs when dedupe is enabled. zot supports database caching using BoltDB as the cache driver for local filesystems and DynamoDB for remote filesystems.
The AWS GO SDK loads additional configuration and credentials values from your environment variables, shared credentials, and shared configuration files.
If the search extension is enabled, additional parameters are required:
The subPaths feature ties together several separate storage filesystems and backends behind the same HTTP API interface. In the example above, both repository paths \"/a\" and \"/b\" are exposed to clients. Content on these two paths can be hosted completely separately by different storage services, locations, or filesystems, with no difference to the user interface and no perceptible difference to the user experience. This is useful if one wants to serve existing OCI images from different backends or if storage can be expanded only by using different backing stores.
zot also supports different storage drivers for each subpath.
Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user.
To verify image signatures, zot supports the following tools:
To enable image signature verification, add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:
The following table lists the configurable attributes of the trust extension.
Attribute Description enable If this attribute is missing, signature verification is disabled by default. Signature verification is enabled by including this attribute and setting it to true. You must also enable at least one of the verification tools. cosign Set to true to enable signature verification using the cosign tool. notation Set to true to enable signature verification using the notation tool."},{"location":"articles/verifying-signatures/#what-is-needed-for-verifying-signatures","title":"What is needed for verifying signatures","text":"
To verify the validity of a signature for an image, zot makes use of two types of files:
A public key file that pairs with the private key used to sign an image with cosign
A certificate file that is used to sign an image with notation
Upload these files using an extension of the zot API, as shown in the following examples:
To upload a public key for cosign:
API path
/v2/_zot/ext/cosign\"\n
Example request
curl --data-binary @file.pub -X POST \"http://localhost:8080/v2/_zot/ext/cosign\"\n
Result
The uploaded file is stored in the _cosign directory under the rootDir specified in the zot configuration file or in the Secrets Manager.
To upload a certificate for notation:
API path
/v2/_zot/ext/notation?truststoreType=ca\n
When uploading a certificate, you should specify the truststoreType. If the truststore is a certificate authority, the value is ca. This is the default if this attribute is omitted.
Example request
curl --data-binary @certificate.crt -X POST \"http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca\"\n
Result
The uploaded file is stored in the _notation/truststore/x509/{truststoreType}/default directory under the rootDir specified in the zot configuration file or in the Secrets Manager.
"},{"location":"articles/verifying-signatures/#where-needed-files-are-stored","title":"Where needed files are stored","text":"
Uploaded public keys and certificates are stored in the local filesystem, in specific directories named _cosign and _notation under $rootDir, or in the Secrets Manager.
The _cosign directory contains uploaded public key files in the following structure:
In this directory, the trustpolicy.json file contains content that is updated automatically whenever a new certificate is added to a new truststore. This content cannot be changed by the user. An example of the trustpolicy.json file content is shown below:
By default, the trustpolicy.json file sets the signatureVerification.level property to strict, which enforces all validations. For example, a signature is not trusted if its certificate has expired, even if the certificate verifies the signature.
The trustpolicy.json file contains two default truststores, ca:default and signingAuthority:default. This list of truststores is not updated when a new certificate is uploaded.
The content of the trustStores field will match the content of the _notation/truststore directory.
Based on the uploaded files and the information about images stored in zot's database, signature verification is performed for all signed images. The verification result for each signed image is stored in the database and is visible from GraphQL. The stored information about a signature includes:
The tool that was used to generate the signature, such as cosign or notation
The trustworthiness of the signature, such as whether a certificate or public key exists that can successfully verify the signature
The author of the signature, which can be either:
The public key, for signatures generated using cosign
The subject of the certificate, for signatures generated using notation
"},{"location":"articles/verifying-signatures/#example-of-graphql-output","title":"Example of GraphQL output","text":"
"},{"location":"articles/workflow/","title":"Software Provenance Workflow Using OCI Artifacts","text":"
This article demonstrates an end-to-end workflow for installing a zot registry, then pushing and signing an image and a related artifact, such as an SBOM.
The following sections describe the step-by-step workflow. To view the steps combined into a single script, see Reference: Full workflow script.
For the workflow examples, the zot registry is assumed to be installed and running at localhost:8080.
"},{"location":"articles/workflow/#step-1-download-the-client-tools","title":"Step 1: Download the client tools","text":"
This workflow uses the regctl registry client and the cosign image signing tool. As a first step, we download binaries for these tools in a tools directory.
"},{"location":"articles/workflow/#step-2-deploy-an-oci-registry-with-referrers-support-zot","title":"Step 2: Deploy an OCI registry with referrers support (zot)","text":"
Next, we execute the following tasks to deploy an OCI registry:
Copy a zot executable binary to the server.
Create a basic configuration file for the zot server, specifying the local root directory, the network location, and the port number.
Launch zot with the newly-created configuration file.
Looping with a periodic cURL query, detect when zot is up and running.
ZOT=${TOOLSDIR}/bin/zot\nZOT_VERSION=2.0.0-rc6\ncurl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal\nchmod +x ${ZOT}\n\nZOT_HOST=localhost\nZOT_PORT=8080\n\n# function to start zot and test for readiness\nfunction zot_setup() {\ncat > $TEST_TMPDIR/zot-config.json << EOF\n{\n \"distSpecVersion\": \"1.1.0-dev\",\n \"storage\": {\n \"rootDirectory\": \"$TEST_TMPDIR/zot\"\n },\n \"http\": {\n \"address\": \"$ZOT_HOST\",\n \"port\": \"$ZOT_PORT\"\n },\n \"log\": {\n \"level\": \"error\"\n }\n}\nEOF\n # start zot as a background task\n ${ZOT} serve $TEST_TMPDIR/zot-config.json &\n pid=$!\n # wait until service is up\n count=5\n up=0\n while [[ $count -gt 0 ]]; do\n if [ ! -d /proc/$pid ]; then\n echo \"zot failed to start or died\"\n exit 1\n fi\n up=1\n curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0\n if [ $up -eq 1 ]; then break; fi\n sleep 1\n count=$((count - 1))\n done\n if [ $up -eq 0 ]; then\n echo \"Timed out waiting for zot\"\n exit 1\n fi\n # setup an OCI client\n ${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT\n}\n\n# call the function to start zot\nzot_setup\n
"},{"location":"articles/workflow/#step-3-copy-an-image-to-the-oci-registry","title":"Step 3: Copy an image to the OCI registry","text":"
This step copies a busybox container image into the registry.
"},{"location":"articles/workflow/#step-4-copy-a-related-artifact-to-the-oci-registry","title":"Step 4: Copy a related artifact to the OCI registry","text":"
This step creates a simple artifact file and associates it with the busybox image in the registry.
The --subject command flag associates the artifact file with the specified subject (in this case, the busybox image). If no subject is specified by the command, the artifact is considered independent and not associated with any existing image.
"},{"location":"articles/workflow/#step-5-display-the-artifact-tree","title":"Step 5: Display the artifact tree","text":"
This step prints the artifact tree of the busybox image. The tree includes the artifact yaml file, showing the association of the artifact to the busybox image.
These script commands define REF0 as the artifact that was uploaded referring to the first container image.
REF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)\nREF0=\"${REF0:1:-1}\"\n
The following example shows the command and its output:
The displayed artifact tree shows that the original image (localhost:8080/busybox:latest) has one direct referrer (sha256:9c06...883e: application/yaml), the artifact yaml file.
"},{"location":"articles/workflow/#step-6-sign-the-image-and-artifact","title":"Step 6: Sign the image and artifact","text":"
This step creates a key pair for cosign in a separate directory, then uses cosign to sign both the image and the artifact file. Both signatures, like the artifact file itself, are associated with the busybox image.
# create a key pair in a different directory\npushd ${TEST_TMPDIR}\nCOSIGN_PASSWORD= ${COSIGN} generate-key-pair\npopd\n# sign the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n# sign the artifact referring to the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}\n
"},{"location":"articles/workflow/#step-7-display-the-artifact-tree","title":"Step 7: Display the artifact tree","text":"
This step again prints the artifact tree, which should now show the artifact and the two signatures, all associated to the busybox image.
${REGCLIENT} artifact tree localhost:8080/busybox:latest\n
The following example shows the command and its output:
The displayed artifact tree shows that the original image now has two direct referrers \u2014 the artifact and the cosign signature of the original image. In addition, there is a second-level referrer \u2014 the cosign signature of the artifact, which is a referrer of the artifact file.
"},{"location":"articles/workflow/#step-8-end-of-demonstration","title":"Step 8: End of demonstration","text":"
This step halts the zot registry server, ending the workflow demonstration.
# function for stopping zot after demonstration\nfunction zot_teardown() {\n killall zot\n}\n\n# stop zot\nzot_teardown\n
"},{"location":"articles/workflow/#reference-full-workflow-script","title":"Reference: Full workflow script","text":"
Expand the text box below to view the entire workflow as a single executable shell script.
To copy the script to the clipboard, click the copy icon that appears in the upper right corner of the expanded text box.
Click here to view the all-in-one script
#!/bin/bash -xe\n\nTEST_TMPDIR=$(mktemp -d \"${PWD}/artifact-test-${1:+-$1}.XXXXXX\")\n\nTOOLSDIR=$(pwd)/hack/tools\nmkdir -p ${TOOLSDIR}/bin\n\nREGCLIENT=${TOOLSDIR}/bin/regctl\nREGCLIENT_VERSION=v0.5.1\ncurl -Lo ${REGCLIENT} https://github.com/regclient/regclient/releases/download/${REGCLIENT_VERSION}/regctl-linux-amd64\nchmod +x ${REGCLIENT}\n\nCOSIGN=${TOOLSDIR}/bin/cosign\nCOSIGN_VERSION=2.1.1\ncurl -Lo ${COSIGN} https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64 \nchmod +x ${COSIGN}\n\n# OCI registry\nZOT=${TOOLSDIR}/bin/zot\nZOT_VERSION=2.0.0-rc6\ncurl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal\nchmod +x ${ZOT}\n\nZOT_HOST=localhost\nZOT_PORT=8080\n\nfunction zot_setup() {\ncat > $TEST_TMPDIR/zot-config.json << EOF\n{\n \"distSpecVersion\": \"1.1.0-dev\",\n \"storage\": {\n \"rootDirectory\": \"$TEST_TMPDIR/zot\"\n },\n \"http\": {\n \"address\": \"$ZOT_HOST\",\n \"port\": \"$ZOT_PORT\"\n },\n \"log\": {\n \"level\": \"error\"\n }\n}\nEOF\n# start as a background task\n${ZOT} serve $TEST_TMPDIR/zot-config.json &\npid=$!\n # wait until service is up\ncount=5\nup=0\nwhile [[ $count -gt 0 ]]; do\n if [ ! -d /proc/$pid ]; then\n echo \"zot failed to start or died\"\n exit 1\n fi\n up=1\n curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0\n if [ $up -eq 1 ]; then break; fi\n sleep 1\n count=$((count - 1))\ndone\nif [ $up -eq 0 ]; then\n echo \"Timed out waiting for zot\"\n exit 1\nfi\n# setup a OCI client\n${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT\n}\n\n# function for stopping zot after demonstration\nfunction zot_teardown() {\nkillall zot\n}\n\n# call the function to start zot\nzot_setup\n\n# copy an image\nskopeo copy --format=oci --dest-tls-verify=false docker://busybox:latest docker://${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n\n# copy an artifact referring to the above image\ncat > ${TEST_TMPDIR}/artifact.yaml << EOF\nkey:\nval: artifact\nEOF\n${REGCLIENT} artifact put --artifact-type application/yaml -f ${TEST_TMPDIR}/artifact.yaml --subject ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\nREF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)\nREF0=\"${REF0:1:-1}\"\n\n# create a key pair in a different directory\npushd ${TEST_TMPDIR}\nCOSIGN_PASSWORD= ${COSIGN} generate-key-pair\npopd\n# sign the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n# sign the artifact referring to the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}\n\n# list the reference tree\n${REGCLIENT} artifact tree localhost:8080/busybox:latest\n\n# stop zot\nzot_teardown\n
"},{"location":"developer-guide/api-reference/","title":"zot API Command Reference","text":"
This article describes the zot REST API commands, parameters, and responses.
The information presented here is adapted from the interactive OpenAPI (formerly swagger) JSON file in the zot Github project.
For instructions and examples of how to use the zot API, see Using the zot API.
Revokes one current user API key based on given key ID
Parameters
Name In Type Required Description id query string true api token id (UUID)
Example responses
200 Response
\"string\"\n
Responses
Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string
Name In Type Required Description body body api.APIKeyPayload true api token id (UUID)
Example responses
201 Response
\"string\"\n
Responses
Status Meaning Description Schema 201 Created created string 400 Bad Request bad request string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string
Get references for an image given a digest and artifact type
Parameters
Name In Type Required Description name path string true repository name digest path string true image digest artifactType query string true artifact type
Example responses
200 Response
\"string\"\n
Responses
Status Meaning Description Schema 200 OK ok string 404 Not Found not found string 500 Internal Server Error internal server error string
Name In Type Required Description action query string true specify action repo query string true repository name
Enumerated Values
Parameter Value action toggleBookmark action toggleStar
Example responses
200 Response
\"string\"\n
Responses
Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request\". string 403 Forbidden forbidden string 404 Not Found not found string 500 Internal Server Error internal server error string
Name In Type Required Description name path string true repository name
Example responses
202 Response
\"string\"\n
Responses
Status Meaning Description Schema 202 Accepted accepted string 401 Unauthorized unauthorized string 404 Not Found not found string 500 Internal Server Error internal server error string
Response Headers
Status Header Type Format Description 202 Location string /v2/{name}/blobs/uploads/{session_id} 202 Range string 0-0
*Get an image's blob/layer upload given a session_id
Parameters
Name In Type Required Description name path string true repository name session_id path string true upload session_id
Example responses
204 Response
\"string\"\n
Responses
Status Meaning Description Schema 204 No Content no content string 404 Not Found not found string 500 Internal Server Error internal server error string
Resume an image's blob/layer upload given an session_id
Parameters
Name In Type Required Description name path string true repository name session_id path string true upload session_id
Example responses
202 Response
\"string\"\n
Responses
Status Meaning Description Schema 202 Accepted accepted string 400 Bad Request bad request string 404 Not Found not found string 416 Range Not Satisfiable range not satisfiable string 500 Internal Server Error internal server error string
Response Headers
Status Header Type Format Description 202 Location string /v2/{name}/blobs/uploads/{session_id} 202 Range string 0-128
Update and finish an image's blob/layer upload given a digest
Parameters
Name In Type Required Description name path string true repository name session_id path string true upload session_id digest query string true blob/layer digest
Example responses
201 Response
\"string\"\n
Responses
Status Meaning Description Schema 201 Created created string 404 Not Found not found string 500 Internal Server Error internal server error string
Update an image's manifest given a reference or a digest
Parameters
Name In Type Required Description name path string true repository name reference path string true image reference or digest
Example responses
201 Response
\"string\"\n
Responses
Status Meaning Description Schema 201 Created created string 400 Bad Request bad request string 404 Not Found not found string 500 Internal Server Error internal server error string
Name In Type Required Description name path string true repository name n query integer true limit entries for pagination last query string true last tag value for pagination
Status Meaning Description Schema 200 OK OK common.ImageTags 400 Bad Request bad request\". string 404 Not Found not found string
This operation does not require authentication
"},{"location":"developer-guide/api-user-guide/","title":"Using the zot API","text":"
This document describes how to use the zot REST API and provides a number of examples.
For comprehensive details of all zot API commands, see Viewing the complete zot API reference.
The zot API implements the OCI Distribution endpoints along with additional endpoints for supported extensions. You can access the REST API at the same URL and port number used by the GUI and by datapath tools.
The examples in this article assume that the zot registry is located at localhost:8080.
"},{"location":"developer-guide/api-user-guide/#supported-api-endpoints","title":"Supported API endpoints","text":"
The following is a list of zot API endpoints along with the conditions under which each endpoint is available.
Some API endpoints are available only when a specific extension is enabled in the zot configuration file, or when an extension build label is specified in the make command (for example, make binary EXTENSIONS=ui), or both.
For comprehensive details of the API endpoints, see Viewing the complete zot API reference.
"},{"location":"developer-guide/api-user-guide/#oci-endpoints","title":"OCI endpoints","text":"Endpoint Actions Description /v2/ GET OCI specification endpoints /v2/_catalog GET Lists repositories in a registry. /v2/_oci/ext/discover GET Discover extensions per the OCI specification /v2/{repo}/blobs/{digest} DELETE, GET, HEAD Lists or deletes an image's blob/layer given a digest /v2/{repo}/blobs/uploads POST Creates an image blob/layer upload /v2/{repo}/blobs/uploads/{session_id} DELETE, GET, PATCH, PUT Creates, lists, or deletes an image's blob/layer upload given a session_id /v2/{repo}/manifests/{reference} DELETE, GET, HEAD, PUT Creates, lists, or deletes references for an image /v2/{repo}/referrers/{digest} GET Lists referrers given a digest /v2/{repo}/tags/list GET List all image tags in a repository"},{"location":"developer-guide/api-user-guide/#zot-oci-extension-endpoints","title":"zot OCI extension endpoints","text":"Endpoint Actions Description Availability /v2/_zot/ext/mgmt GET Mgmt extension endpoints Enabled by using the mgmt build label and enabling the search extension in the configuration file. /v2/_zot/ext/notation POST With query parameters, uploads certificates for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the notation option enabled. /v2/_zot/ext/search Enhanced search Enabled by using the search build label and enabling the search extension in the configuration file. /v2/_zot/ext/cosign POST Uploads keys for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the cosign option enabled. /v2/_zot/ext/userprefs PUT User preferences endpoints Enabled by using the userprefs build label and enabling both the search and the ui extensions in the configuration file."},{"location":"developer-guide/api-user-guide/#zot-auth-endpoints","title":"zot auth endpoints","text":"Endpoint Actions Description Availability /zot/auth/apikey DELETE, GET, POST Creates, lists, or deletes API keys Available when API key authentication is enabled in the configuration file (\"apikey\": true). /zot/auth/login POST Opens an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication. /zot/auth/logout POST Ends an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication. /zot/auth/callback/\\<provider> POST Specifies a social authentication service provider for redirecting logins, such as Google or dex. Enabled when an OpenID authentication service provider is specified in the configuration file."},{"location":"developer-guide/api-user-guide/#other-zot-endpoints","title":"other zot endpoints","text":"Endpoint Actions Description Availability /v2/_zot/pprof/ GET Returns a current HTML-format profile list along with a count of currently available records for each profile. See Performance Profiling in zot for usage details. Always enabled. /v2/_zot/debug/graphql-playground# See Using GraphQL for details. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label."},{"location":"developer-guide/api-user-guide/#oras-endpoints","title":"ORAS endpoints","text":"Endpoint Actions Description Availability /oras/artifacts/v1/{repo}/ manifests/{digest}/referrers GET OCI Registry As Storage (ORAS) endpoints Always enabled."},{"location":"developer-guide/api-user-guide/#prometheus-endpoint","title":"prometheus endpoint","text":"Endpoint Actions Description Availability /metrics GET Returns extended metrics for monitoring by prometheus Enabled when the metrics extension is enabled in the configuration file."},{"location":"developer-guide/api-user-guide/#openapi-swagger-endpoints","title":"OpenAPI (swagger) endpoints","text":"
This endpoint is accessed with a browser.
Endpoint Action Description Availability /swagger/v2/ (browser) Displays an interactive OpenAPI (swagger) API reference. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label."},{"location":"developer-guide/api-user-guide/#api-authentication","title":"API authentication","text":"
If zot authentication is not configured, any user can access the zot API.
When pushing and pulling images using API calls, your identity can be authenticated by either a password or an API key.
With a valid password, you can specify your credentials in a cURL request as shown in this example:
curl -u <user>:<password> -X GET http://<server>/<endpoint>\n
An API key has advantages in situations where the primary zot authentication does not use the command line, such as a GUI login or social login. Also, you can reduce your security exposure by using an API key instead of your broader credentials, such as an LDAP username and password.
"},{"location":"developer-guide/api-user-guide/#using-api-keys","title":"Using API keys","text":""},{"location":"developer-guide/api-user-guide/#enabling-api-keys","title":"Enabling API keys","text":"
To enable the use of API keys, you must set the apikey attribute to true in the zot configuration file, as shown in the following example:
"},{"location":"developer-guide/api-user-guide/#creating-your-api-key","title":"Creating your API key","text":"
Before you can create or revoke an API key, you must first log in using a different authentication mechanism, such as logging in through the zot GUI. When you are logged in, you can create an API key for your identity using the following API command:
The API key (apiKey) is shown to the user only in the command output when the key is created. It cannot be later retrieved from zot with any other command.
"},{"location":"developer-guide/api-user-guide/#using-your-api-key-in-an-api-command","title":"Using your API key in an API command","text":"
The API key replaces a password in the API command, as shown in the following cURL example:
"},{"location":"developer-guide/api-user-guide/#uploading-a-certificate-for-notation","title":"Uploading a certificate for Notation","text":"
To upload a certificate for notation, use the following endpoint:
POST /v2/_zot/ext/notation\n
cURL command example:
curl --data-binary @certificate.crt -X POST \"http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca\"\n
"},{"location":"developer-guide/api-user-guide/#viewing-the-complete-zot-api-reference","title":"Viewing the complete zot API reference","text":"
You can find comprehensive details of all zot API commands in either of the following locations:
As text descriptions in the zot API Command Reference in the zot documentation.
As an interactive OpenAPI (swagger) JSON file in the zot Github project.
There are many ways to view a swagger file as an interactive document. If you have the npm package installed, for example, you can execute the following command:
$ npx open-swagger-ui swagger.json\n
This command creates a local web server at localhost:3355 where you can interact with the API reference using a browser.
"},{"location":"developer-guide/contributing/","title":"Contributing to zot Development","text":"
The zot project is built for developers by developers. The zot project welcomes the participation of the open source community in extending and improving zot.
zot is released under the Apache License 2.0. All contributions must adhere to this license and must explicitly state adherence.
"},{"location":"developer-guide/contributing/#submitting-a-pull-request-pr","title":"Submitting a Pull Request (PR)","text":"
First, fork the zot project on GitHub and submit a commit to your fork. Then open a new pull request (PR) to the zot project. All pull requests must meet these requirements:
License statement
Either the commit message or the PR description must contain the following statement:
\"By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.\"
Developer Certificate of Origin (DCO) and sign-off
All commits require a Developer Certificate of Origin via the \"Signed-off-by:\" commit message and commit signatures using GPG keys. Include the -s flag in your git commit command.
Commit message format
The commit message must follow the Convention Commits format. The message must begin with a keyword that categorizes the commit, followed by a colon. Validation of a commit message is determined by this expression:
An example of a valid commit message is \"docs: Fixes a typo in module.md.\"
In addition, any new PR requires a brief form to be completed by the submitter with details about the PR. Appropriate code owners are automatically identified and will be notified of the new PR.
We take code quality very seriously. All PRs must pass various CI/CD checks that enforce code quality such as code coverage, security scanning, performance regressions, distribution spec conformance, ecosystem client tool compatibility, etc.
Issues are broadly classified as functional bugs and security issues. The latter is treated a little differently due to the sensitive nature.
"},{"location":"developer-guide/contributing/#filing-a-functional-issue","title":"Filing a Functional Issue","text":"
No software is perfect, and we expect users to find issues with the zot code base. First, check whether your issue has already been filed by someone else by performing an issue search. If the issue is not found, file a new issue by clicking the New issue button on the zot/issues page and answering the questions. The more information that you can provide, the easier it becomes to triage the issue.
"},{"location":"developer-guide/contributing/#filing-a-security-issue","title":"Filing a Security Issue","text":"
Security issues are best filed by sending an email to security@zotregistry.dev. After 45 days, we will make the issue public and give credit to the original filer of the issue.
"},{"location":"developer-guide/contributing/#code-of-conduct","title":"Code of Conduct","text":"
To report a conduct-related incident occurring on the zot project, contact the zot project conduct committee by sending an email to conduct@zotregistry.dev. You can expect a response within three business days.
"},{"location":"developer-guide/extensions-dev/","title":"Developing New Extensions","text":"
You can add new functionality to the zot registry by developing extensions for integration into zot.
The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.
When planning the development of a new extension, be sure to familiarize yourself with the OCI documentation and guidelines for extensions.
The following extensions are currently available in the zot project:
metrics
sync
search
scrub
lint
You can examine the implementation of these extensions in the zot project extensions section. The operation and configuration of the current extensions is described in Configuring zot.
"},{"location":"developer-guide/extensions-dev/#guidelines-for-developing-new-extensions","title":"Guidelines for developing new extensions","text":"
Each file to be included in the binary for only a specific extension must contain the following syntax at the beginning of the file. For example, a file to be included in the build for extension foo must begin with the following lines:
- The first line (`//go:build foo`) is added automatically by the linter if not already present.\n\n- The second line and the third (blank) line are mandatory.\n
For each file that contains functions specific to the extension, create a corresponding \"no-op\" file that contains exactly the same function names. In this file:
Each function is a \"no-op,\" performing no action other than to return a \"success\" value if expected.
We recommend naming this \"no-op\" file by appending -disabled to the name of the original file. For example, if the extension is implemented by extension-foo.go, the corresponding \"no-op\" file could be named extension-foo-disabled.go.
The first two lines declare an \"anti-tag\" (for example, !foo). In the foo extension example, the \"no-op\" file will be included in binaries that don't implement the foo extension, but won't be included in binaries that implement the foo extension. The foo example \"no-op\" file begins with the following lines:
See extension lint-disabled.go in the zot project for an example of a \"no-op\" file.
When developing a new extension, you should create a blackbox test in which a binary containing the new extension can be tested in a usage scenario. See the test/blackbox folder in the zot project for examples of extension tests.
Create targets in Makefile for newly added blackbox tests. You should also add them as GitHub Workflows in .github/workflows/ecosystem-tools.yaml in the zot project.
When configuring multiple extensions in the extensions section of the zot configuration file, list new extensions after the current extensions in the recommended order, such as:
"},{"location":"developer-guide/extensions-dev/#building-zot-with-extensions","title":"Building zot with extensions","text":"
When you build the full zot image (for example, make binary), all extensions listed in the EXTENSIONS variable in Makefile are included in the build. When you've created a new extension, you must modify the EXTENSIONS variable in Makefile by adding the new extension.
To build an image with only selected extensions, you can specify the desired extensions by declaring them in the build command:
make binary EXTENSIONS=extension1,extension2,extension3...\n
For example, to build with only sync and scrub, the command would be:
make binary EXTENSIONS=sync,scrub\n
"},{"location":"developer-guide/onboarding/","title":"Onboarding zot for Development","text":"
zot is a production-ready, open-source, extensible OCI-native image registry, built for developers by developers.
Development is officially supported on Linux and Apple MacOS platforms. However, development should be possible on any platform that supports the golang toolchain.
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS (Apple M1)
Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.
You must use a golang version of at least the minimum specified in go.mod or the build will fail.
To build zot, execute the make command in the zot directory using the following general syntax:
$ make OS=os ARCH=architecture {binary | binary-minimal}
The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.
The binary option builds the full zot binary image with all extensions.
The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.
For example, to build a zot image with extensions for an Intel-based linux server, use the following command:
make OS=linux ARCH=amd64 binary\n
The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-minimal-linux-amd64.
Click here to view an example of the getting started process.
To produce a zot binary that includes extensive debugging information, build zot with the binary-debug option, as shown in this example:
make OS=linux ARCH=amd64 binary-debug\n
You can then attach and run a debugging tool such as Delve to the running zot process.
Delve is a powerful open-source debugger for the Go programming language. Downloads and documentation for Delve are available on GitHub at https://github.com/go-delve/delve.
Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.
For detailed information about performance profiling, see Performance Profiling in zot.
/\n- pkg/ # Source code for all libraries\n - api/ # Source code for HTTP APIs\n - config/ # Global configuration model\n - storage/ # Source code for storage backends\n - cli/ # Source code for command line interface (cli)\n - common/ # Source code for common utility routines\n - compliance/ # Source code for dist-spec conformance tests\n - log/ # Source code for logging framework\n - test/ # Internal test scripts/data\n - extensions/ # Source code for all extensions\n - config/\n - sync/\n - monitoring/\n - sync/\n - exporter/ # Source code for metrics exporter\n- cmd/ # Source code for binary main()s\n - zot/ # Source code for zot binary\n - zli/ # Source code for zot cli\n - zb/ # Source code for zb, the dist-spec benchmarking tool\n- errors/ # Source code for error codes\n- examples/ # Configuration examples\n- swagger/ # Swagger integration\n- docs/ # Documentation\n
"},{"location":"developer-guide/onboarding/#additional-state-in-zot","title":"Additional state in zot","text":"
In addition to the storage of repository images, zot stores data for various processes in local and remote storage and databases. The following table shows the storage locations for different processes and types of data.
Data or Process Storage Location Description images local andAWS S3 Image blobs repository synchronization local/<repo_name>/.sync The sync operation temporarily copies the upstream blobs to: /<repo_name>/.sync/${UUID}/<repo_name>, then copies to /<repo_name> and deletes the temporary directory ${UUID} deduplication local/cache.db Cache for deduplication of files stored locally AWS DynamoDB Cache for deduplication of files stored in AWS CVE local/_trivy Database of Common Vulnerabilities and Exposures (CVE) information and scan results user sessions local/_sessions zot user session authentication (for zui) PKI authentication documents local/_cosign Private keys for signature verification using cosign local/_notation Certificates for signature verification using notation metadata local/repo.db Local storage of manifests, configurations, download counters, signature verification results AWS DynamoDB Cloud storage of manifests, configurations, download counters, signature verification results"},{"location":"general/architecture/","title":"Architecture","text":"
zot is an OCI-native container image registry. This document discusses the design goals, the overall architecture, and the design choices made in the implementation of the design goals.
HTTP APIs strictly conforms to the OCI Distribution Specification
zot intends to be a production reference implementation for the OCI Distribution Specification. In fact, zot does not support any other vendor protocol or specification.
Storage layout follows the OCI Image Specification
The default and only supported storage layout is the OCI Image Layout. The implications of this choice are that any OCI image layout can be served by zot and conversely, zot converts data on-the-wire into an OCI image layout.
zot is a single binary image with all features included so that deployment is extremely simple in various environments, including bare-metal, cloud, and embedded devices. Behavior is controlled by a single configuration file.
"},{"location":"general/architecture/#enable-only-what-you-need","title":"Enable Only What You Need","text":"
A clear separation exists between (1) the core OCI-compliant HTTP APIs and storage functionality, and (2) other add-on features modeled as extensions. The extension features can be selectively enabled both at build-time and run-time.
For more information, see \"Conditional Builds\" in zot's security posture document.
External interaction with zot consists of the following two types:
Client-initiated data or meta-data queries
Admin-initiated configuration
All client-side interaction occurs over HTTP APIs. The core data path queries are governed by the OCI Distribution Specification. All additional meta-data queries are handled based on the setting of the search extension:
If the search extension is enabled, enhanced registry searching and filtering is supported, using graphQL. A database is maintained by zot to efficiently answer complex queries on data stored in the database.
If the search extension is not enabled, basic queries are supported using the core APIs. These queries are less efficient and search actual storage, which is limited in content.
A single configuration file governs zot instance behavior. An exception can be made for security concerns, wherein configuration items containing sensitive credentials can be stored in separate files referenced by the main configuration file. Using separate files allows stricter permissions to be enforced on those files if stored locally. Also, modeling as external files allows for storing Kubernetes Secrets.
The configuration file is divided into sections for http, storage, log, and extension, governing the behavior of the respective components.
"},{"location":"general/architecture/#authentication-and-authorization","title":"Authentication and Authorization","text":"
A robust set of authentication and authorization options are supported natively in zot. These controls are enforced before access is allowed into the storage layer.
For more information, see User Authentication and Authorization with zot.
zot supports any modern local filesystem. Remote filesystems, such as AWS S3 or any AWS S3-compatible storage system, are supported. Additional driver support is planned in the roadmap.
Deduplication is supported for both local and remote filesystems, but deduplication requires a filesystem with hard-link support.
For more information, see Storage Planning with zot.
zot integrates with the trivy security scanner to scan container images for vulnerabilities. The database is kept current by periodically downloading any vulnerability database updates at a configurable interval. The user remains agnostic of the actual scanner implementation, which may change over time.
Several periodic tasks occur in the registry, such as garbage collection, sync mirroring, and scrubbing. A task scheduler handles these tasks in the background, taking care not to degrade or interrupt foreground tasks running in the context of HTTP APIs.
"},{"location":"general/concepts/","title":"Concepts","text":""},{"location":"general/concepts/#what-is-zot","title":"What is zot?","text":"
zot is a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.
Two broad trends are changing how we build, distribute, and consume software. The first trend is the increasing adoption of container technologies. The second trend is that software solutions are being composed by combining elements from various sources rather than being built entirely from scratch. The latter trend raises the importance of software provenance and supply chain security. In both trends, zot intends to play an important role by providing a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.
"},{"location":"general/concepts/#what-is-an-oci-image-registry","title":"What is an OCI image registry?","text":"
An OCI image registry is a server-based application that allows you to store, manage, and share container images. A developer uploads (pushes) an image to the registry for distribution. Users can then download (pull) the image to run on their systems. The OCI Distribution Specification, published by the Open Container Initiative (OCI), defines a standard API protocol for these and other image registry operations.
An image registry can be a part of your continuous integration and continuous deployment (CI/CD) pipeline when you host zot on your public or private server. In its minimal form, you can also embed a zot registry in a product. In either case, zot provides a secure software supply chain for container images.
zot = OCI Distribution Specification + OCI Image Format
At its heart, zot is a production-ready, vendor-neutral OCI image registry with images stored in the OCI image format and with the OCI distribution specification on-the-wire. zot is built for developers by developers, offering features such as minimal deployment using a single binary image, built-in authentication and authorization, and inline garbage collection and storage deduplication.
Some of the principal advantages of zot are:
Open source
OCI standards-only both on-the-wire and on-disk
Clear separation between core distribution spec and zot-specific extensions
Software supply chain security, including support for cosign and notation
Security hardening
Single binary with many features built-in
Suitable for deployments in cloud, bare-metal, and embedded devices
zot fully conforms to the OCI Distribution Specification.
The following table lists additional advantages of zot:
Distribution Spec conformance yes CNCF project accepted as a Sandbox Project License Apache 2.0 On-premises deployment yes OCI conformance* yes Single binary image* yes Minimal build* yes Storage Layout OCI v1 Image Layout Authentication built-in Authorization built-in Garbage collection inline Storage deduplication inline Cloud storage support yes Delete by tag yes Vulnerability scanning built-in Command line interface (cli) yes UI yes External contributions beta available Image signatures built-in
* The minimal build feature is the ability to build a minimal Distribution Spec compliant registry in order to reduce library dependencies and the possible attack surface.
The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.
Wherever applicable, extensions can be dynamically discovered using the extensions support of the OCI Distribution Specification.
Extension features of zot are available only with a full zot image. They are excluded from the minimal zot image.
"},{"location":"general/extensions/#extensions-implemented-in-zot","title":"Extensions implemented in zot","text":"
The extensions implemented in zot include administrator-configured functionality and end-user features.
Currently, search, trust, and userprefs are the only zot extensions operable by end users. Only these extensions are accessible through HTTP APIs and are discoverable using the OCI extensions mechanism.
The following extensions are currently supported by zot:
One of the key functions of a container image registry (which is essentially a graph of blobs) is the ability to perform interesting image and graph traversal queries. The user interacts with the search extension via a graphQL endpoint. The schema is published with every release.
Examples of queries are:
\"Does an image exist?\"
\"What is its size?\"
\"Does an image depend on this image via its layers?\"
\"What vulnerabilities exist in an image or its dependent images?\"
You can deploy a local mirror pointing to an upstream zot instance with various container image download policies, including on-demand and periodic downloads. The sync function is useful to avoid overwhelming the upstream instance, or if the upstream instance has rate-limited access.
The lint extension helps to avoid image compliance issues by enforcing certain policies about the image or the image metadata. Currently, lint can check an uploaded image to enforce the presence of required annotations such as the author or the license.
Although container images are content-addressable with their SHA256 checksums, and validations are performed during storage and retrieval, it is possible that bit-rot sets in when not in use. The scrub extension actively scans container images in the background to proactively detect errors.
Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user through the zot API. The trust extension enables and configures this function.
The metrics extension adds a node exporter, which is not present in the minimal build.
"},{"location":"general/extensions/#graphical-user-interface","title":"Graphical user interface","text":"
Using the zot graphical user interface (GUI), you can browse a zot registry for container images and artifacts. From the web interface, you can copy the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.
The userprefs extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.
The functions currently implemented by this extension include:
Toggling the star (favorites) icon for a repository.
Toggling the bookmark icon for a repository.
For information about configuring zot extensions, see Configuring zot.
"},{"location":"general/features/","title":"Summary of Key Features","text":"
Conforms to OCI distribution spec APIs
Uses OCI image layout for image storage
Can serve any OCI image layout as a registry
Single binary for all the features
Doesn't require root privileges
Clear separation between core dist-spec and zot-specific extensions
Supports container image signatures - cosign and notation
Supports helm charts
Behavior controlled via configuration
Binaries released for multiple operating systems and architectures
Supports advanced image queries using search extension
Supports image deletion by tag
Currently suitable for on-premises deployments (e.g. colocated with Kubernetes)
Compatible with ecosystem tools such as skopeo and cri-o
Vulnerability scanning of images
TLS support Authentication via:
TLS mutual authentication
HTTP Basic (local htpasswd and LDAP)
HTTP Bearer token
Supports Identity-Based Access Control
Supports live modifications on the configuration file while zot is running (Authorization configuration only)
Inline storage optimizations:
Automatic garbage collection of orphaned blobs
Layer deduplication using hard links when content is identical
Data scrubbing
Serve multiple storage paths (and backends) using a single zot server
Pull and synchronize from other dist-spec conformant registries
Supports rate limiting including per HTTP method
Metrics with Prometheus
Using a node exporter in case of minimal zot
Swagger based documentation
zli: command-line client support
zb: a benchmarking tool for dist-spec conformant registries
Released under Apache 2.0 License
"},{"location":"general/glossary/","title":"Glossary","text":""},{"location":"general/glossary/#documentation-icons","title":"Documentation Icons","text":"Icon Description Note \u2014 A point of emphasis or caution. Tip \u2014 A helpful suggestion or a reference to additional material not covered in this document. Warning \u2014 A suggestion or advisory intended to avoid a loss of service or data."},{"location":"general/glossary/#definitions","title":"Definitions","text":"Term Description artifact A file of any kind produced during a container build process or associated with the operation of a container. For example, a Helm chart is an artifact that might be stored along with a container. CNCF As part of the Linux Foundation, the Cloud Native Computing Foundation provides support, oversight, and direction for open-source, cloud native projects. cosign cosign is a tool that performs container signing, verification, and storage in an OCI registry. cosigned cosigned is an image admission controller that validates container images before deploying them. cri-o cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes. deduplication A storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. digest A hashed checksum, such as SHA-256, for verifying the integrity of the downloaded image. Distribution Specification The OCI Distribution Specification project defines an API protocol to facilitate and standardize the distribution of content. extensions Additional registry features (APIs) that are not a part of the Distribution Specification can be added as Extensions. helm chart A helm chart is a package of files that orchestrate the deployment of Kubernetes resources into a Kubernetes cluster. manifest An image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system. node exporter A software component that collects hardware and operating system level metrics exposed by the kernel. OCI The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes. ORAS OCI Registry as Storage (ORAS) is a tool for distributing OCI artifacts across OCI registries. prometheus Prometheus is a node exporter that exposes a wide variety of hardware- and kernel-related metrics. referrer An image containing a non-nil subject field with a descriptor to the referred image. registry A service that stores and distributes container images and artifacts. repository A collection of images with the same name, differentiated by tags. skopeo skopeo is a command line utility that performs various operations on container images and image repositories. stacker stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout. tag A label applied to an image that distinguishes the image from other images in the same repository. A common example is a version tag. zb A benchmarking tool, available as a zot companion binary, for benchmarking a zot registry or any other container image registry that conforms to the OCI Distribution Specification. zli A zot companion binary that implements a set of command line commands for interacting with the zot registry server. zui A zot companion binary that implements a graphical user interface (GUI) for interacting with the zot registry server. zxp A node exporter, available as a zot companion binary, that can be deployed with a minimal zot image in order to scrape metrics from the zot server."},{"location":"general/project/","title":"About the zot Project","text":""},{"location":"general/project/#project-repository","title":"Project Repository","text":"
"},{"location":"general/releases/","title":"Released Images for zot","text":"
This document describes the available zot images for the various supported hardware and software platforms, along with information about image variations, image locations, and image naming formats.
zot is supported on Linux and Apple MacOS platforms with Intel or ARM processors.
Table: Supported platforms and architectures
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS (Apple M1) freebsd amd64 Intel-based FreeBSD* freebsd arm64 ARM-based FreeBSD*
**NOTE:* While binary images are available for FreeBSD, building container images is not supported at this time."},{"location":"general/releases/#full-and-minimal-binary-images","title":"Full and minimal binary images","text":"
In addition to variations for specific platforms and architectures, binary images are also available in full and minimal flavors:
A full zot binary image is compiled with all extensions. Extensions include functions such as metrics, registry synchronization, search, and scrub.
A minimal distribution-spec conformant zot binary image is compiled with only a minimal set of code and libraries, reducing the attack surface. This option might be optimal for a registry embedded in a shipping product.
An executable binary image for zot is named using the target platform and architecture from the Supported platforms and architectures table. The general format of a binary image file name is one of these two:
zot-<os>-<architecture>
A full zot binary image with all extensions has a filename of the form zot-<os>-<architecture>. For example, the full binary image for an Intel-based linux server is zot-linux-amd64.
zot-<os>-<architecture>-minimal
A minimal distribution-spec conformant zot binary image has a filename of the form zot-<os>-<architecture>-minimal. For example, the minimal binary image for an Intel-based linux server is zot-linux-amd64-minimal.
For convenience, you can rename the binary image file to simply zot after downloading.
"},{"location":"general/releases/#where-to-get-zot","title":"Where to get zot","text":"
You can download native executable binary images or container (Docker) images.
The zot project is hosted on GitHub at project-zot.
To download a binary image, go to the zot releases and select a release. Go to the Assets section of the release page and download the binary for your platform and architecture.
You may need to use the chmod command to make the image executable.
When downloading a binary image for MacOS, download the darwin image.
It is now possible to bisect CVEs (zli cve diff) between two image tags/versions in the same repository. Furthermore, a CVE query for a particular image tag can return a detailed description of CVEs.
"},{"location":"general/whats-new/#documentation-for-immutable-image-tags","title":"Documentation for \"Immutable Image Tags\"","text":"
A new article has been added to document how image tags can be made immutable.
"},{"location":"general/whats-new/#cross-repo-tag-search-in-ui","title":"Cross-repo tag search in UI","text":"
You can now search for a tag across all repos by starting your query as ':' in the UI, which will return all images that have that tag."},{"location":"general/whats-new/#support-for-oras-artifacts-removed","title":"Support for ORAS Artifacts removed","text":"
OCI distribution spec 1.1.0 has added support \"artifacts\" which is likely to gain wider adoption. ORAS artifacts are not widely used or supported.
:warning: Support is removed starting from this version.\n
"},{"location":"general/whats-new/#v201","title":"v2.0.1","text":""},{"location":"general/whats-new/#support-for-hot-reloading-of-ldap-credentials-file","title":"Support for hot reloading of LDAP credentials file","text":"
Since v2.0.0, LDAP credentials have been specified in a separate file. Starting with this version, the file is watched and changes applied without restarting zot.
"},{"location":"general/whats-new/#bugfixes-and-performance-improvements","title":"Bugfixes and performance improvements","text":"
Under some configurations, zot consumes significant CPU and memory resources. This has been fixed in this release.
Support is added for OCI Distribution Spec v1.1.0-rc3 and OCI Image Spec v1.1.0-rc4. The OCI changes are summarized here. These specifications allow arbitrary artifact types and references so that software supply chain use cases can be supported (SBOMs, signatures, etc). Currently, oras and regclient support this spec.
For a demonstration of an end-to-end OCI artifacts workflow, see Software Provenance Workflow Using OCI Artifacts.
Support is deprecated for earlier OCI release candidates.
Using the new zot GUI, you can browse a zot registry for container images and artifacts. The web interface provides the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.
"},{"location":"general/whats-new/#support-for-social-logins","title":"Support for social logins","text":"
Support is added for OpenID authentication with GitHub, Google, and dex.
"},{"location":"general/whats-new/#group-policies-for-authorization","title":"Group policies for authorization","text":"
When creating authorization policies, you can assign multiple users to a named group. A group-specific authorization policy can then be defined, specifying allowed access and actions for the group.
Configuration syntax change: In the previous release, authorization policies were defined directly under the accessControl key in the zot configuration file. With the new ability to create authorization groups, it becomes necessary to add a new repositories key below accessControl. Beginning with zot v2.0.0, the set of authorization policies are now defined under the repositories key.
The validity of an image's signature can be verified by zot. Users can upload public keys or certificates to zot.
"},{"location":"general/whats-new/#ldap-credentials-stored-separately-from-configuration","title":"LDAP credentials stored separately from configuration","text":"
The LDAP credentials are removed from zot's LDAP configuration and stored in a separate file. See zot's LDAP documentation.
This LDAP configuration change is incompatible with previous zot releases. When upgrading, you must reconfigure your LDAP credentials if you use LDAP.
"},{"location":"general/whats-new/#storage-deduplication-on-startup","title":"Storage deduplication on startup","text":"
Deduplication, a storage space saving feature, now runs or reverts at startup depending on whether the feature is enabled or disabled. You can trigger deduplication by enabling it and then restarting zot.
In the zot GUI, you can bookmark an image so that it can be easily found later. Bookmarked images appear in search queries when the bookmarked option is enabled.
"},{"location":"general/whats-new/#ability-to-delete-tags-from-the-ui","title":"Ability to delete tags from the UI","text":""},{"location":"general/whats-new/#command-line-search","title":"Command line search","text":"
The zli search command allows smart searching for a repository by its name or for an image by its repo:tag.
"},{"location":"general/whats-new/#search-by-digest","title":"Search by digest","text":"
You can perform a global search for a digest (SHA hash) using either the UI or the CLI. This function is useful when an issue is found in a layer that is used by multiple images. In the UI Search box, for example, begin typing sha256: followed by a partial or complete digest value to see a dropdown list of images that contain the layer with the digest value.
"},{"location":"general/whats-new/#graphql-support-for-search","title":"GraphQL support for search","text":"
A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. In addition to supporting direct GraphQL queries through the API, zot hosts the GraphQL Playground, which provides an interactive graphical environment for GraphQL queries.
"},{"location":"general/whats-new/#scheduling-of-background-tasks","title":"Scheduling of background tasks","text":"
You can adjust the background scheduler based on your deployment requirements for tasks that are handled in the background, such as garbage collection. See Configuring zot.
"},{"location":"general/whats-new/#performance-profiling-for-troubleshooting","title":"Performance profiling for troubleshooting","text":"
You can use zot's built-in profiling tools to collect and analyze runtime performance data.
"},{"location":"general/whats-new/#binaries-for-freebsd","title":"Binaries for FreeBSD","text":"
zot binary images are available for the FreeBSD operating system. Supported architectures are amd64 and arm64.
\u00a0zot container images for FreeBSD will be available in a future release.
The two types of state (images and image metadata) can both now be on remote storage so that zot process lifecycle and its storage can be managed and scaled independently.
"},{"location":"general/whats-new/#digest-collision-detection-during-image-deletion","title":"Digest Collision Detection During Image Deletion","text":"
When two or more image tags point to the same image digest and the image is deleted by digest causes data loss and dangling references. A new behavior-based policy called detectManifestCollision was added to prevent this.
"},{"location":"install-guides/install-guide-k8s/","title":"Installing zot with Kubernetes and Helm","text":"
Using Kubernetes with Helm charts for zot, you can easily deploy zot as an application in a Kubernetes cluster.
"},{"location":"install-guides/install-guide-k8s/#before-you-begin","title":"Before you begin","text":""},{"location":"install-guides/install-guide-k8s/#prerequisites","title":"Prerequisites","text":"
kubectl must be installed and a Kubernetes cluster must be ready.
Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.
"},{"location":"install-guides/install-guide-k8s/#installing-zot","title":"Installing zot","text":""},{"location":"install-guides/install-guide-k8s/#step-1-locate-the-helm-charts-in-a-remote-repository","title":"Step 1: Locate the Helm charts in a remote repository","text":"
Specify a remote repository that contains the Helm charts for zot. Give the repo a local name, such as project-zot, as in this example:
\"project-zot\" has been added to your repositories\n
The Helm charts for zot are currently hosted in these publicly-accessible repositories: - zotregistry.dev - artifacthub.io
Search the repository to see the Helm charts for zot installation. Search using the keyword 'project-zot' or 'zot', as in this example:
helm search repo project-zot
NAME CHART VERSION APP VERSION DESCRIPTION\nproject-zot/zot <chart-version> v2.1.0 A Helm chart for Kubernetes\n
The APP VERSION is the version/tag of the zot image used for the deployment.
Update to the latest information of available charts from the chart repository, as shown in this example:
helm repo update project-zot
Hang tight while we grab the latest from your chart repositories...\n...Successfully got an update from the \"project-zot\" chart repository\nUpdate Complete. \u2388Happy Helming!\u2388\n
Display the default information of the Helm chart, as shown in this example:
helm show all project-zot/zot
apiVersion: v2\n appVersion: v2.1.0\n description: A Helm chart for Kubernetes\n name: zot\n type: application\n version: <chart-version>\n\n # Default values for zot.\n # This is a YAML-formatted file.\n # Declare variables to be passed into your templates.\n replicaCount: 1\n image:\n repository: ghcr.io/project-zot/zot-linux-amd64\n pullPolicy: IfNotPresent\n tag: \"v2.1.0\"\n serviceAccount:\n create: true\n annotations: {}\n name: \"\"\n service:\n type: NodePort\n port: 5000\n
"},{"location":"install-guides/install-guide-k8s/#step-2-determine-any-needed-changes-from-the-helm-charts-defaults","title":"Step 2: Determine any needed changes from the Helm chart\u2019s defaults","text":"
Inspect the default information of the Helm chart, as shown in the previous step. In many cases, the default chart values may be acceptable. If your installation requires any non-default settings, you may be able to specify them during the installation. Not all chart values are configurable, but you can display those that are configurable using the command in the following example:
helm show values project-zot/zot
# Default values for zot.\n # This is a YAML-formatted file.\n # Declare variables to be passed into your templates.\n replicaCount: 1\n image:\n repository: ghcr.io/project-zot/zot-linux-amd64\n pullPolicy: IfNotPresent\n tag: \"v2.1.0\"\n serviceAccount:\n create: true\n annotations: {}\n name: \"\"\n service:\n type: NodePort\n port: 5000\n
The configurable settings in the chart are listed in the following table:
parameter description
replicaCount
Desired number of replicas of the application
image.repository
Repository and image name for the application
image.pullPolicy
Whether to pull the image from the repository. If not specified, the policy depends on image.tag:
If tag is :latest or no tag: Always
If tag is other than :latest: IfNotPresent
image.tag
Identifies different versions the image. default is the chart appVersion.
Examples: :latest (the default) or :v2.1.0
serviceAccount.create
Specifies whether a service account should be created
serviceAccount.annotations
Annotations to add to the service account
serviceAccount.name
Name of the service account to use. If name is not set and create is true, a name is generated using the fullname template.
service.type
ClusterIP (default), NodePort, LoadBalancer, ExternalName, or Headless
You can change multiple settings with one --set statement. For example, you might want your installation to have more replicas or a different port number:
--set replicaCount=2,service.port=5050
"},{"location":"install-guides/install-guide-k8s/#customizing-the-helm-chart-using-a-file","title":"Customizing the Helm chart using a file","text":"
You can also create a YAML file with your overrides and then add the new file by adding the -f flag to the helm install command. For example, to override the replica count and port number, the contents of your YAML file (for example, \"myfile.yaml\") would be:
replicaCount: 2\nservice:\n port: 5050\n
and the following flag would be added to the helm install command:
Install zot using the helm install command. The first example shows how to perform a default installation. The additional examples show different ways to modify the helm install command to override default settings in the Helm chart:
Example 1: use default chart parameters
helm install zot project-zot/zot
NAME: zot\nLAST DEPLOYED: Thu Aug 11 19:13:02 2022\nNAMESPACE: default\nSTATUS: deployed\nREVISION: 1\nNOTES:\n Get the application URL by running these commands:\n export NODE_PORT=$(kubectl get --namespace default -o jsonpath=\"{.spec.ports[0].nodePort}\" services zot)\n export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath=\"{.items[0].status.addresses[0].address}\")\n echo http://$NODE_IP:$NODE_PORT\n
Example 2: modify specific chart parameters with 'set'
helm install --set replicaCount=2,service.port=5050 zot project-zot/zot
Example 3: modify specific chart parameters with a file
helm install -f myfile.yaml zot project-zot/zot
Example 4: use a specific version of the Helm chart
helm install zot project-zot/zot --version 0.1.0
Example 5: link to a kubeconfig file
helm install zot project-zot/zot --kubeconfig $HOME/.kube/config
"},{"location":"install-guides/install-guide-k8s/#after-the-installation","title":"After the installation","text":""},{"location":"install-guides/install-guide-k8s/#verify-the-installation","title":"Verify the installation","text":"
List all releases that are either deployed or failed.
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION\nzot default 1 <datetime> deployed <chart-version> v2.1.0\n
This response indicates that zot is deployed.
After making sure that your pods are up and running, execute the following commands:
Should you need to uninstall zot, use the helm uninstall command, as in this example:
helm uninstall zot
"},{"location":"install-guides/install-guide-linux/","title":"Installing zot on Bare Metal Linux","text":"
Using an available executable zot image, you can easily deploy zot on a Linux server.
"},{"location":"install-guides/install-guide-linux/#before-you-begin","title":"Before you begin","text":""},{"location":"install-guides/install-guide-linux/#about-binary-images","title":"About binary images","text":"
Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.
Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.
"},{"location":"install-guides/install-guide-linux/#installation","title":"Installation","text":""},{"location":"install-guides/install-guide-linux/#step-1-get-zot","title":"Step 1: Get zot","text":"
Using wget, download the appropriate zot binary image for your platform from the zot GitHub project. Download the image to the`/usr/bin/` directory and rename it to zot, as in this example:
"},{"location":"install-guides/install-guide-linux/#step-2-create-a-zot-configuration-file","title":"Step 2: Create a zot configuration file","text":"
Create a zot configuration file as /etc/zot/config.json.
See Configuration file options for an example file with options and recommendations. You can find other configuration file examples in the zot GitHub project and in Configuring zot.
"},{"location":"install-guides/install-guide-linux/#step-3-configure-a-local-authentication-account","title":"Step 3: Configure a local authentication account","text":"
If you want to use local authentication with zot, create a /etc/zot/htpasswd file with an initial account entry using the htpasswd command as in this example:
"},{"location":"install-guides/install-guide-linux/#step-4-define-the-zot-service","title":"Step 4: Define the zot service","text":"
Create a /etc/systemd/system/zot.service file to define the zot service in systemd. The following is an example service file for zot:
[Unit]\nDescription=OCI Distribution Registry\nDocumentation=https://zotregistry.dev/\nAfter=network.target auditd.service local-fs.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/zot serve /etc/zot/config.json\nRestart=on-failure\nUser=zot\nGroup=zot\nLimitNOFILE=500000\nMemoryHigh=30G\nMemoryMax=32G\n\n[Install]\nWantedBy=multi-user.target\n
Be sure to configure a dedicated non-root user ID as the User and Group in the zot service definition. The 'zot' user ID in this example is created in the next step.
"},{"location":"install-guides/install-guide-linux/#step-5-create-a-user-id-to-own-the-zot-service","title":"Step 5: Create a user ID to own the zot service","text":"
Create a non-root user ID to be the owner of the zot service and its resources.
In this example, the user ID 'zot' is created with the adduser command, and resource ownership is assigned.
With the adduser options shown, the 'zot' user ID has no local directory. There is no ability to log into the zot user account, and the account has no finger information.
When the zot service has started, you can check its status with this command:
sudo systemctl status zot\n
"},{"location":"install-guides/install-guide-linux/#after-the-installation","title":"After the installation","text":"
If your zot registry server is public facing, we recommend that you test your TLS configuration using a service such as the Qualys SSL Server Test.
Refer to Configuring zot for further information about maintaining your zot registry server.
"},{"location":"install-guides/install-guide-linux/#configuration-file-options-and-recommendations","title":"Configuration file options and recommendations","text":"
The following zot configuration file (config.json) can be used as a template for your own installation. You can modify this file to suit your own environment.
The example file enables registry synchronization with two other container registries. In the example, the zot server synchronizes with the Google and Docker container registries, as shown here:
"},{"location":"user-guides/user-guide-datapath/","title":"Push and Pull Image Content","text":"
zot is an OCI image registry that allows you to store, manage, and share container images.
A zot registry can store and serve a variety of content, but the type of content may dictate your choice of a client tool.
For various content types, this document shows examples of using a third-party client tool that supports the content. The following table shows which content and client tools are demonstrated.
"},{"location":"user-guides/user-guide-datapath/#pull-an-oci-image-to-a-private-docker-registry","title":"Pull an OCI image to a private docker registry","text":"
This example pulls the latest container image for the busybox application and stores the image to a local private docker registry.
In these examples, authentication is disabled for the source and destination. You can enable authentication by changing the command line options as follows:
--src-tls-verify=true\n--dest-tls-verify=true\n
You can also add credentials for authenticating with a source or destination repository:
"},{"location":"user-guides/user-guide-datapath/#common-tasks-using-regclient-for-oci-images","title":"Common tasks using regclient for OCI images","text":"
regclient is a client interface that performs various operations on OCI container images and image repositories. The command line interface for regclient is regctl.
For detailed information about regctl commands, see the regctl Documentation.
"},{"location":"user-guides/user-guide-datapath/#push-an-oci-image_1","title":"Push an OCI image","text":"
This example pushes version 1.20 of golang to a tools repository within the registry.
In the preceding examples, TLS authentication with the zot registry was disabled by the following command:
$ regctl registry set --tls=disabled localhost:5000\n
This command allows regctl to accept an HTTP response from the zot server. If TLS authentication is enabled on the zot registry server, you can omit this command from your regctl session.
"},{"location":"user-guides/user-guide-datapath/#common-tasks-using-oras-for-oci-artifacts","title":"Common tasks using oras for OCI artifacts","text":"
ORAS (OCI Registry As Storage) is a command line client for storing OCI artifacts on OCI repositories.
For detailed information about the oras commands in these examples, see the ORAS CLI documentation.
"},{"location":"user-guides/user-guide-datapath/#push-an-artifact","title":"Push an artifact","text":"
This example pushes version 2 of an artifact file named hello-artifact to a zot registry.
You will be prompted to manually enter a password.
"},{"location":"user-guides/user-guide-datapath/#common-tasks-using-crane-for-oci-images","title":"Common tasks using crane for OCI images","text":"
crane is an open-source project that provides a command-line interface (CLI) for interacting with container registries, such as Docker Hub and Google Container Registry.
For detailed information about crane commands, see the crane Documentation.
"},{"location":"user-guides/user-guide-datapath/#push-an-oci-image_2","title":"Push an OCI image","text":"
This example pushes the latest container image for the alpine application to a registry.
"},{"location":"user-guides/user-guide-datapath/#copy-an-oci-image-to-a-private-docker-registry","title":"Copy an OCI image to a private docker registry","text":"
This example pulls the latest container image for the alpine application and stores the image to a local private docker registry.
To authenticate with the registry server, log in at the start of your session using the following command:
$ crane auth login -u myUsername localhost:5000\n
"},{"location":"user-guides/user-guide-gui/","title":"Use the Web Interface to Find Images","text":"
Using a browser, you can browse a zot repository for container images and artifacts. The web interface also provides the commands for downloading an image using popular third-party tools.
If a zot registry is built with the optional zui package, the registry has a web interface.
"},{"location":"user-guides/user-guide-gui/#access-the-registry","title":"Access the registry","text":"
Depending on the security configuration of the zot registry, you might need to authenticate before being given access.
The initial page of the registry displays a sampling of the most popular images and recently updated images. To view all available images in the registry, click the View all link in the upper right of the page to go to the /explore page.
Wherever an image name appears, two icons follow the name, indicating the results of the vulnerability scan and the signature status. These icons are described in Icons and their meanings.
"},{"location":"user-guides/user-guide-gui/#find-an-image","title":"Find an image","text":"
To assist you in finding images specific to your requirements, the /explore page provides several sorting options along with faceted navigation in addition to a general search box.
Sorting criteria include relevance, most recently updated, alphabetical, and most downloaded.
Navigation facets include operating system, CPU architecture, and signature status.
When you locate the desired image, click its tile.
"},{"location":"user-guides/user-guide-gui/#inspect-the-image-properties","title":"Inspect the image properties","text":"
The OVERVIEW tab of the initial image description page contains a brief description of the image along with several details, such as the repository URL, number of downloads, last published, size, and license type.
Click the TAGS tab to view the available versions of the image.
Click the tag link of the desired version of the image. In the resulting page, you can view detailed information about the image, including its digest hash, and you can obtain a command to pull the image from the repository.
Tabs on this page provide the following information:
Tab Description LAYERS The build command and the digest hash USES A list of images used by this image USED BY A list of images that use this image VULNERABILITIES A list of known vulnerabilities
From the LAYERS tab, click Details to view an example of the image build command and the layer's digest hash.
"},{"location":"user-guides/user-guide-gui/#pull-an-image","title":"Pull an image","text":"
After opening the tag link of the desired image, click the Pull Image drop-down list to display the available pull commands. Docker, podman, and skopeo image management tools are supported.
Select a tool and click the pages icon next to the command to copy the full command to your clipboard. An example of the pull command using podman is:
To mark an image so that it can be easily found later, click the bookmark icon on the image page. Bookmarked images appear in search queries when the Bookmarked option is enabled.
The bookmark icon before selection:
The bookmark icon after selection:
"},{"location":"user-guides/user-guide-gui/#icons-and-their-meanings","title":"Icons and their meanings","text":"
These icons appear next to the image name, indicating the results of the vulnerability scan and the signature status.
Icon Description A vulnerability scan of the image found no vulnerabilities A vulnerability scan of the image failed(See severity icon in VULNERABILITIES tab) Critical severity High severity Medium severity Low severity The image signature is verified The image signature is not verified The image is not bookmarked by the user The image is bookmarked by the user"},{"location":"user-guides/zli/","title":"Using the command line interface (zli)","text":"
zli: The command line tool for zot servers
"},{"location":"user-guides/zli/#what-is-zli","title":"What is zli?","text":"
zli is a binary that implements a set of command line commands for interacting with the zot registry server.
We recommend installing zli when you install zot.
"},{"location":"user-guides/zli/#how-to-get-zli","title":"How to get zli","text":"
zli is hosted with zot on GitHub at project-zot. From GitHub, you can download the zli binary or you can build zli from the source.
zli is supported for the following operating systems and platform architectures:
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS"},{"location":"user-guides/zli/#downloading-zli-binaries","title":"Downloading zli binaries","text":"
You can download the executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.
The binary image is named using the OS and architecture from the Supported platforms table. For example, the binary for an Intel-based MacOS server is zli-darwin-amd64.
"},{"location":"user-guides/zli/#building-zli-from-source","title":"Building zli from source","text":"
To build the zli binary, copy or clone the zot project from GitHub and execute the make cli command in the zot directory. Use the same command options that you used to build zot, as shown:
make OS=os ARCH=architecture cli
For example, the following command builds zli for an Intel-based MacOS server:
make OS=darwin ARCH=amd64 cli\n
In this example, the resulting executable file is zli-darwin-amd64 in the zot/bin directory.
"},{"location":"user-guides/zli/#common-tasks-using-zli","title":"Common tasks using zli","text":"
This section includes examples of common zot server tasks using the zli command line interface. For a detailed listing of zli commands, see the zli Command Reference in this guide.
The original filename of the zli executable file will reflect the build options, such as zli-linux-amd64. For convenience, you can rename the executable to simply zli. The instructions and examples in this guide use zli as the name of the executable file.
"},{"location":"user-guides/zli/#adding-a-zot-server-url","title":"Adding a zot server URL","text":"
You can modify the zot server configuration using the zli config add command. This example adds a zot server URL with an alias of remote-zot:
You can list all images hosted on a zot server using the zli image list command with the server\u2019s alias:
$ bin/zli image list --config local\n\nREPOSITORY TAG OS/ARCH DIGEST SIGNED SIZE \nalpine latest linux/amd64 3fc10231 false 84MB \nbusybox latest linux/amd64 9172c5f6 false 2.2MB\n
You can also filter the image list to view a specific image by specifying the image name:
$ bin/zli image name busybox:latest --config local\n\nREPOSITORY TAG OS/ARCH DIGEST SIGNED SIZE \nbusybox latest linux/amd64 9172c5f6 false 2.2MB\n
"},{"location":"user-guides/zli/#scanning-images-for-known-vulnerabilities","title":"Scanning images for known vulnerabilities","text":"
Using the zli cve list command, you can fetch the CVE (Common Vulnerabilities and Exposures) information for images hosted on the zot server. This example shows how to learn which images are affected by a specific CVE:
$ bin/zli cve affected CVE-2017-9935 --config remote-zot\n\nIMAGE NAME TAG DIGEST SIZE\nc3/openjdk-dev commit-5be4d92 ac3762e2 335MB\n
This example displays a list of all CVEs affecting a specific image:
$ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot\n\nID SEVERITY TITLE\nCVE-2015-8540 LOW libpng: underflow read in png_check_keyword()\nCVE-2017-16826 LOW binutils: Invalid memory access in the coff_s...\n
This example (--verbose) displays a list of all CVEs affecting a specific image with details:
$ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot --verbose\nLOW 2, UNKNOWN 1, TOTAL 3\n\nCVE-2015-8540\n...\n
Note that the details may display the package path in the image when the information is available.
This example displays the detailed CVEs in JSON format:
$ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot -f json\n{\n \"Tag\": \"0.3.19\",\n \"CVEList\": [\n {\n \"Id\": \"CVE-2019-17006\",\n \"Severity\": \"MEDIUM\",\n \"Title\": \"nss: Check length of inputs for cryptographic primitives\",\n \"Description\": \"A vulnerability was discovered in nss where input text length was not checked when using certain cryptographic primitives. This could lead to a heap-buffer overflow resulting in a crash and data leak. The highest threat is to confidentiality and integrity of data as well as system availability.\",\n \"PackageList\": [\n {\n \"Name\": \"nss\",\n \"InstalledVersion\": \"3.44.0-7.el7_7\",\n \"FixedVersion\": \"Not Specified\"\n },\n {\n \"Name\": \"nss-sysinit\",\n \"InstalledVersion\": \"3.44.0-7.el7_7\",\n \"FixedVersion\": \"Not Specified\"\n },\n {\n \"Name\": \"nss-tools\",\n \"InstalledVersion\": \"3.44.0-7.el7_7\",\n \"FixedVersion\": \"Not Specified\"\n }]\n }]\n}\n
This example lists all images on a specific zot server that are affected by a specific CVE:
$ bin/zli cve affected --config remote-zot CVE-2017-9935 --repo c3/openjdk-dev\n\nIMAGE NAME TAG DIGEST SIZE\nc3/openjdk-dev commit-2674e8a 71046748 338MB\nc3/openjdk-dev commit-bd5cc94 0ab7fc76\n
This example lists all images on a specific zot server where the CVE has been fixed:
$ bin/zli cve fixed c3/openjdk-dev CVE-2017-9935 --config remote-zot\n\nIMAGE NAME TAG DIGEST SIZE\nc3/openjdk-dev commit-2674e8a-squashfs b545b8ba 321MB\nc3/openjdk-dev commit-d5024ec-squashfs cd45f8cf 321MB\n
This example lists all CVEs that have been found in one image and not the other:
$ bin/zli cve diff c3/openjdk-dev:1.0.0 c3/openjdk-dev:2.0.0 --config remote-zot\n\nID SEVERITY TITLE\nCVE-2015-8540 LOW libpng: underflow read in png_check_keyword()\nCVE-2017-16826 LOW binutils: Invalid memory access in the coff_s...\n
For example, the above query lists all CVEs that have been found in c3/openjdk-dev:1.0.0 but not in c3/openjdk-dev:2.0.0
"},{"location":"user-guides/zli/#searching-for-repositories-and-images","title":"Searching for repositories and images","text":"
You can locate repositories and images hosted on a zot server using the zli search command.
To search for a repository, specify the full name with a colon or a partial name with no colon.
To search for an image, specify the full repository name followed by the tag or a prefix of the tag.
This example searches the zot registry named 'local' for a repository whose name contains the substring 'ng':
$ bin/zli search query ng --config local\n\nNAME SIZE LAST UPDATED DOWNLOADS STARS\nnginx 794MB 2023-03-01 18:44:17.707690369 +0000 UTC 0 0\nmongo 232MB 2022-10-18 15:03:40.7646203 +0300 +0300 0 0\ngolang 1.1GB 2023-06-22 00:32:38.613354854 +0000 UTC 0 0\n
This example searches the zot registry named 'local' for a repository named 'nginx'. Because the repository name is followed by a colon, the search results must match the name exactly.
"},{"location":"user-guides/zli/#sorting-the-output-of-a-zli-command","title":"Sorting the output of a zli command","text":"
For a zli command that can result in a lengthy output list, you can use the command flag --sort-by <option> to cause the output to be sorted by a specified property of the output data. The available sorting criteria vary for different commands, but examples of sorting criteria options are described in the following table:
flag option criteria alpha-asc alphabetical, ascending alpha-dsc alphabetical, descending relevance quality of match severity severity of condition update-time timestamp
For a given command that results in an output list, you can see the available sorting criteria in the usage information returned by the --help flag. For example, bin/zli image name --help returns usage information containing the following line under \"Flags\":
--sort-by string Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default \"alpha-asc\")
According to this information, the list of image names returned by the bin/zli image name command can be sorted in order of alphabetical ascending, alphabetical descending, or the timestamp of the latest update of the image. The default sorting method for this command, if no --sort-by flag is present, is alphabetical ascending.
This section provides detailed usage information for basic first-level zli commands. Many zli commands also support subcommands, which are listed as \"Available Commands\" in each command description. For example, zli search can be extended with either the query or subject subcommand. To see the detailed usage for each subcommand, type the command with the subcommand and append --help, such as zli search query --help. The zli search description below includes the subcommand help as an example.
$ bin/zli --help\n\nUsage:\n zli [flags]\n zli [command]\n\nAvailable Commands:\n completion Generate the autocompletion script for the specified shell\n config Configure zot registry parameters for CLI\n cve Lookup CVEs in images hosted on the zot registry\n help Help about any command\n image List images hosted on the zot registry\n repo List all repositories\n search Search images and their tags\n\nFlags:\n -h, --help help for zli\n -v, --version show the version and exit\n\nUse \"zli [command] --help\" for more information about a command.\n
This command generates the autocompletion script for zli for the specified shell. See each subcommand\u2019s help for details on how to use the generated script.
$ bin/zli completion --help\n\nUsage:\n zli completion [command]\n\nAvailable Commands:\n bash Generate the autocompletion script for bash\n fish Generate the autocompletion script for fish\n powershell Generate the autocompletion script for powershell\n zsh Generate the autocompletion script for zsh\n\nFlags:\n -h, --help help for completion\n\nUse \"zli completion [command] --help\" for more information about a command.\n
This command configures zot registry parameters for CLI.
$ bin/zli config --help\n\nUsage:\n zli config <config-name> [variable] [value] [flags]\n zli config [command]\n\nExamples:\n zli config add main https://zot-foo.com:8080\n zli config --list\n zli config main url\n zli config main --list\n zli config remove main\n\nAvailable Commands:\n add Add configuration for a zot registry\n remove Remove configuration for a zot registry\n\nFlags:\n -h, --help help for config\n -l, --list List configurations\n --reset Reset a variable value\n\nUse \"zli config [command] --help\" for more information about a command.\n\nUseful variables:\n url zot server URL\n showspinner show spinner while loading data [true/false]\n verify-tls enable TLS certificate verification of the server [default: true]\n
This command lists CVEs (Common Vulnerabilities and Exposures) of images hosted on the zot registry
$ ./zli cve --help\n\nUsage:\n zli cve [command]\n\nAvailable Commands:\n affected List images affected by a CVE\n fixed List tags where a CVE is fixedRetryWithContext\n list List CVEs by REPO:TAG or REPO@DIGEST\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n -h, --help help for cve\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nUse \"zli cve [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
This command lists images hosted on the zot registry.
$ ./zli image --help\n\nUsage:\n zli image [command]\n\nAvailable Commands:\n base List images that are base for the given image\n cve List all CVE's of the image\n derived List images that are derived from given image\n digest List images that contain a blob(manifest, config or layer) with the given digest\n list List all images\n name List image details by name\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n -h, --help help for image\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nUse \"zli image [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
This command lists all repositories in the zot registry.
$ ./zli repo --help\n\nUsage:\n zli repo [command]\n\nAvailable Commands:\n list List all repositories\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -h, --help help for repo\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n\nUse \"zli repo [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
The search command allows smart searching for a repository by its name or for an image by its repo:tag.
$ ./zli search --help\n\nSearch repos or images\n\nUsage:\n zli search [command]\n\nAvailable Commands:\n query Fuzzy search for repos and their tags.\n subject List all referrers for this subject.\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n -h, --help help for search\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nUse \"zli search [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
$ ./zli search query --help\n\nUsage:\n zli search query [repo]|[repo:tag] [flags]\n\nExamples:\n# For repo search specify a substring of the repo name without the tag\n zli search query \"test/repo\"\n\n# For image search specify the full repo name followed by the tag or a prefix of the tag.\n zli search query \"test/repo:2.1.\"\n\nFlags:\n -h, --help help for query\n --sort-by string Options for sorting the output: [relevance, update-time, alpha-asc, alpha-dsc] (default \"relevance\")\n\nGlobal Flags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nRun 'zli config -h' for details on [config-name] argument\n
$ ./zli search subject --help\n\nList all referrers for this subject. The subject can be specified by tag(repo:tag) or by digest\" or (repo@digest)\n\nUsage:\n zli search subject [repo:tag]|[repo@digest] [flags]\n\nExamples:\n# For referrers search specify the referred subject using it's full digest or tag:\n zli search subject \"repo@sha256:f9a0981...\"\n zli search subject \"repo:tag\"\n\nFlags:\n -h, --help help for subject\n --sort-by string Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default \"alpha-asc\")\n\nGlobal Flags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nRun 'zli config -h' for details on [config-name] argument\n
"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"admin-guide/admin-configuration/","title":"Configuring zot","text":"
The registry administrator configures zot primarily through settings in the configuration file.
Using the information in this guide, you can compose a configuration file with the settings and features you require for your zot registry server.
Before launching zot with a new configuration, we recommend that you verify the syntax of your configuration as described in Verifying the configuration file.
The configuration file is a JSON or YAML file that contains all configuration settings for zot functions such as:
network
storage
authentication
authorization
logging
metrics
synchronization with other registries
clustering
The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:
zot serve config.json
The instructions and examples in this guide use zot as the name of the zot executable file. The examples do not include the path to the executable file.
When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. This initial file is similar to the following example:
The configuration file contains the Distribution Specification version (distSpecVersion). The structure and content of other attributes are described in the later sections of this guide.
Additional registry features that are not a part of the Distribution Specification are allowed to be added as Extensions.
With a full (not minimal) zot image, the following extension features can be enabled and configured under an extensions attribute in the configuration file as shown in the following example.
The extension features are available only with a full zot image. With a minimal zot image, the extensions section is ignored if present.
The following features are configured under the extensions attribute.
Metrics
Sync
Search
Scrub
Lint
ImageTrust
UI
An extension feature is usually enabled by the presence of the feature\u2019s attribute under extensions. An extension feature can then be disabled by either omitting the feature attribute or by including an enable attribute with a value of false.
Two API-only extensions, User Preferences and Mgmt, are not enabled or configured under the extensions section of the configuration file. These API-only extensions are enabled as follows:
Mgmt is enabled when the Search extension is enabled.
User Preferences is enabled when both the Search and UI extensions are enabled.
"},{"location":"admin-guide/admin-configuration/#enabling-and-disabling-extensions","title":"Enabling and disabling extensions","text":"
Following is an example of enabling or disabling a feature in the extensions section. The scrub feature is enabled in these two configurations:
New functionality can be added to the zot registry by developing custom extensions for integration into zot. For information about developing extensions, see Developing New Extensions.
The following table lists the configurable attributes.
Attribute Description address The IP address of the zot server. port The port number of the zot server. realm The security policy domain defined for the server. tls The included attributes in this section specify the Transport Layer Security (TLS) settings for the server. cert The path and filename of the server\u2019s SSL/TLS certificate. key The path and filename of the server\u2019s registry key."},{"location":"admin-guide/admin-configuration/#storage","title":"Storage","text":"
Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.
Filesystem storage is configured with the storage attribute in the zot configuration file, as shown in the following simple example.
With zot, you have the option to store your registry image files either in local filesystem storage or in cloud storage, such as an Amazon Simple Storage Service (S3) bucket.
zot can store and serve files from one or more local directories (folders). A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.
Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.
Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.
Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.
Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.
After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. The zot configuration model allows for enabling and disabling garbage collection (gc). The model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs.
The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.
For detailed information about configuring local or remote storage and storage features for your zot registry, see Storage Planning with zot.
"},{"location":"admin-guide/admin-configuration/#security-and-hardening","title":"Security and hardening","text":""},{"location":"admin-guide/admin-configuration/#authentication","title":"Authentication","text":"
zot supports authentication by the following methods:
TLS mutual authentication
Basic local authentication using an htpasswd file
LDAP authentication
Bearer (OAuth2) authentication using an HTTP Bearer token
For detailed information about configuring authentication for your zot registry, see User Authentication and Authorization with zot.
User identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific repository paths.
For detailed information about configuring access control policies for your zot registry, see User Authentication and Authorization with zot.
"},{"location":"admin-guide/admin-configuration/#preventing-automated-attacks-with-failure-delay","title":"Preventing automated attacks with failure delay","text":"
Use the auth and failDelay attributes under http in the configuration file to delay the response to an authentication failure. A delayed response helps to prevent automated attacks. The configuration is shown in the following example.
The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.
In this example, the Rate attribute directly under Ratelimit sets a global rate limit of ten API calls per second. You can optionally override the global limit for specific API Methods. In this example, API GET calls are limited to five per second.
zot supports a range of monitoring tools including the following:
Logging
Logging for zot operations is configured with the log attribute in the configuration file.
Metrics
Metrics data is available in a Prometheus format. A full zot image with extensions includes a node exporter. A minimal zot image can use an external node exporter such as zxp.
Benchmarking
The zot project includes the zb tool, which allows you to benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification.
Performance profiling
Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.
When zot is deployed in a Kubernetes setup, a site reliability engineering (SRE) operator can monitor service level indicators (SLI) such as metrics and logs. Metrics will appear in Prometheus using the zot metrics extension, while logs will appear in the Elasticsearch stack (ELK stack) using Filebeat.
For detailed information about the monitoring tools, see Monitoring the registry.
For detailed information about benchmarking, see Benchmarking zot with zb.
For detailed information about performance profiling, see Performance Profiling in zot.
To ensure high-availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a loadbalancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Loadbalancing across many zot replicas can also increase aggregate network throughput.
For detailed information about clustering with zot, see zot Clustering.
"},{"location":"admin-guide/admin-configuration/#syncing-and-mirroring-registries","title":"Syncing and mirroring registries","text":"
A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync extension feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Synchronization between registries can be implemented by periodic polling of the upstream registry or synchronization can occur on demand, when a user pulls an image from the downstream registry.
As with git, wherein every clone is a full repository, you can configure a local zot instance to be a full OCI mirror registry. This allows for a fully distributed disconnected container image build pipeline.
For detailed information about syncing and mirroring, see OCI Registry Mirroring With zot.
The following table lists the configurable attributes of the lint extension.
Attribute Description enable If this attribute is missing, incoming image linting is disabled by default. Linting can be enabled by including this attribute and setting it to true. mandatoryAnnotations A list of annotations that are required to be present in the image being pushed to the repository.
If the mandatory annotations option is configured when you push an image, linter will verify that the mandatory annotations list present in the configuration is also found in the manifest's annotations list. If any annotations are missing, the push is denied.
"},{"location":"admin-guide/admin-configuration/#verifying-the-signatures-of-uploaded-images","title":"Verifying the signatures of uploaded images","text":"
The trust extension provides a mechanism to verify image signatures using certificates and public keys.
To enable image signature verification, you must add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:
You must also upload public keys (for cosign) or certificates (for notation) that can be used to verify the image signatures.
For detailed information about configuring image signature verification, see Verifying image signatures.
"},{"location":"admin-guide/admin-configuration/#enabling-the-registrys-graphical-user-interface","title":"Enabling the registry's graphical user interface","text":"
Using the zot graphical user interface (GUI), a user can browse a zot registry for container images and artifacts.
To configure zot's GUI, add the ui attribute under extensions in the configuration file, as shown in the following example:
The following table lists the configurable attributes of the ui extension.
Attribute Description enable If this attribute is missing, the zot GUI is disabled by default. The GUI can be enabled by including this attribute and setting it to true."},{"location":"admin-guide/admin-configuration/#scrubbing-the-image-registry","title":"Scrubbing the image registry","text":"
To check the integrity of the filesystem and the data in the registry, you can schedule a periodic scrub operation. The scrub process traverses the filesystem, verifying that all data blocks are readable. While running, the process may slightly reduce the registry performance.
To enable scrubbing, add the scrub attribute under extensions in the configuration file, as shown in the following example:
The following table lists the configurable attributes for scrubbing the registry.
Attribute Description enable If this attribute is missing, registry scrubbing is enabled by default. Scrubbing can be disabled by setting this attribute to false. interval The time interval between periodic scrub operations. This value must be at least two hours (2h)."},{"location":"admin-guide/admin-configuration/#scheduling-background-tasks","title":"Scheduling background tasks","text":"
Some zot functions, such as garbage collection and registry synchronization, run as background tasks. These tasks are queued and executed by the scheduler.
The scheduler is by default allowed to simultaneously run a maximum number of tasks equal to four times the number of CPUs available to the zot process. For most users, there should be no need to modify this maximum number. If such a need arises, you can configure a new maximum number of simultaneous tasks in the numWorkers property of the scheduler attribute in the configuration file, as shown in the following example.
"},{"location":"admin-guide/admin-configuration/#enhanced-searching-and-querying-images","title":"Enhanced searching and querying images","text":"
While basic searching is always enabled for images in the zot registry, you can enable enhanced registry searching and filtering using graphQL.
Add the search attribute under extensions in the configuration file to enable and configure the enhanced search extension, as shown in the following example.
The following table lists the configurable attributes for enhanced search.
Attribute Description enable If this attribute is missing, enhanced search is enabled by default. Enhanced search can be disabled by setting this attribute to false. cve Extends enhanced search to allow searching of Common Vulnerabilities and Exposures (CVE). updateInterval Sets the interval at which the searchable database of CVE items is refreshed."},{"location":"admin-guide/admin-configuration/#setting-user-preferences","title":"Setting user preferences","text":"
The user preferences extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.
The user preferences extension is enabled by default when the search and ui extensions are enabled. There are no other configuration file fields for this extension.
A userprefs API endpoint accepts as a query parameter an action to perform along with any other required parameters for the specified action. The actions currently implemented do not require an HTTP payload, nor do they return any related data other than an HTTP response code.
"},{"location":"admin-guide/admin-configuration/#verifying-the-configuration-file","title":"Verifying the configuration file","text":"
Before launching zot, verify the syntax of your configuration file using the following command:
zot verify <configfile>
Verifying the configuration file protects against operator errors and any conflicts arising from zot release version changes.
After verifying your configuration file, you can launch zot with the following command:
zot serve <configfile>
"},{"location":"admin-guide/admin-getting-started/","title":"Getting Started with zot Administration","text":"
This document helps you to deploy an appropriate zot image or to build zot if desired.
After deploying zot, proceed to Configuring zot to choose and configure the features you need.
"},{"location":"admin-guide/admin-getting-started/#installing-zot","title":"Installing zot","text":""},{"location":"admin-guide/admin-getting-started/#how-to-get-zot","title":"How to get zot","text":"
The zot project is hosted on GitHub at project-zot. From GitHub, you can download zot executable binary images or full source code.
zot is officially supported on Linux and Apple MacOS platforms, using Intel or ARM processors. However, development should be possible on any platform that supports the golang toolchain.
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS freebsd amd64 Intel-based FreeBSD* freebsd arm64 ARM-based FreeBSD*
* NOTE: While binary images are available for FreeBSD, building container images is not supported at this time.
Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.
Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.
You can launch a zot binary as a container service using a container management tool such as Podman, Docker, or Helm.
You can launch zot as a host-level service by downloading a binary image and running it as a systemd service.
You can copy or clone the full zot source code and build an image with custom build flags.
"},{"location":"admin-guide/admin-getting-started/#deploying-a-zot-binary-image","title":"Deploying a zot binary image","text":"
Executable binary images for supported server platforms and architectures are available from the zot package repository in GitHub.
You can download the appropriate binary image and run it directly on your server, or you can use a container management tool such as Podman, runc, Helm, or Docker to fetch and deploy the image in a container on your server.
For convenience, you can rename the binary image file to simply zot.
"},{"location":"admin-guide/admin-getting-started/#example-deploying-with-a-container-manager","title":"Example: Deploying with a container manager","text":"
Using a container manager such as Podman, runc, Helm, or Docker, you can install a zot binary image, as in the following examples.
Using podman
podman run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest\n\npodman run -p 5000:5000 ghcr.io/project-zot/zot-minimal-linux-amd64:latest\n
Click here to view an example of deploying using podman.
Using docker
docker run -p 5000:5000 ghcr.io/project-zot/zot-linux-amd64:latest\n
Each of these example commands pulls a zot binary image from the GitHub Container Registry (ghcr.io) and launches a zot image registry at http://localhost:5000.
Click here to view an example of deploying using docker.
"},{"location":"admin-guide/admin-getting-started/#building-zot-from-source","title":"Building zot from source","text":""},{"location":"admin-guide/admin-getting-started/#prerequisites","title":"Prerequisites","text":""},{"location":"admin-guide/admin-getting-started/#install-golang","title":"Install golang","text":"
Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.
You must use a golang version of at least the minimum specified in go.mod or the build will fail.
"},{"location":"admin-guide/admin-getting-started/#building-an-executable-binary-from-source","title":"Building an executable binary from source","text":"
Download or clone the full zot project from GitHub at project-zot. To clone the zot project from GitHub, use this command:
To build zot, execute the make command in the zot directory using the following general syntax:
make OS=os ARCH=architecture {binary | binary-minimal}
The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.
The binary option builds the full zot binary image with all extensions.
The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.
For example, to build a zot image with extensions for an Intel-based linux server, use the following command:
make OS=linux ARCH=amd64 binary\n
The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-linux-amd64-minimal.
For convenience, you can rename the binary image file to simply zot.
"},{"location":"admin-guide/admin-getting-started/#building-a-zot-container-image-from-source","title":"Building a zot container image from source","text":"
with Stacker
Using the settings in stacker.yaml, you can build a container image that runs the latest zot by running the following command:
make binary-stacker\n
with Docker
A sample Dockerfile is provided on the zot project page in GitHub. You can edit the sample file with your specific values, such as the desired operating system, hardware architecture, and full or minimal build, as in this example:
ARG OS=linux\nARG ARCH=amd64\n\nRUN make COMMIT=$COMMIT OS=$OS ARCH=$ARCH clean binary-minimal\n
Using your edited Dockerfile, you can build a container image that runs the latest zot by running the following command:
make image\n
"},{"location":"admin-guide/admin-getting-started/#deploying-the-container-image","title":"Deploying the container image","text":"
Deploy the image using your container manager, such as Podman, runc, Helm, or Docker, as in these examples:
with Podman
podman run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest\n
with Docker
docker run --rm -it -p 5000:5000 -v $(pwd)/registry:/var/lib/registry zot:latest\n
A container image built with the sample Dockerfile and deployed with the example command results in a running registry at http://localhost:5000. Registry content is stored at .registry, which is bind mounted to /var/lib/registry in the container. By default, auth is disabled. As part of the build, a YAML configuration file is created at /etc/zot/config.yml in the container.
You can override the configuration file with custom configuration settings in the deployment command and in a local configuration file as shown in this example:
The zot service is initiated with the zot serve command followed by the name of a configuration file, as in this example:
zot serve config.yml
For convenience, you can rename the binary image file to simply zot.The instructions and examples in this guide use zot as the name of the zot executable file and do not include the path to the executable file.
You configure zot primarily through adding and modifying settings in the zot configuration file. The configuration file is a JSON or YAML file that contains all configuration settings for zot functions.
When you first build zot or deploy an image or container from the distribution, a basic configuration file config.json is created. You can modify the initial file or you can create a new file.
Follow the instructions in Configuring zot, to compose a configuration file with the settings and features you require for your zot registry server.
"},{"location":"articles/authn-authz/","title":"User Authentication and Authorization with zot","text":"
A robust set of authentication/authorization options are supported:
Authentication
TLS, including mTLS
Username/password or token-based user authentication
LDAP
htpasswd
OAuth2 with bearer token
Authorization
Powerful identity-based access controls for repositories or specific repository paths
OpenID/OAuth2 social login with Google, GitHub, GitLab, and dex
The zot configuration model supports both authentication and authorization. Authentication credentials allow access to zot HTTP APIs. Authorization policies provide fine-grained control of the actions each authenticated user can perform in the registry.
Because authentication credentials are passed over HTTP, it is imperative that TLS be enabled. You can enable and configure TLS authentication in the zot configuration file, as shown in the following example.
When basic HTTP authentication is used, the username and password credentials are joined by a colon (:), base64 encoded, and passed in the HTTP Authorization header.
To avoid passing the username and password credentials for every HTTP request, a zot client can use bearer token-based authentication. In this method, the client first authenticates with a token server and receives a short-lived token. The client then passes this token in the HTTP Authorization header, specifying Bearer as the authentication scheme.
Configure bearer authentication in the zot configuration file as shown in this example.
The following table lists the configurable attributes.
Attribute Description realm A string typically related to the authentication scheme (BASIC and BEARER). service The name of the authentication service. cert The path and filename of the server\u2019s SSL/TLS certificate."},{"location":"articles/authn-authz/#mutual-tls-authentication","title":"Mutual TLS authentication","text":"
zot supports basic TLS and password-less mutual TLS authentication (mTLS). Specifying a cacert file in the TLS section of the zot configuration file enables mTLS. The cacert parameter is used to validate the client-side TLS certificates.
The following table lists the configurable attributes.
Attribute Description cert The path and filename of the server\u2019s SSL/TLS certificate. key The path and filename of the server\u2019s registry key. cacert The path and filename of the server\u2019s cacerts file, which contains trusted certificate authority (CA) certificates."},{"location":"articles/authn-authz/#preventing-automated-attacks-with-failure-delay","title":"Preventing automated attacks with failure delay","text":"
To help prevent automated attacks, you can add a delayed response to an authentication failure. Configure the failDelay attribute in the configuration file as shown in the following example.
The failDelay attribute specifies a waiting time, in seconds, before zot sends a failure notification to an authenticating user who has been denied access.
You can implement server-side authentication for zot using htpasswd or LDAP or both.
When both htpasswd and LDAP configuration are specified, LDAP authentication is given preference. Because htpasswd authentication is strictly local and requires no remote service, htpasswd serves as a fail-safe authentication mechanism should LDAP become unavailable.
zot supports integration with an LDAP-based authentication service such as Microsoft Windows Active Directory (AD). Enable and configure LDAP authentication in the zot configuration file, as shown in the following example.
The following table lists the configurable attributes for LDAP authentication.
Attribute Description credentialsFile The path to a file containing the bind credentials for LDAP. address The IP address or hostname of the LDAP server. port The port number used by the LDAP service. startTLS Set to true to enable TLS communication with the LDAP server. baseDN Starting location within the LDAP directory for performing user searches. userAttribute Attribute name used to obtain the username. userGroupAttribute Attribute name used to obtain groups to which a user belongs. skipVerify Skip TLS verification. subtreeSearch Set to true to expand the scope for search to include subtrees of the base DN.
To allow for separation of configuration and credentials, the credentials for the LDAP server are specified in a separate file, as shown in the following example.
The following table lists the configurable attributes of the LDAP credentials file.
Attribute Description bindDN Base Distinguished Name for the LDAP search. bindPassword Password of the bind LDAP user."},{"location":"articles/authn-authz/#htpasswd","title":"htpasswd","text":"
Enable and configure htpasswd authentication in the zot configuration file, as shown in the following example.
For strong security, make sure to use the -B option, specifying the bcrypt hashing algorithm. This is the only algorithm supported by zot for htpasswd.
Enable htpasswd authentication and configure the path to the htpasswd authentication in the zot configuration file.
With an access scheme that relies solely on authentication, any authenticated user would be given complete access to the registry. To better control access, zot supports identity-based repository-level access control (authorization) policies. The access control policy is a function of repository, user, and the action being performed on that repository.
"},{"location":"articles/authn-authz/#access-control-policies","title":"Access control policies","text":"
Five identity-based types of access control policies are supported:
Policy type Attribute Access allowed Default defaultPolicy The default policy specifies what actions are allowed if a user is authenticated but does match any user-specific policy. User-specific users, actions A user-specific policy specifies access and actions for explicitly named users. Group-specific groups, actions A group-specific policy specifies access and actions for explicitly named groups. Anonymous anonymousPolicy An anonymous policy specifies what an unauthenticated user is allowed to do. This is an appropriate policy when you want to grant open read-only access to one or more repositories. Admin adminPolicy The admin policy is a global access control policy that grants privileges to perform actions on any repository.
Access control is organized by repositories, users, and their actions. Most users of a particular repository will have similar access control requirements and can be served by a repository-specific defaultPolicy. Should a user require an exception to the default policy, a user-specific or group-specific override policy can be configured.
With an anonymousPolicy, a repository can allow anonymous actions which do not require user authentication. Finally, one or more users can be designated as administrators, to whom the global adminPolicy applies.
A user's access to a particular repository is evaluated first by whether a user-specific policy exists, then by group-specific policies, and then (in order) by default and admin policies.
A group-specific policy can be applied within any type of access policy, including default or admin policies. The group policy name can also be used with LDAP.
User identity or group identity can be used as an authorization criterion for allowing actions on one or more repository paths. For specific users, you can choose to allow any combination of read, create, update, or delete actions on specific paths.
When you define policies for specific repository paths, the paths can be specified explicitly or by using glob patterns with simple or recursive wildcards. When a repository path matches more than one path description, authorization is granted based on the policy of the longest (most specific) path matched. For example, if policies are defined for path descriptions ** and repos2/repo, the repos2/repo path will match both ** and repos2/repo descriptions. In this case, the repos2/repo policy will be applied because it is longer.
Note that ** effectively defines the default policy, as it matches any path not matched by any other per-repository policy. To override all other policies, you can specify a global admin policy.
Always include the read action in any policy that you define. The create, update, and delete actions cannot be used without the read action.
"},{"location":"articles/authn-authz/#example-access-control-configuration","title":"Example: Access control configuration","text":"
Use the accessControl attribute in the configuration file to define a set of identity-based authorization policies, as shown in the following example.
The default policy (**) gives all authenticated users the ability to read or create content, while giving user \"charlie\" and those in \"group2\" the additional ability to update content.
The policy for tmp/** matches all repositories under tmp recursively and allows all authenticated users to read, create, or update content in those repositories. Unauthenticated users have read-only access to these repositories.
The policy for infra/* matches all repositories directly under infra. Separate policies are defined for specific users, along with a default read-only policy for all other users.
The policy for repos2/repo matches only that specific repository.
An admin policy (adminPolicy) gives the user \"admin\" global authorization to read, create, update, or delete content in any repository, overriding all other policies.
In releases prior to zot v2.0.0, authorization policies were defined directly under the accessControl key in the zot configuration file. Beginning with v2.0.0, the set of authorization policies are now defined under a new repositories key.
"},{"location":"articles/authn-authz/#social-login-using-openidoauth2","title":"Social login using OpenID/OAuth2","text":"
Social login is an authentication/authorization method in which your existing credentials for another site or service can be used to log in to a service such as zot. For example, you can log in to zot using your GitHub account credentials, and zot will contact GitHub to verify your identity using OAuth 2.0 and OpenID Connect (OIDC) protocols.
Several social login providers are supported by zot:
github
google
gitlab
oidc (for example, dex)
The following example shows the zot configuration for these providers:
"},{"location":"articles/authn-authz/#using-google-github-or-gitlab","title":"Using Google, GitHub, or GitLab","text":"
A client logging into zot by social login must specify a supported OpenID/OAuth2 provider as a URL query parameter. A client logging in using Google, GitHub, or GitLab must additionally specify a callback URL for redirection to a zot page after a successful authentication.
The login URL using Google, GitHub, or GitLab uses the following format:
dex is an identity service that uses OpenID Connect (OIDC) to drive authentication for client apps, such as zot. While this section shows how to use dex with zot, zot supports other OIDC services as well.
Like zot, dex uses a configuration file for setup. To specify zot as a client in dex, configure a staticClients entry in the dex configuration file with a zot callback, such as the following example in the dex configuration file:
For detailed information about configuring dex service, see the dex Getting Started documentation.
"},{"location":"articles/authn-authz/#using-openidoauth2-when-zot-is-behind-a-proxy-or-load-balancer","title":"Using OpenID/OAuth2 when zot is behind a proxy or load balancer","text":"
When the zot registry is running behind a proxy or load balancer, you must provide an external URL for OpenID/OAuth2 clients to redirect back to zot. This externalUrl attribute is the URL of the registry, as shown in this example:
"},{"location":"articles/benchmarking-with-zb/","title":"Benchmarking zot with zb","text":"
The zb tool is useful for benchmarking OCI registry workloads in scenarios such as the following:
comparing configuration changes
comparing software versions
comparing hardware/deployment environments
comparing with other registries
With the zb tool, you can benchmark a zot registry or any other container image registry that conforms to the OCI Distribution Specification published by the Open Container Initiative (OCI).
We recommend installing and benchmarking with zb when you install zot.
"},{"location":"articles/benchmarking-with-zb/#how-to-get-zb","title":"How to get zb","text":"
The zb project is hosted with zot on GitHub at project-zot. From GitHub, you can download the zb binary or you can build zb from the source. You can also directly run the released docker image.
"},{"location":"articles/benchmarking-with-zb/#supported-platforms-and-architectures","title":"Supported platforms and architectures","text":"
zb is supported for the following operating systems and platform architectures:
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS"},{"location":"articles/benchmarking-with-zb/#downloading-zb-binaries","title":"Downloading zb binaries","text":"
Download the executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.
The binary image is named using the target platform and architecture from the Supported platforms and architectures table. For example, the binary for an Intel-based MacOS server is zb-darwin-amd64.
"},{"location":"articles/benchmarking-with-zb/#building-zb-from-source","title":"Building zb from source","text":"
To build the zb binary, copy or clone the zot project from GitHub and execute the make bench command in the zot directory. Use the same command options that you used to build zot, as shown:
make OS=os ARCH=architecture bench
For example, the following command builds zb for an Intel-based MacOS server:
make OS=darwin ARCH=amd64 bench
In this example, the resulting executable file is zb-darwin-amd64 in the zot/bin directory.
A sample Dockerfile for zb is available at Dockerfile-zb.
The original filename of the executable file will reflect the build options, such as zb-linux-amd64. For convenience, you can rename the executable to simply zb.
The instructions and examples in this guide use zb as the name of the executable file.
To view the usage and options of zb, run the command with the --help option:
bin/zb --help
Command output:
Usage:\n zb <url> [flags]\n\n Flags:\n -A, --auth-creds string \u00a0 \u00a0 \u00a0Use colon-separated BASIC auth creds\n -c, --concurrency int \u00a0 \u00a0 \u00a0 \u00a0Number of multiple requests to make at a time (default 1)\n \u00a0 -h, --help \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 help for zb\n \u00a0 -o, --output-format string \u00a0 Output format of test results: stdout (default), json, ci-cd\n \u00a0 -r, --repo string \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Use specified repo on remote registry for test data\n \u00a0 -n, --requests int \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Number of requests to perform (default 1)\n \u00a0 -s, --src-cidr string \u00a0 \u00a0 \u00a0 \u00a0Use specified cidr to obtain ips to make requests from, src-ips and src-cidr are mutually exclusive\n \u00a0 -i, --src-ips string \u00a0 \u00a0 \u00a0 \u00a0 Use colon-separated ips to make requests from, src-ips and src-cidr are mutually exclusive\n \u00a0 -v, --version \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0Show the version and exit\n \u00a0 -d, --working-dir string \u00a0 \u00a0 Use specified directory to store test data\n
Registry URL: http://localhost:8080\n\n Concurrency Level: 2\n Total requests: 100\n Working dir:\n\n ========\n Test name: Get Catalog\n Time taken for tests: 45.397205ms\n Complete requests: 100\n Failed requests: 0\n Requests per second: 2202.7788\n\n 2xx responses: 100\n\n min: 402.259\u00b5s\n max: 3.295887ms\n p50: 855.045\u00b5s\n p75: 971.709\u00b5s\n p90: 1.127389ms\n p99: 3.295887ms\n\n ========\n Test name: Push Monolith 1MB\n Time taken for tests: 952.336383ms\n Complete requests: 100\n Failed requests: 0\n Requests per second: 105.00491\n\n 2xx responses: 100\n\n min: 11.125673ms\n max: 26.375356ms\n p50: 18.917253ms\n p75: 21.753441ms\n p90: 24.02137ms\n p99: 26.375356ms\n\n ...\n
"},{"location":"articles/building-ci-cd-pipeline/","title":"Building an OCI-native Container Image CI/CD Pipeline","text":"
An OCI-native secure container image build/delivery pipeline using the following tools:
stacker for building OCI images
zot as a vendor-neutral OCI image registry server
skopeo for performing repository interactions
cosign for container signing and verification
cri-o for deploying container images
cosigned for validating container images before deployment
The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes.
This document describes a step-by-step procedure towards achieving an OCI-native secure software supply chain using zot in collaboration with other open source tools. The following diagram shows a portion of the CI/CD pipeline.
stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout.
zot is a production-ready vendor-neutral OCI image registry server purely based on the OCI Distribution Specification. If stacker is used to build the OCI image, it can also be used to publish the built image to an OCI registry.
cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes.
zot is compatible with kubernetes/cri-o using docker:// transport, which is the default.
High availability of the zot registry is supported by the following features:
Stateless zot instances to simplify scale out
Shared remote storage
Bare-metal and Kubernetes deployments
To ensure high availability of the registry, zot supports a clustering scheme with stateless zot instances/replicas fronted by a load balancer and a shared remote backend storage. This scheme allows the registry service to remain available even if a few replicas fail or become unavailable. Load balancing across many zot replicas can also increase aggregate network throughput.
Beginning with zot release v2.1.0, you can design a highly scalable cluster that does not require configuring the load balancer to direct repository queries to specific zot instances within the cluster. See Scale-out clustering. Scale-out clustering is the preferred method if you are running v2.1.0 or later.
Clustering is supported in both bare-metal and Kubernetes environments.
The remote backend storage must be S3 API-compatible.
In a stateless clustering scheme, the image data is stored in the remote storage backend and the registry cache is disabled by turning off deduplication.
The OCI Distribution Specification imposes certain rules about the HTTP URI paths to which various ecosystem tools must conform. Consider these rules when setting the HTTP prefixes during load balancing and ingress gateway configuration.
Clustering is supported by using multiple stateless zot replicas with shared S3 storage and an HAProxy (with sticky session) load balancing traffic to the replicas. Each replica is responsible for one or more repositories.
"},{"location":"articles/clustering/#haproxy-configuration","title":"HAProxy configuration","text":"Click here to view a sample HAProxy configuration.
"},{"location":"articles/clustering/#zot-s3-configuration","title":"zot S3 configuration","text":"Click here to view a sample zot configuration for S3.
"},{"location":"articles/graphql/","title":"Using GraphQL for Enhanced Searches","text":"
A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. You can submit a GraphQL structured query as an API call or you can use a browser to access the GraphQL Playground, an interactive graphical environment for GraphQL queries.
"},{"location":"articles/graphql/#how-to-use-graphql-for-search-queries","title":"How to use GraphQL for search queries","text":"
GraphQL is a query language for APIs. A GraphQL server, as implemented in zot's registry search engine, executes GraphQL queries that match schema recognized by the server. In response, the server returns a structure containing the requested information. The schema currently recognized by zot are those that correspond to the queries listed in What GraphQL queries are supported.
To learn more about GraphQL, see these resources:
Introduction to GraphQL
The Fullstack Tutorial for GraphQL
To perform a search, compose a GraphQL structured query for a specific search and deliver it to zot using one of the methods described in the following sections.
For examples of GraphQL queries supported in zot, see Examples of zot searches using GraphQL.
"},{"location":"articles/graphql/#using-the-search-api-directly","title":"Using the search API directly","text":"
You can submit a GraphQL structured query as the HTML data payload in a direct API call using a shell tool such as cURL or Postman. GraphQL queries are sent to the zot search extension API:
/v2/_zot/ext/search\n
The following example submits a zot GraphQL query using cURL:
In the GraphQL Playground, you can construct and submit a query structure and you can view the query response in a graphical environment in the browser. You can also inspect the schema.
"},{"location":"articles/graphql/#what-graphql-queries-are-supported","title":"What GraphQL queries are supported","text":"Supported queries graphQL query Input Output Description Search images by digest ImageListForDigest digest image list Searches all repositories in the registry and returns list of images that matches given digest (manifest, config or layers) Search images affected by a given CVE id CVEListForImage CVE id image list Searches the entire registry and returns list of images affected by given CVE List CVEs for a given image CVEListForImage image CVE list Scans given image and returns list of CVEs affecting the image List images not affected by a given CVE id ImagesListWithCVEFixed repository, CVE id image list Scans all images in a given repository and returns list of latest (by date) images not affected by the given CVE Latest image from all repos RepoListWithNewestImage none repo summary list Returns the latest image from all the repos in the registry List all images with expanded information for a given repository ExpandedRepoInfo repository repo info List expanded repo information for all images in repo, alongside a repo summary All images in repo ImageList repository image list Returns all images in the specified repo Global search GlobalSearch query image summary / repo summary / layer summary Will return what's requested in the query argument Derived image list DerivedImageList image image list Returns a list of images that depend on the image specified in the argument Base image list BaseImageList image image list Returns a list of images that the specified image depends on Get details of a specific image Image image image summary Returns details about a specific image Get referrers of a specific image Referrers repo, digest, type artifact manifests Returns a list of artifacts of given type referring to a specific repo and digests"},{"location":"articles/graphql/#examples-of-zot-searches-using-graphql","title":"Examples of zot searches using GraphQL","text":"
These examples show only the GraphQL query without details on how to send them to a server. See How to use GraphQL for search queries.
The query structures shown in these examples request all fields allowed by the schema for the particular query type. The schema allows you to request a subset of the data, if desired, omitting any fields that you don't need.
"},{"location":"articles/graphql/#list-cves-of-given-image","title":"List CVEs of given image","text":"
{\n \"data\": {\n \"CVEListForImage\": {\n \"Tag\": \"3.17\",\n \"Page\": {\n \"TotalCount\": 9,\n \"ItemCount\": 1\n },\n \"CVEList\": [\n {\n \"Id\": \"CVE-2023-5363\",\n \"Title\": \"openssl: Incorrect cipher key and IV length processing\",\n \"Description\": \"Issue summary: A bug has been identified in the processing of key and\\ninitialisation vector (IV) lengths. This can lead to potential truncation\\nor overruns during the initialisation of some symmetric ciphers.\\n\\nImpact summary: A truncation in the IV can result in non-uniqueness,\\nwhich could result in loss of confidentiality for some cipher modes.\\n\\nWhen calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or\\nEVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after\\nthe key and IV have been established. Any alterations to the key length,\\nvia the \\\"keylen\\\" parameter or the IV length, via the \\\"ivlen\\\" parameter,\\nwithin the OSSL_PARAM array will not take effect as intended, potentially\\ncausing truncation or overreading of these values. The following ciphers\\nand cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.\\n\\nFor the CCM, GCM and OCB cipher modes, truncation of the IV can result in\\nloss of confidentiality. For example, when following NIST's SP 800-38D\\nsection 8.2.1 guidance for constructing a deterministic IV for AES in\\nGCM mode, truncation of the counter portion could lead to IV reuse.\\n\\nBoth truncations and overruns of the key and overruns of the IV will\\nproduce incorrect results and could, in some cases, trigger a memory\\nexception. However, these issues are not currently assessed as security\\ncritical.\\n\\nChanging the key and/or IV lengths is not considered to be a common operation\\nand the vulnerable API was recently introduced. Furthermore it is likely that\\napplication developers will have spotted this problem during testing since\\ndecryption would fail unless both peers in the communication were similarly\\nvulnerable. For these reasons we expect the probability of an application being\\nvulnerable to this to be quite low. However if an application is vulnerable then\\nthis issue is considered very serious. For these reasons we have assessed this\\nissue as Moderate severity overall.\\n\\nThe OpenSSL SSL/TLS implementation is not affected by this issue.\\n\\nThe OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because\\nthe issue lies outside of the FIPS provider boundary.\\n\\nOpenSSL 3.1 and 3.0 are vulnerable to this issue.\",\n \"Severity\": \"HIGH\",\n \"PackageList\": [\n {\n \"Name\": \"libcrypto3\",\n \"InstalledVersion\": \"3.0.8-r0\",\n \"FixedVersion\": \"3.0.12-r0\"\n },\n {\n \"Name\": \"libssl3\",\n \"InstalledVersion\": \"3.0.8-r0\",\n \"FixedVersion\": \"3.0.12-r0\"\n }\n ]\n }\n ]\n }\n }\n}\n
"},{"location":"articles/graphql/#search-images-affected-by-a-given-cve-id","title":"Search images affected by a given CVE id","text":"
"},{"location":"articles/graphql/#list-all-images-with-expanded-information-for-a-given-repository","title":"List all images with expanded information for a given repository","text":"
{\n \"data\": {\n \"Image\": {\n \"RepoName\": \"mariadb\",\n \"Tag\": \"latest\",\n \"LastUpdated\": \"2022-10-18T14:56:33.1993083+03:00\",\n \"Digest\": \"sha256:49a299f5c4b1af5bc2aa6cf8e50ab5bad85db4d0095745369acfc1934ece99d0\",\n \"Description\": \"MariaDB Server is a high performing open source relational database, forked from MySQL.\"\n }\n }\n}\n
"},{"location":"articles/graphql/#get-referrers-of-a-specific-image","title":"Get referrers of a specific image","text":"
"},{"location":"articles/high-availability/","title":"Deploying a Highly Available zot Registry","text":"
A highly available zot registry can be easily implemented using zot's registry synchronization feature.
In the zot configuration, the sync extension allows a zot instance to mirror another zot instance with various container image download policies, including on-demand and periodic downloads. You can use the zot sync function combined with a load balancer such as HAProxy to implement a highly available registry.
Two failover configurations are possible:
Active/standby
Registry requests are sent by the load balancer to the active zot instance, while a standby instance mirrors the active. If the load balancer detects a failure of the active instance, it then sends requests to the standby instance.
Active/active
Registry requests are load-balanced between two zot instances, each of which mirrors the other.
The highly available zot registry described in this article differs from zot clustering. Although zot clustering provides a level of high availability, the instances share common storage, whose failure would affect all instances. In the method described in this article, each instance has its own storage, providing an additional level of safety.
For details of configuring the sync extension, see OCI Registry Mirroring With zot.
"},{"location":"articles/high-availability/#configuring-an-activestandby-registry","title":"Configuring an active/standby registry","text":"
An active/standby zot registry can be implemented between two zot instances by configuring the sync extension in the standby instance to mirror the other instance. In this scheme:
a load balancer such as HAProxy is deployed for active/passive load balancing of the zot instances
each zot instance is configured as a standalone registry with its own storage
the standby zot instance has its sync extension enabled to periodically synchronize with (mirror) the active instance
With periodic synchronization, a window of failure exists between synchronization actions. For example, if an image is posted to the active instance soon after the standby has synchronized with the active, and then the active fails, the standby will not have the new image. To minimize this exposure, we recommend keeping the synchronization period as small as practical.
"},{"location":"articles/high-availability/#configuring-an-activeactive-registry","title":"Configuring an active/active registry","text":"
An active/active zot registry can be implemented between two zot instances by configuring the sync extension in each instance to point to the other instance. In this scheme:
a load balancer such as HAProxy or a DNS-based routing scheme is deployed for load balancing between zot instances
path-based routing must be implemented
each zot instance is configured as a standalone registry with its own storage
each zot instance has its sync extension enabled to periodically synchronize with the other instance
With periodic synchronization, a window of failure exists between synchronization actions. For example, if an image is posted to instance A soon after instance B has synchronized with instance A, and then instance A fails, instance B will not have the new image. To minimize this exposure, we recommend keeping the synchronization period as small as practical.
Immutable image tag support is achieved by leveraging authorization policies.
It is considered best practice to avoid changing the content once a software version has been released. While zot does not have an explicit configuration flag to make image tags immutable, the same effect can be achieved with authorization as follows.
"},{"location":"articles/immutable-tags/#immutable-for-all-users","title":"Immutable For All Users","text":"
By setting the defaultPolicy to \"read\" and \"create\" for a particular repository, images can be pushed (once) and pulled but further updates are rejected.
"},{"location":"articles/immutable-tags/#immutable-with-overrides","title":"Immutable With Overrides","text":"
As in the example above, with defaultPolicy set to \"read\" and \"create\" for a particular repository, images can be pushed (once) and pulled, but further updates are rejected. Exceptions can be made for some users, and user-specific policies can be added to allow \"update\" operations as shown below.
"},{"location":"articles/kind-deploy/","title":"Using kind for Deployment Testing","text":"
Use kind to try out zot deployment with Kubernetes.
This article describes how to create a kind cluster that includes a local zot registry.
"},{"location":"articles/kind-deploy/#deploying-the-cluster-and-registry","title":"Deploying the cluster and registry","text":"
The procedure described installs a kind cluster with a zot registry at localhost:5001 and then loads and runs a \"hello\" app to test the installation. Although the procedure is given as a series of steps, you can find a complete shell script to perform these steps at the end of this article.
This article is based on Create A Cluster And Registry, which you can find on the kind website.
"},{"location":"articles/kind-deploy/#step-1-prepare-the-environment","title":"Step 1: Prepare the environment","text":"
The following packages must be installed:
docker
kubernetes
kind
containerd
skopeo
Execute the following shell commands to set environment variables.
set -o errexit\n\n# set no_proxy if applicable\nif [ ! -z \"${no_proxy}\" ]; then \n echo \"Updating no_proxy environment variables\";\n export no_proxy=${no_proxy},kind-registry;\n export NO_PROXY=${no_proxy};\nfi\n
"},{"location":"articles/kind-deploy/#step-2-create-a-registry-container","title":"Step 2: Create a registry container","text":"
Create a kind-registry container, pulling a zot binary from the GitHub Container Registry (ghcr.io).
This example pulls zot-minimal-linux-amd64:latest, a minimal (no extensions) zot image for an AMD-based linux server.
Other available images are described at the zot releases page in GitHub. You can also specify a release by replacing latest with an available release number.
"},{"location":"articles/kind-deploy/#step-3-create-the-kind-cluster","title":"Step 3: Create the kind cluster","text":"
Create a cluster with the local registry enabled.
# enable the local registry in containerd\ncat <<EOF | kind create cluster --config=-\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n- |-\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"localhost:${reg_port}\"]\n endpoint = [\"http://${reg_name}:5000\"]\nEOF\n
"},{"location":"articles/kind-deploy/#step-4-connect-the-registry-to-the-cluster-network","title":"Step 4: Connect the registry to the cluster network","text":"
Connect the registry to the \"kind\" network so that it can communicate with other resources in the same network.
"},{"location":"articles/kind-deploy/#step-5-document-the-local-registry","title":"Step 5: Document the local registry","text":"
Create a ConfigMap that specifies how to interact with the local registry. This ConfigMap follows the KEP-1755 Standard for communicating a local registry.
"},{"location":"articles/kind-deploy/#step-6-deploy-and-test","title":"Step 6: Deploy and test","text":"
Use skopeo to copy (pull) a \"hello\" app from the Google Container Registry (gcr.io) into the new zot registry. Using kubectl, deploy the app from the new local zot registry as \"hello-server\" and monitor the deployment for initial availability.
# copy an image\nskopeo copy --format=oci --dest-tls-verify=false \\\ndocker://gcr.io/google-samples/hello-app:1.0 \\\ndocker://localhost:5001/hello-app:1.0\n\n# deploy the image\nkubectl create deployment hello-server --image=localhost:5001/hello-app:1.0\n\n# check for availability\necho \"Waiting for deployment/hello-server to be ready ...\"\nkubectl wait deployment -n default hello-server \\\n --for condition=Available=True --timeout=90s\n
"},{"location":"articles/kind-deploy/#reference-a-complete-script","title":"Reference: A complete script","text":"
The following script executes all of the preceding steps.
Click here to view the entire script
#!/bin/sh\nset -o errexit\n\n# Reference: https://kind.sigs.k8s.io/docs/user/local-registry/\n\n# set no_proxy if applicable\nif [ ! -z \"${no_proxy}\" ]; then \n echo \"Updating no_proxy env var\";\n export no_proxy=${no_proxy},kind-registry;\n export NO_PROXY=${no_proxy};\nfi\n\n# create registry container unless it already exists\nreg_name='kind-registry'\nreg_port='5001'\nif [ \"$(docker inspect -f '{{.State.Running}}' \"${reg_name}\" 2>/dev/null || true)\" != 'true' ]; then\n docker run \\\n -d --restart=always -p \"127.0.0.1:${reg_port}:5000\" --name \"${reg_name}\" \\\n ghcr.io/project-zot/zot-minimal-linux-amd64:latest\nfi\n\n# create a cluster with the local registry enabled in containerd\ncat <<EOF | kind create cluster --config=-\nkind: Cluster\napiVersion: kind.x-k8s.io/v1alpha4\ncontainerdConfigPatches:\n- |-\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"localhost:${reg_port}\"]\n endpoint = [\"http://${reg_name}:5000\"]\nEOF\n\n# connect the registry to the cluster network if not already connected\nif [ \"$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' \"${reg_name}\")\" = 'null' ]; then\n docker network connect \"kind\" \"${reg_name}\"\nfi\n\n# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry\n#\n# document the local registry\ncat <<EOF | kubectl apply -f -\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: local-registry-hosting\n namespace: kube-public\ndata:\n localRegistryHosting.v1: |\n host: \"localhost:${reg_port}\"\n help: \"https://kind.sigs.k8s.io/docs/user/local-registry/\"\nEOF\n\n# copy an image\nskopeo copy --format=oci --dest-tls-verify=false docker://gcr.io/google-samples/hello-app:1.0 docker://localhost:5001/hello-app:1.0\n\n# deploy the image\nkubectl create deployment hello-server --image=localhost:5001/hello-app:1.0\n\n# check for availability\necho \"Waiting for deployment/hello-server to be ready ...\"\nkubectl wait deployment -n default hello-server --for condition=Available=True --timeout=90s\n\n# cleanup\necho \"Press a key to begin cleanup ...\"\nread KEYPRESS\nkind delete cluster\ndocker stop kind-registry\ndocker rm kind-registry\n
"},{"location":"articles/mirroring/","title":"OCI Registry Mirroring With zot","text":"
A zot registry can mirror one or more upstream OCI registries, including popular cloud registries such as Docker Hub and Google Container Registry (gcr.io).
A key use case for zot is to act as a mirror for upstream registries. If an upstream registry is OCI distribution-spec conformant for pulling images, you can use zot's sync feature to implement a downstream mirror, synchronizing OCI images and corresponding artifacts. Because synchronized images are stored in zot's local storage, registry mirroring allows for a fully distributed disconnected container image build pipeline. Container image operations terminate in local zot storage, which may reduce network latency and costs.
Because zot is a OCI-only registry, any upstream image stored in the Docker image format is converted to OCI format when downloading to zot. In the conversion, some non-OCI attributes may be lost. Signatures, for example, are removed due to the incompatibility between formats.
For mirroring an upstream registry, two common use cases are a fully mirrored or a pull through (on-demand) cache registry.
As with git, wherein every clone is a full repository, you can configure your local zot instance to be a fully mirrored OCI registry. For this mode, configure zot for synchronization by periodic polling, not on-demand. Zot copies and caches a full copy of every image on the upstream registry, updating the cache whenever polling discovers a change in content or image version at the upstream registry.
For a pull through cache mirrored registry, configure zot for on-demand synchronization. When an image is first requested from the local zot registry, the image is downloaded from the upstream registry and cached in local storage. Subsequent requests for the same image are served from zot's cache. Images that have not been requested are not downloaded. If a polling interval is also configured, zot periodically polls the upstream registry for changes, updating any cached images if changes are detected.
Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only on-demand mirroring with Docker Hub.
"},{"location":"articles/mirroring/#migrating-or-updating-a-registry-using-mirroring","title":"Migrating or updating a registry using mirroring","text":"
Mirroring zot using the sync feature allows you to easily migrate a registry. In situations such as the following, zot mirroring provides an easy solution.
Migrating an existing zot or non-zot registry to a new location.
Provided that the source registry is OCI-compliant for image pulls, you can mirror the registry to a new zot registry, delete the old registry, and reroute network traffic to the new registry.
Updating (or downgrading) a zot registry.
To minimize downtime during an update, or to avoid any incompatibilities between zot releases that would preclude an in-place update, you can bring up a new zot registry with the desired release and then migrate from the existing registry.
To ensure a complete migration of the registry contents, set a polling interval in the configuration of the new zot registry and set prefix to **, as shown in this example:
"},{"location":"articles/mirroring/#basic-configuration-for-mirroring-with-sync","title":"Basic configuration for mirroring with sync","text":"
The sync feature of zot is an extension of the OCI-compliant registry implementation. You can configure the sync feature under the extensions section of the zot configuration file, as shown in this example:
A list of one or more URLs to an upstream image registry. If the main URL fails, the sync process will try the next URLs in the listed order.
onDemand
false: Pull all images not found in the local registry.
true: Pull any image not found in the local registry only when the image is requested by a user.
pollInterval
The period in seconds between polling of a remote registry. If no value is specified, no periodic polling will occur. If a value is set and the content attributes are configured, periodic synchronization is enabled and will run at the specified value.Note: Because Docker Hub rate-limits pulls and does not support catalog listing, do not use polled mirroring with Docker Hub. Use only onDemand mirroring with Docker Hub.
tlsVerify
false: TLS will not be verified.
true: (Default) The TLS connection to the destination registry will be verified.
certDir
If a path is specified, use certificates (*.crt, *.cert, *.key files) at this path when connecting to the destination registry or daemon. If no path is specified, use the default certificates directory.
maxRetries
The maximum number of retries if an error occurs during either an on-demand or periodic synchronization. If no value is specified, no retries will occur.
retryDelay
The interval in seconds between retries. This attribute is mandatory when maxRetries is configured.
onlySigned
false: Synchronize signed or unsigned images.
true: Synchronize only signed images (either notary or cosign).
content
The included attributes in this section specify which content will be pulled. If this section is not populated, periodic polling will not occur. The included attributes can also filter which on-demand images are pulled.
prefix
On the remote registry, the path from which images will be pulled. This path can be a string that exactly matches the remote path, or it can be a glob pattern. For example, the path can include a wildcard (*) or a recursive wildcard (**).
tags
The included attributes in this optional section specify how remote images will be selected for synchronization based on image tags.
tags.regex
Specifies a regular expression for matching image tags. Images whose tags do not match the expression are not pulled.
tags.semver
Specifies whether image tags are to be filtered by semantic versioning (semver) compliance.
false: Do not filter by semantic versioning.
true: Filter by semantic versioning.
destination
Specifies the local path in which pulled images are to be stored.
stripPrefix
Specifies whether the prefix path from the remote registry will be retained or replaced when the image is stored in the zot registry.
false: Retain the source prefix, append it to the destination path.
true: Remove the source prefix.
Note: If the source prefix was specified with meta-characters (such as **), only the prefix segments that precede the meta-characters are removed. Any remaining path segments are appended to the destination path.
"},{"location":"articles/mirroring/#configuration-examples-for-mirroring","title":"Configuration examples for mirroring","text":""},{"location":"articles/mirroring/#example-multiple-repositories-with-polled-mirroring","title":"Example: Multiple repositories with polled mirroring","text":"
The following is an example of sync configuration for mirroring multiple repositories with polled mirroring.
The configuration in this example will result in the following behavior:
Only signed images (notation and cosign) are synchronized.
The sync communication is secured using certificates in certDir.
This registry synchronizes with upstream registry every 6 hours.
On-demand mirroring is disabled.
Based on the content filtering options, this registry synchronizes these images:
From /repo1/repo, images with tags that begin with \"4.\" and are semver compliant. Files are stored locally in /repo1/repo on localhost.
From /repo2/repo, images with all tags. Because stripPrefix is enabled, files are stored locally in /repo2. For example, docker://upstream/repo2/repo:v1 is stored as docker://local/repo2:v1.
From /repo3/repo, images with all tags. Files are stored locally in /repo3/repo.
"},{"location":"articles/mirroring/#example-multiple-registries-with-on-demand-mirroring","title":"Example: Multiple registries with on-demand mirroring","text":"
The following is an example of sync configuration for mirroring multiple registries with on-demand mirroring.
With this zot configuration, the sync behavior is as follows:
This initial user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/docker-images/alpine <dest>causes zot to synchronize the content with the docker.io registry: docker.io/library/alpine:latestto the zot registry: localhost:8080/docker-images/alpine:latestbefore delivering the content to the requestor at <dest>.
This initial user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/k8s-images/kube-proxy:v1.19.2 <dest>causes zot to synchronize the content with the gcr.io registry: k8s.gcr.io/kube-proxy:v1.19.2 to the zot registry: localhost:8080/k8s-images/kube-proxy:v1.19.2before delivering the content to the requestor at <dest>.
You can use this command: curl http://localhost:8080/v2/_catalogto display the local repositories:
With this zot configuration, the sync behavior is as follows:
This user request for content from the zot registry: skopeo copy --src-tls-verify=false docker://localhost:8080/kube-proxy/kube-proxy:v1.19.2 <dest>causes zot to synchronize the content with this remote registry: k8s.gcr.io/kube-proxy:v1.19.2to the zot registry: localhost:8080/kube-proxy/kube-proxy:v1.19.2before delivering the content to the requestor at <dest>.
You can use this command: curl http://localhost:8080/v2/_catalogto display the local repositories:
In zot storage, the requested content is located here: /tmp/zot/kube-proxy/kube-proxy/kube-proxy/This subpath is created from the following path components:
/tmp/zot is the rootDirectory of the zot registry
kube-proxy is the rootDirectory of the storage subpath
kube-proxy is the sync destination parameter
kube-proxy is the repository name
"},{"location":"articles/monitoring/","title":"Monitoring the registry","text":"
zot supports a range of monitoring tools including logging, metrics, and benchmarking.
The following sections describe how to configure logging and monitoring with zot. You can use zot's benchmarking tool to test your configuration and deployment, as described in Benchmarking zot with zb.
The available methods for collecting metrics varies depending on whether your zot installation is a minimal (distribution-spec-only) image or a full image including extensions.
"},{"location":"articles/monitoring/#enabling-metrics-for-a-full-zot-image-with-extensions","title":"Enabling metrics for a full zot image with extensions","text":"
Add the metrics attribute under extensions in the configuration file to enable and configure metrics, as shown in the following example.
The following table lists the configurable attributes for metrics collection.
Attribute Description enable If this attribute is missing, metrics collection is enabled by default. Metrics collection can be disabled by setting this attribute to false. prometheus Attributes under prometheus contain configuration settings for the Prometheus node exporter. path The server path on which metrics will be exposed."},{"location":"articles/monitoring/#collecting-metrics-from-a-minimal-zot-image-using-a-node-exporter","title":"Collecting metrics from a minimal zot image using a node exporter","text":"
Although a minimal zot image does not contain a node exporter, it exposes internal metrics in a Prometheus format for collection by a separate node exporter tool such as zxp. The zot companion binary zxp is a node exporter that can be deployed with a minimal zot image in order to scrape metrics from the zot server.
Metrics are automatically enabled in the zot server upon first scrape from the node exporter and the metrics are automatically disabled when the node exporter has not performed any scraping for some period. No extra zot configuration is needed for this behavior.
You can download the zxp executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.
The binary image is named using the target platform and architecture. For example, the binary for an Intel-based MacOS server is zxp-darwin-amd64. To configure the zxp example image, run this command:
zxp-darwin-amd64 config zxp-config-file
For convenience, you can rename the binary image file to simply zxp.
A sample Dockerfile for zxp is available at Dockerfile-zxp.
The configuration file of zxp contains connection details for the zot server from which it will scrape metrics. The following JSON structure is an example of the zxp-config-file contents:
The zxp module does not have Prometheus integration.
The zxp module is not needed with a full zot image.
"},{"location":"articles/pprofiling/","title":"Performance Profiling in zot","text":"
Use zot's built-in profiling tools to collect and analyze runtime performance.
The profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.
If authentication is enabled, only a zot admin user can access the APIs for profiling.
All examples in this article assume that the zot registry is running at localhost:8080.
"},{"location":"articles/pprofiling/#what-data-is-available","title":"What data is available?","text":"
The zot source code incorporates golang's pprof package of runtime analysis tools to collect data for the following performance-related profiles:
Profile Description allocs A sampling of all past memory allocations. block Stack traces that led to blocking on synchronization primitives. cmdline The command line invocation of the current program. goroutine Stack traces of all current goroutines. Use debug=2 as a URL query parameter to export in the same format as an unrecovered panic. heap A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample. mutex Stack traces of holders of contended mutexes. profile CPU usage profile. You can specify the duration in the seconds URL query parameter. After receiving the profile file, use the go tool pprof command to investigate the profile. threadcreate Stack traces that led to the creation of new OS threads. trace A trace of execution of the current program. You can specify the duration in the seconds URL query parameter. After you get the trace file, use the go tool trace command to investigate the trace.
To return a current HTML-format profile list along with a count of currently available records for each profile, use the following API command:
/v2/_zot/pprof/\n
If authentication is enabled, only an admin user can access this API.
"},{"location":"articles/pprofiling/#how-do-i-export-profile-data","title":"How do I export profile data?","text":"
To collect and export any available profile, use the following API command format:
This command example creates an output data file named \"cpu.prof\".
The query parameter ?seconds=<number> specifies the number of seconds to gather the profile data. If this parameter is not specified, the default is 30 seconds.
In this example, the raw output data is redirected to a file named \"cpu.prof\". Alternatively, you can use curl -O to create a file with the default profile name (in this case, \"profile\"). If no output file is specified by either a cURL flag or an output redirection, the cURL command fails with \"Failure writing output to destination\".
The command output file is in a machine-readable format that can be interpreted by performance analyzers.
"},{"location":"articles/pprofiling/#analyzing-the-cpu-usage-profile-using-go-tool-pprof","title":"Analyzing the CPU usage profile using go tool pprof","text":"
Go's pprof package provides a variety of presentation formats for analyzing runtime performance.
For detailed information, see the pprof documentation.
"},{"location":"articles/pprofiling/#generating-a-pprof-web-presentation","title":"Generating a pprof web presentation","text":"
When an HTTP port is specified as a command flag, the go tool pprof command installs and opens a local web server that provides a web interface for viewing and analyzing the profile data. This example opens a localhost page at port 9090 for viewing the CPU usage data captured in the profile file named \"cpu.prof\".
$ go tool pprof -http=:9090 cpu.prof\nServing web UI on http://localhost:9090\n
The pprof web view offers several options for viewing and interpreting the collected performance data. Select VIEW to see the available options:
A Flame Graph can be very useful for analyzing CPU usage:
"},{"location":"articles/pprofiling/#generating-a-graphic-image","title":"Generating a graphic image","text":"
The pprof package can generate graphic representations of profile data in many formats. This example generates a PNG file representing the CPU usage in the \"cpu.prof\" file.
$ go tool pprof -png cpu.prof\nGenerating report in profile001.png\n
"},{"location":"articles/pprofiling/#opening-a-pprof-interactive-session","title":"Opening a pprof interactive session","text":"
This example opens an interactive session with pprof and executes the pprof top command, which displays the top ten modules by CPU usage during the profiling capture window.
"},{"location":"articles/pprofiling/#analyzing-the-trace-profile-using-go-tool-trace","title":"Analyzing the trace profile using go tool trace","text":"
You can collect trace data with the trace profile, as in this example:
Retention policies are configured in the storage section of the zot configuration file under the retention attribute. One or more policies can be grouped under the policies attribute.
By default, if no retention policies are defined, all tags are retained.
If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed. To avoid unintended removals, we recommend defining a default policy, as described in Configuration notes.
The following table lists the attributes available in the retention policy configuration.
Attribute Value Description dryRun boolean If true, will log a removal action without actually removing the image. Default is false. delay time Remove untagged and referrers only if they are older than the specified <time> hours, such as 24h. policies list A list of policies. repositories list A list of glob patterns to match repositories. deleteReferrers boolean If true, delete manifests with a missing Subject. Default is false. deleteUntagged boolean If true, delete untagged manifests. Default is true. keepTags list Criteria for tags to retain always. mostRecentlyPushedCount count Retains the top <count> most recently pushed tags. mostRecentlyPulledCount count Retains the top <count> most recently pulled tags. pushedWithin time Retains the tags pushed during the last <time> hours, such as 24h. pulledWithin time Retains the tags pulled during the last <time> hours, such as 24h. patterns regex See Notes."},{"location":"articles/retention/#configuration-notes","title":"Configuration notes","text":"
A repository will apply the first policy it matches.
If a repository matches no policy, the repository and all its tags are retained.
If at least one keepTags policy is defined for a repository, all tags not matching those policies are removed.
If keepTags is present but empty, all tags are retained.
When multiple rules are configured, a tag is retained if it meets at least one rule.
When you specify a regex pattern combined with one or more rules, the rules are applied only to those tags matching the regex.
When you specify a regex pattern with no rules other than the default, all tags matching the pattern are retained.
In the repositories list, a single asterisk (/*) matches all first-level items in the repository. A double asterisk (/**) matches all recursively.
We recommend defining a default keepTags policy, such as the following example, as the last policy in the policy list. All tags that don't match the preceding policies will be retained by this default policy:
A cluster of zot instances can be easily scaled with no repo-specific intelligence in the load balancing scheme, using:
Stateless zot instances to simplify scale out
Shared remote storage
zot release v2.1.0 or later
Beginning with zot release v2.1.0, a new \"scale-out\" architecture greatly reduces the configuration required when deploying large numbers of zot instances. As before, multiple identical zot instances run simultaneously using the same shared reliable storage, but with improved scale and performance in large deployments. A highly scalable cluster can be architected by automatically sharding based on repository name so that each zot instance is responsible for a subset of repositories.
In a cloud deployment, the shared backend storage (such as AWS S3) and metadata storage (such as DynamoDB) can also be easily scaled along with the zot instances.
For high availability clustering with earlier zot releases, see zot Clustering.
For easy scaling of instances (replicas), the following conditions must be met:
All zot replicas must be running zot release v2.1.0 (or later) with identical configurations.
All zot replicas in the cluster use remote storage at a single shared S3 backend. There is no local caching in the zot replicas.
Each zot replica in the cluster has its own IP address, but all replicas use the same port number.
"},{"location":"articles/scaleout/#how-it-works","title":"How it works","text":"
Each repo is served by one zot replica, and that replica is solely responsible for serving all images of that repo. A repo in storage can be written to only by the zot replica responsible for that repo.
When a zot replica in the cluster receives an image push or pull request for a repo, the receiving replica hashes the repo path and consults a hash table to determine which replica is responsible for the repo.
If the hash indicates that another replica is responsible, the receiving replica forwards the request to the responsible replica and then acts as a proxy, returning the response to the requestor.
If the hash indicates that the current (receiving) replica is responsible, the request is handled locally.
For better resistance to collisions and preimage attacks, zot uses SipHash as the hashing algorithm.
Either of the following two schemes can be used to reach the cluster.
"},{"location":"articles/scaleout/#using-a-single-entry-point-load-balancer","title":"Using a single entry point load balancer","text":"
When a single entry point load balancer such as HAProxy is deployed, the number of zot replicas can easily be expanded by simply adding the IP addresses of the new replicas in the load balancer configuration.
When the load balancer receives an image push or pull request for a repo, it forwards the request to any replica in the cluster. No repo-specific programming of the load balancer is needed because the load balancer does not need to know which replica owns which repo. The replicas themselves can determine this.
Because the scale-out architecture greatly simplifies the role of the load balancer, it may be possible to eliminate the load balancer entirely. A scheme such as DNS-based routing can be implemented, exposing the zot replicas directly to the clients.
In these examples, clustering is supported by using multiple stateless zot replicas with shared S3 storage and an HAProxy (with sticky session) load balancer forwarding traffic to the replicas.
"},{"location":"articles/scaleout/#cluster-member-configuration","title":"Cluster member configuration","text":"
In the replica configuration, each replica must have a list of its peers configured in the \"members\" section of the JSON structure. This is a list of reachable addresses or hostnames. Each replica owns one of these addresses.
The replica must also have a hash key for hashing the repo path of the image request and a TLS certificate for authenticating with its peers.
Click here to view a sample cluster configuration for each replica. See the \"cluster\" section in the JSON structure.
The HAProxy load balancer uses a simple round-robin balancing scheme and delivers a cookie to the requestor to maintain a sticky session connection to the assigned replica.
Click here to view a sample HAProxy configuration.
"},{"location":"articles/scaleout/#when-a-replica-fails","title":"When a replica fails","text":"
The scale-out clustering scheme described in this article is not self-healing when a replica fails. In case of a replica failure, only those repositories that are mapped to the failed replica are affected. If the error is not transient, the cluster must be resized and restarted to exclude that replica.
With an HAProxy load balancer, we recommend implementing an HAProxy circuit breaker to monitor and protect the cluster.
"},{"location":"articles/scaleout/#cve-repository-in-a-zot-cluster-environment","title":"CVE repository in a zot cluster environment","text":"
CVE scanning is not supported for cloud deployments. In the scale-out clustering scheme described in this article, CVE scanning is disabled. In this case, we recommend implementing a CVE repository with a zot instance outside of the cluster using a local disk for storage and Trivy as the detection engine.
The sync feature of zot, either on demand or periodic, is compatible with scale-out clustering. In this case, the repo names are hashed to a particular replica and only that replica will perform the sync.
An overview of zot build-time and runtime security hardening features, including:
Build-time hardening such as PIE-mode builds
Minimal-build option for smaller attack surface
Open Source Security Foundation best practices for CI/CD
Non-root deployment
Robust authentication/authorization options
The zot project takes a defense-in-depth approach to security, applying industry-standard best practices at various stages. Recognizing that security hardening and product features are sometimes in conflict with each other, we also provide flexibility both at build and deployment time.
The zot binary is built with PIE build-mode enabled to take advantage of ASLR support in modern operating systems such as Linux ASLR. While zot is intended to be a long-running service (without frequent restarts), it prevents attackers from developing a generic attack that depends on predictable memory addresses across multiple zot deployments.
Functionality in zot is broadly organized as a core Distribution Specification implementation and additional features as extensions. The rationale behind this approach is to minimize or control library dependencies that get included in the binary and consequently the attack surface.
We currently build and release two image flavors:
minimal, which is a minimal Distribution Specification conformant registry, and
full, which incorporates the minimal build and all extensions
The minimal flavor is for the security-minded and minimizes the number of dependencies and libraries. The full flavor is for the functionality-minded with the caveat that the attack surface of the binary is potentially broader. However by no means are these the only options. Our build (via the Makefile) provides the flexibility to pick and choose extensions in order to build a binary between minimal and full. For example,
make EXTENSIONS=search binary
produces a zot binary with only the search feature enabled.
zot is an open source project and all code submissions are open and transparent. Every pull request (PR) submitted to the project repository must be reviewed by the code owners. We have additional CI/CD workflows monitoring for unreviewed commits.
All PRs must pass the full CI/CD pipeline checks including unit, functional, and integration tests, code quality and style checks, and performance regressions. In addition, all binaries produced are subjected to further security scans to detect any known vulnerabilities.
All interactions with zot are over HTTP APIs, and htpasswd-based local authentication, LDAP, mutual TLS, and token-based authentication mechanisms are supported. We strongly recommend enabling a suitable mechanism for your deployment use case in order to prevent unauthorized access. See the provided authentication examples.
Following authentication, it is further possible to allow or deny actions by a user on a particular repository stored on the zot registry. See the provided access control examples.
We understand that no software is perfect and in spite of our best efforts, security bugs may be found. Refer to our security policy for taking a responsible course of action when reporting security bugs.
"},{"location":"articles/storage/","title":"Storage Planning with zot","text":"
zot supports the following features to provide OCI standards-based, vendor-agnostic image storage:
Data handling in zot revolves around two main principles: that data and APIs on the wire conform to the OCI Distribution Specification and that data on the disk conforms to the OCI Image Layout Specification. As a result, any client that is compliant with the Distribution Specification can read from or write to a zot registry. Furthermore, the actual storage is simply an OCI Image Layout. With only these two specification documents in hand, the entire data flow inside can be easily understood.
zot does not implement, support, or require any vendor-specific protocols, including that of Docker.
"},{"location":"articles/storage/#hosting-an-oci-image-layout","title":"Hosting an OCI image layout","text":"
Because zot supports the OCI image layout, it can readily host and serve any directories holding a valid OCI image layout even when those directories have been created elsewhere. This property of zot is suitable for use cases in which container images are independently built, stored, and transferred, but later need to be served over the network.
Exposing flexibility in storage capabilities is a key tenet for catering to the requirements of varied environments ranging from cloud to on-premises to IoT.
Most modern filesystems buffer and flush RAM data to disk after a delay. The purpose of this function is to improve performance at the cost of higher disk memory usage. In embedded devices such as Raspberry Pi, for example, where RAM may be very limited and at a premium, it is desirable to flush data to disk more frequently. The zot storage configuration exposes an option called commit which, when enabled, causes data writes to be committed to disk immediately. This option is disabled by default.
Deduplication is a storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. The deduplication option (dedupe) is also available for supported cloud storage backends.
Upon startup, zot enforces the dedupe status on the existing storage. If the dedupe status upon startup is true, zot deduplicates all blobs found in storage, both local and remote. If the status upon startup is false, zot restores cloud storage blobs to their original state. There is no need for zot to restore local filesystem storage if hard links are used.
After an image is deleted by deleting an image manifest, the corresponding blobs can be purged to free up space. However, since Distribution Specification APIs are not transactional between blob and manifest lifecycle, care must be taken so as not to put the storage in an inconsistent state. Garbage collection in zot is an inline feature meaning that it is not necessary to take the registry offline. See Configuring garbage collection for details.
The scrub function, available as an extension, makes it possible to ascertain data validity by computing hashes on blobs periodically and continuously so that any bit rot is caught and reported early.
zot can store and serve files from one or more local directories. A minimum of one root directory is required for local hosting, but additional hosted directories can be added. When accessed by HTTP APIs, all directories can appear as a single data store.
Remote filesystems that are mounted and accessible locally such as NFS or fuse are treated as local filesystems.
zot can also store data remotely in the cloud, using the storage APIs of the cloud service. Currently, zot supports only the AWS s3 storage service.
"},{"location":"articles/storage/#example-configuration-for-remote-s3-storage","title":"Example: configuration for remote (s3) storage","text":"Click here to view a sample zot configuration for remote storage.
The following table lists the attributes of the storage configuration.
Attribute Description
rootDirectory
Location of the images stored in the server file system.
commit
For faster performance, data written by zot is retained in memory before being periodically committed to disk by the operating system. To eliminate this retention time and cause data to be written to disk immediately, set to true. This prevents data loss but reduces performance.
dedupe
If the server filesystem supports hard links, you can optimize storage space by enabling inline deduplication of layers and blobs that are shared among multiple container images. Deduplication is enabled by default. Set to false to disable deduplication.
gc
When an image is deleted, either by tag or by reference, orphaned blobs can lead to wasted storage. Garbage collection (gc) is enabled by default to reclaim this space. Set to false to disable garbage collection.
gcDelay
(Optional) If garbage collection is enabled, causes it to run once after the specified delay time. The default is 1 hour. Requires the gc attribute to be true.
gcInterval
(Optional) If garbage collection is enabled, causes periodic collection at the specified interval. Must be set based on use cases and user workloads. If no value is specified, there is no periodic collection. Requires the gc attribute to be true.
subpaths
You can store and serve images from multiple filesystems, each with their own repository paths and settings. The following example shows three subpaths.
The zot configuration model allows for enabling and disabling garbage collection (gc) and specifying a periodic interval (gcInterval) for collection.
gcgcInterval Result false n/a GC disabled omitted n/a GC enabled with 1 hour interval (default) true omitted GC enabled with 1 hour interval true 0 GC runs only once true >0 GC enabled with specified interval
The configuration model also allows the configuration of a tunable delay (gcDelay), which can be set depending on client network speeds and the size of blobs. The gcDelay attribute causes collection to run once after the specified delay time. This attribute has a default value of one hour (1h).
"},{"location":"articles/storage/#configuring-remote-storage-with-s3","title":"Configuring remote storage with s3","text":"
To configure an Amazon Simple Storage Service (s3) bucket for zot, use the storageDriver attribute in the zot configuration file, as shown in the following example:
The following table lists the attributes of storageDriver when configuring s3 for remote storage:
Attribute Required Description name yes Name of storage driver. Only s3 is supported for now. accesskey no Your AWS Access Key. If you use IAM roles, omit to fetch temporary credentials from IAM. secretkey no Your AWS Secret Key. If you use IAM roles, omit to fetch temporary credentials from IAM. region yes The AWS region in which your bucket exists. regionendpoint no Endpoint for S3 compatible storage services (Minio, etc). forcepathstyle no To enable path-style addressing when the value is set to true. The default is true. bucket yes The bucket name in which you want to store the registry\u2019s data. encrypt no Specifies whether the registry stores the image in encrypted format or not. A boolean value. The default is false. keyid no Optional KMS key ID to use for encryption (encrypt must be true, or this parameter is ignored). The default is none. secure no Indicates whether to use HTTPS instead of HTTP. A boolean value. The default is true. skipverify no Skips TLS verification when the value is set to true. The default is false. v4auth no Indicates whether the registry uses Version 4 of AWS\u2019s authentication. The default is true. chunksize no The S3 API requires multipart upload chunks to be at least 5MB. This value should be a number that is larger than 5 * 1024 * 1024. multipartcopychunksize no Default chunk size for all but the last S3 Multipart Upload part when copying stored objects. multipartcopymaxconcurrency no Max number of concurrent S3 Multipart Upload operations when copying stored objects. multipartcopythresholdsize no Default object size above which S3 Multipart Upload will be used when copying stored objects. rootdirectory no This is a prefix that is applied to all S3 keys to allow you to segment data in your bucket if necessary. storageclass no The S3 storage class applied to each registry file. The default is STANDARD. useragent no The User-Agent header value for S3 API operations. usedualstack no Use AWS dual-stack API endpoints. accelerate no Enable S3 Transfer Acceleration. objectacl no The S3 Canned ACL for objects. The default value is \u201cprivate\u201d. loglevel no The log level for the S3 client. The default value is off.
For more information, see the s3 storage driver docs.
In the s3 configuration file example, the s3 credentials were configured with the attributes accesskey and secretkey. As an alternative, you can omit these attributes from the configuration file and you can configure them using environment variables or a credential file.
Environment variables
zot looks for credentials in the following environment variables:
The [default] heading defines credentials for the default profile, which zot will use unless you configure it to use another profile. You can specify a profile using the AWS_PROFILE environment variable as in this example:
AWS_PROFILE=test-account\n
The credential file must be named credentials. The file must be located in the .aws/ subdirectory in the home directory of the same server that is running your zot application.
For more details about specifying s3 credentials, see the AWS documentation.
A cache driver is used to store duplicate blobs when dedupe is enabled. zot supports database caching using BoltDB as the cache driver for local filesystems and DynamoDB for remote filesystems.
The AWS GO SDK loads additional configuration and credentials values from your environment variables, shared credentials, and shared configuration files.
If the search extension is enabled, additional parameters are required:
The subPaths feature ties together several separate storage filesystems and backends behind the same HTTP API interface. In the example above, both repository paths \"/a\" and \"/b\" are exposed to clients. Content on these two paths can be hosted completely separately by different storage services, locations, or filesystems, with no difference to the user interface and no perceptible difference to the user experience. This is useful if one wants to serve existing OCI images from different backends or if storage can be expanded only by using different backing stores.
zot also supports different storage drivers for each subpath.
Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user.
To verify image signatures, zot supports the following tools:
To enable image signature verification, add the trust attribute under extensions in the zot configuration file and enable one or more verification tools, as shown in the following example:
The following table lists the configurable attributes of the trust extension.
Attribute Description enable If this attribute is missing, signature verification is disabled by default. Signature verification is enabled by including this attribute and setting it to true. You must also enable at least one of the verification tools. cosign Set to true to enable signature verification using the cosign tool. notation Set to true to enable signature verification using the notation tool."},{"location":"articles/verifying-signatures/#what-is-needed-for-verifying-signatures","title":"What is needed for verifying signatures","text":"
To verify the validity of a signature for an image, zot makes use of two types of files:
A public key file that pairs with the private key used to sign an image with cosign
A certificate file that is used to sign an image with notation
Upload these files using an extension of the zot API, as shown in the following examples:
To upload a public key for cosign:
API path
/v2/_zot/ext/cosign\"\n
Example request
curl --data-binary @file.pub -X POST \"http://localhost:8080/v2/_zot/ext/cosign\"\n
Result
The uploaded file is stored in the _cosign directory under the rootDir specified in the zot configuration file or in the Secrets Manager.
To upload a certificate for notation:
API path
/v2/_zot/ext/notation?truststoreType=ca\n
When uploading a certificate, you should specify the truststoreType. If the truststore is a certificate authority, the value is ca. This is the default if this attribute is omitted.
Example request
curl --data-binary @certificate.crt -X POST \"http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca\"\n
Result
The uploaded file is stored in the _notation/truststore/x509/{truststoreType}/default directory under the rootDir specified in the zot configuration file or in the Secrets Manager.
"},{"location":"articles/verifying-signatures/#where-needed-files-are-stored","title":"Where needed files are stored","text":"
Uploaded public keys and certificates are stored in the local filesystem, in specific directories named _cosign and _notation under $rootDir, or in the Secrets Manager.
The _cosign directory contains uploaded public key files in the following structure:
In this directory, the trustpolicy.json file contains content that is updated automatically whenever a new certificate is added to a new truststore. This content cannot be changed by the user. An example of the trustpolicy.json file content is shown below:
By default, the trustpolicy.json file sets the signatureVerification.level property to strict, which enforces all validations. For example, a signature is not trusted if its certificate has expired, even if the certificate verifies the signature.
The trustpolicy.json file contains two default truststores, ca:default and signingAuthority:default. This list of truststores is not updated when a new certificate is uploaded.
The content of the trustStores field will match the content of the _notation/truststore directory.
Based on the uploaded files and the information about images stored in zot's database, signature verification is performed for all signed images. The verification result for each signed image is stored in the database and is visible from GraphQL. The stored information about a signature includes:
The tool that was used to generate the signature, such as cosign or notation
The trustworthiness of the signature, such as whether a certificate or public key exists that can successfully verify the signature
The author of the signature, which can be either:
The public key, for signatures generated using cosign
The subject of the certificate, for signatures generated using notation
"},{"location":"articles/verifying-signatures/#example-of-graphql-output","title":"Example of GraphQL output","text":"
"},{"location":"articles/workflow/","title":"Software Provenance Workflow Using OCI Artifacts","text":"
This article demonstrates an end-to-end workflow for installing a zot registry, then pushing and signing an image and a related artifact, such as an SBOM.
The following sections describe the step-by-step workflow. To view the steps combined into a single script, see Reference: Full workflow script.
For the workflow examples, the zot registry is assumed to be installed and running at localhost:8080.
"},{"location":"articles/workflow/#step-1-download-the-client-tools","title":"Step 1: Download the client tools","text":"
This workflow uses the regctl registry client and the cosign image signing tool. As a first step, we download binaries for these tools in a tools directory.
"},{"location":"articles/workflow/#step-2-deploy-an-oci-registry-with-referrers-support-zot","title":"Step 2: Deploy an OCI registry with referrers support (zot)","text":"
Next, we execute the following tasks to deploy an OCI registry:
Copy a zot executable binary to the server.
Create a basic configuration file for the zot server, specifying the local root directory, the network location, and the port number.
Launch zot with the newly-created configuration file.
Looping with a periodic cURL query, detect when zot is up and running.
ZOT=${TOOLSDIR}/bin/zot\nZOT_VERSION=2.0.0-rc6\ncurl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal\nchmod +x ${ZOT}\n\nZOT_HOST=localhost\nZOT_PORT=8080\n\n# function to start zot and test for readiness\nfunction zot_setup() {\ncat > $TEST_TMPDIR/zot-config.json << EOF\n{\n \"distSpecVersion\": \"1.1.0-dev\",\n \"storage\": {\n \"rootDirectory\": \"$TEST_TMPDIR/zot\"\n },\n \"http\": {\n \"address\": \"$ZOT_HOST\",\n \"port\": \"$ZOT_PORT\"\n },\n \"log\": {\n \"level\": \"error\"\n }\n}\nEOF\n # start zot as a background task\n ${ZOT} serve $TEST_TMPDIR/zot-config.json &\n pid=$!\n # wait until service is up\n count=5\n up=0\n while [[ $count -gt 0 ]]; do\n if [ ! -d /proc/$pid ]; then\n echo \"zot failed to start or died\"\n exit 1\n fi\n up=1\n curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0\n if [ $up -eq 1 ]; then break; fi\n sleep 1\n count=$((count - 1))\n done\n if [ $up -eq 0 ]; then\n echo \"Timed out waiting for zot\"\n exit 1\n fi\n # setup an OCI client\n ${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT\n}\n\n# call the function to start zot\nzot_setup\n
"},{"location":"articles/workflow/#step-3-copy-an-image-to-the-oci-registry","title":"Step 3: Copy an image to the OCI registry","text":"
This step copies a busybox container image into the registry.
"},{"location":"articles/workflow/#step-4-copy-a-related-artifact-to-the-oci-registry","title":"Step 4: Copy a related artifact to the OCI registry","text":"
This step creates a simple artifact file and associates it with the busybox image in the registry.
The --subject command flag associates the artifact file with the specified subject (in this case, the busybox image). If no subject is specified by the command, the artifact is considered independent and not associated with any existing image.
"},{"location":"articles/workflow/#step-5-display-the-artifact-tree","title":"Step 5: Display the artifact tree","text":"
This step prints the artifact tree of the busybox image. The tree includes the artifact yaml file, showing the association of the artifact to the busybox image.
These script commands define REF0 as the artifact that was uploaded referring to the first container image.
REF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)\nREF0=\"${REF0:1:-1}\"\n
The following example shows the command and its output:
The displayed artifact tree shows that the original image (localhost:8080/busybox:latest) has one direct referrer (sha256:9c06...883e: application/yaml), the artifact yaml file.
"},{"location":"articles/workflow/#step-6-sign-the-image-and-artifact","title":"Step 6: Sign the image and artifact","text":"
This step creates a key pair for cosign in a separate directory, then uses cosign to sign both the image and the artifact file. Both signatures, like the artifact file itself, are associated with the busybox image.
# create a key pair in a different directory\npushd ${TEST_TMPDIR}\nCOSIGN_PASSWORD= ${COSIGN} generate-key-pair\npopd\n# sign the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n# sign the artifact referring to the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}\n
"},{"location":"articles/workflow/#step-7-display-the-artifact-tree","title":"Step 7: Display the artifact tree","text":"
This step again prints the artifact tree, which should now show the artifact and the two signatures, all associated to the busybox image.
${REGCLIENT} artifact tree localhost:8080/busybox:latest\n
The following example shows the command and its output:
The displayed artifact tree shows that the original image now has two direct referrers \u2014 the artifact and the cosign signature of the original image. In addition, there is a second-level referrer \u2014 the cosign signature of the artifact, which is a referrer of the artifact file.
"},{"location":"articles/workflow/#step-8-end-of-demonstration","title":"Step 8: End of demonstration","text":"
This step halts the zot registry server, ending the workflow demonstration.
# function for stopping zot after demonstration\nfunction zot_teardown() {\n killall zot\n}\n\n# stop zot\nzot_teardown\n
"},{"location":"articles/workflow/#reference-full-workflow-script","title":"Reference: Full workflow script","text":"
Expand the text box below to view the entire workflow as a single executable shell script.
To copy the script to the clipboard, click the copy icon that appears in the upper right corner of the expanded text box.
Click here to view the all-in-one script
#!/bin/bash -xe\n\nTEST_TMPDIR=$(mktemp -d \"${PWD}/artifact-test-${1:+-$1}.XXXXXX\")\n\nTOOLSDIR=$(pwd)/hack/tools\nmkdir -p ${TOOLSDIR}/bin\n\nREGCLIENT=${TOOLSDIR}/bin/regctl\nREGCLIENT_VERSION=v0.5.1\ncurl -Lo ${REGCLIENT} https://github.com/regclient/regclient/releases/download/${REGCLIENT_VERSION}/regctl-linux-amd64\nchmod +x ${REGCLIENT}\n\nCOSIGN=${TOOLSDIR}/bin/cosign\nCOSIGN_VERSION=2.1.1\ncurl -Lo ${COSIGN} https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64 \nchmod +x ${COSIGN}\n\n# OCI registry\nZOT=${TOOLSDIR}/bin/zot\nZOT_VERSION=2.0.0-rc6\ncurl -Lo ${ZOT} https://github.com/project-zot/zot/releases/download/v${ZOT_VERSION}/zot-linux-amd64-minimal\nchmod +x ${ZOT}\n\nZOT_HOST=localhost\nZOT_PORT=8080\n\nfunction zot_setup() {\ncat > $TEST_TMPDIR/zot-config.json << EOF\n{\n \"distSpecVersion\": \"1.1.0-dev\",\n \"storage\": {\n \"rootDirectory\": \"$TEST_TMPDIR/zot\"\n },\n \"http\": {\n \"address\": \"$ZOT_HOST\",\n \"port\": \"$ZOT_PORT\"\n },\n \"log\": {\n \"level\": \"error\"\n }\n}\nEOF\n# start as a background task\n${ZOT} serve $TEST_TMPDIR/zot-config.json &\npid=$!\n # wait until service is up\ncount=5\nup=0\nwhile [[ $count -gt 0 ]]; do\n if [ ! -d /proc/$pid ]; then\n echo \"zot failed to start or died\"\n exit 1\n fi\n up=1\n curl -f http://$ZOT_HOST:$ZOT_PORT/v2/ || up=0\n if [ $up -eq 1 ]; then break; fi\n sleep 1\n count=$((count - 1))\ndone\nif [ $up -eq 0 ]; then\n echo \"Timed out waiting for zot\"\n exit 1\nfi\n# setup a OCI client\n${REGCLIENT} registry set --tls=disabled $ZOT_HOST:$ZOT_PORT\n}\n\n# function for stopping zot after demonstration\nfunction zot_teardown() {\nkillall zot\n}\n\n# call the function to start zot\nzot_setup\n\n# copy an image\nskopeo copy --format=oci --dest-tls-verify=false docker://busybox:latest docker://${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n\n# copy an artifact referring to the above image\ncat > ${TEST_TMPDIR}/artifact.yaml << EOF\nkey:\nval: artifact\nEOF\n${REGCLIENT} artifact put --artifact-type application/yaml -f ${TEST_TMPDIR}/artifact.yaml --subject ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\nREF0=$(${REGCLIENT} artifact tree --format '{{jsonPretty .}}' localhost:8080/busybox:latest | jq .referrer[0].reference.Digest)\nREF0=\"${REF0:1:-1}\"\n\n# create a key pair in a different directory\npushd ${TEST_TMPDIR}\nCOSIGN_PASSWORD= ${COSIGN} generate-key-pair\npopd\n# sign the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox:latest\n# sign the artifact referring to the image\nCOSIGN_PASSWORD= COSIGN_OCI_EXPERIMENTAL=1 COSIGN_EXPERIMENTAL=1 ${COSIGN} sign -y --key ${TEST_TMPDIR}/cosign.key --registry-referrers-mode=oci-1-1 ${ZOT_HOST}:${ZOT_PORT}/busybox@${REF0}\n\n# list the reference tree\n${REGCLIENT} artifact tree localhost:8080/busybox:latest\n\n# stop zot\nzot_teardown\n
"},{"location":"developer-guide/api-reference/","title":"zot API Command Reference","text":"
This article describes the zot REST API commands, parameters, and responses.
The information presented here is adapted from the interactive OpenAPI (formerly swagger) JSON file in the zot Github project.
For instructions and examples of how to use the zot API, see Using the zot API.
Revokes one current user API key based on given key ID
Parameters
Name In Type Required Description id query string true api token id (UUID)
Example responses
200 Response
\"string\"\n
Responses
Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string
Name In Type Required Description body body api.APIKeyPayload true api token id (UUID)
Example responses
201 Response
\"string\"\n
Responses
Status Meaning Description Schema 201 Created created string 400 Bad Request bad request string 401 Unauthorized unauthorized string 500 Internal Server Error internal server error string
Get references for an image given a digest and artifact type
Parameters
Name In Type Required Description name path string true repository name digest path string true image digest artifactType query string true artifact type
Example responses
200 Response
\"string\"\n
Responses
Status Meaning Description Schema 200 OK ok string 404 Not Found not found string 500 Internal Server Error internal server error string
Name In Type Required Description action query string true specify action repo query string true repository name
Enumerated Values
Parameter Value action toggleBookmark action toggleStar
Example responses
200 Response
\"string\"\n
Responses
Status Meaning Description Schema 200 OK ok string 400 Bad Request bad request\". string 403 Forbidden forbidden string 404 Not Found not found string 500 Internal Server Error internal server error string
Name In Type Required Description name path string true repository name
Example responses
202 Response
\"string\"\n
Responses
Status Meaning Description Schema 202 Accepted accepted string 401 Unauthorized unauthorized string 404 Not Found not found string 500 Internal Server Error internal server error string
Response Headers
Status Header Type Format Description 202 Location string /v2/{name}/blobs/uploads/{session_id} 202 Range string 0-0
*Get an image's blob/layer upload given a session_id
Parameters
Name In Type Required Description name path string true repository name session_id path string true upload session_id
Example responses
204 Response
\"string\"\n
Responses
Status Meaning Description Schema 204 No Content no content string 404 Not Found not found string 500 Internal Server Error internal server error string
Resume an image's blob/layer upload given an session_id
Parameters
Name In Type Required Description name path string true repository name session_id path string true upload session_id
Example responses
202 Response
\"string\"\n
Responses
Status Meaning Description Schema 202 Accepted accepted string 400 Bad Request bad request string 404 Not Found not found string 416 Range Not Satisfiable range not satisfiable string 500 Internal Server Error internal server error string
Response Headers
Status Header Type Format Description 202 Location string /v2/{name}/blobs/uploads/{session_id} 202 Range string 0-128
Update and finish an image's blob/layer upload given a digest
Parameters
Name In Type Required Description name path string true repository name session_id path string true upload session_id digest query string true blob/layer digest
Example responses
201 Response
\"string\"\n
Responses
Status Meaning Description Schema 201 Created created string 404 Not Found not found string 500 Internal Server Error internal server error string
Update an image's manifest given a reference or a digest
Parameters
Name In Type Required Description name path string true repository name reference path string true image reference or digest
Example responses
201 Response
\"string\"\n
Responses
Status Meaning Description Schema 201 Created created string 400 Bad Request bad request string 404 Not Found not found string 500 Internal Server Error internal server error string
Name In Type Required Description name path string true repository name n query integer true limit entries for pagination last query string true last tag value for pagination
Status Meaning Description Schema 200 OK OK common.ImageTags 400 Bad Request bad request\". string 404 Not Found not found string
This operation does not require authentication
"},{"location":"developer-guide/api-user-guide/","title":"Using the zot API","text":"
This document describes how to use the zot REST API and provides a number of examples.
For comprehensive details of all zot API commands, see Viewing the complete zot API reference.
The zot API implements the OCI Distribution endpoints along with additional endpoints for supported extensions. You can access the REST API at the same URL and port number used by the GUI and by datapath tools.
The examples in this article assume that the zot registry is located at localhost:8080.
"},{"location":"developer-guide/api-user-guide/#supported-api-endpoints","title":"Supported API endpoints","text":"
The following is a list of zot API endpoints along with the conditions under which each endpoint is available.
Some API endpoints are available only when a specific extension is enabled in the zot configuration file, or when an extension build label is specified in the make command (for example, make binary EXTENSIONS=ui), or both.
For comprehensive details of the API endpoints, see Viewing the complete zot API reference.
"},{"location":"developer-guide/api-user-guide/#oci-endpoints","title":"OCI endpoints","text":"Endpoint Actions Description /v2/ GET OCI specification endpoints /v2/_catalog GET Lists repositories in a registry. /v2/_oci/ext/discover GET Discover extensions per the OCI specification /v2/{repo}/blobs/{digest} DELETE, GET, HEAD Lists or deletes an image's blob/layer given a digest /v2/{repo}/blobs/uploads POST Creates an image blob/layer upload /v2/{repo}/blobs/uploads/{session_id} DELETE, GET, PATCH, PUT Creates, lists, or deletes an image's blob/layer upload given a session_id /v2/{repo}/manifests/{reference} DELETE, GET, HEAD, PUT Creates, lists, or deletes references for an image /v2/{repo}/referrers/{digest} GET Lists referrers given a digest /v2/{repo}/tags/list GET List all image tags in a repository"},{"location":"developer-guide/api-user-guide/#zot-oci-extension-endpoints","title":"zot OCI extension endpoints","text":"Endpoint Actions Description Availability /v2/_zot/ext/mgmt GET Mgmt extension endpoints Enabled by using the mgmt build label and enabling the search extension in the configuration file. /v2/_zot/ext/notation POST With query parameters, uploads certificates for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the notation option enabled. /v2/_zot/ext/search Enhanced search Enabled by using the search build label and enabling the search extension in the configuration file. /v2/_zot/ext/cosign POST Uploads keys for signature verification Enabled by using the imagetrust build label and enabling the trust extension with the cosign option enabled. /v2/_zot/ext/userprefs PUT User preferences endpoints Enabled by using the userprefs build label and enabling both the search and the ui extensions in the configuration file."},{"location":"developer-guide/api-user-guide/#zot-auth-endpoints","title":"zot auth endpoints","text":"Endpoint Actions Description Availability /zot/auth/apikey DELETE, GET, POST Creates, lists, or deletes API keys Available when API key authentication is enabled in the configuration file (\"apikey\": true). /zot/auth/login POST Opens an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication. /zot/auth/logout POST Ends an API session Available when authentication is available. This includes not only OpenID, but all session-based authentication. /zot/auth/callback/\\<provider> POST Specifies a social authentication service provider for redirecting logins, such as Google or dex. Enabled when an OpenID authentication service provider is specified in the configuration file."},{"location":"developer-guide/api-user-guide/#other-zot-endpoints","title":"other zot endpoints","text":"Endpoint Actions Description Availability /v2/_zot/pprof/ GET Returns a current HTML-format profile list along with a count of currently available records for each profile. See Performance Profiling in zot for usage details. Always enabled. /v2/_zot/debug/graphql-playground# See Using GraphQL for details. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label."},{"location":"developer-guide/api-user-guide/#oras-endpoints","title":"ORAS endpoints","text":"Endpoint Actions Description Availability /oras/artifacts/v1/{repo}/ manifests/{digest}/referrers GET OCI Registry As Storage (ORAS) endpoints Always enabled."},{"location":"developer-guide/api-user-guide/#prometheus-endpoint","title":"prometheus endpoint","text":"Endpoint Actions Description Availability /metrics GET Returns extended metrics for monitoring by prometheus Enabled when the metrics extension is enabled in the configuration file."},{"location":"developer-guide/api-user-guide/#openapi-swagger-endpoints","title":"OpenAPI (swagger) endpoints","text":"
This endpoint is accessed with a browser.
Endpoint Action Description Availability /swagger/v2/ (browser) Displays an interactive OpenAPI (swagger) API reference. Enabled only in a binary-debug zot build or when the zot registry has been built with the debug extension label."},{"location":"developer-guide/api-user-guide/#api-authentication","title":"API authentication","text":"
If zot authentication is not configured, any user can access the zot API.
When pushing and pulling images using API calls, your identity can be authenticated by either a password or an API key.
With a valid password, you can specify your credentials in a cURL request as shown in this example:
curl -u <user>:<password> -X GET http://<server>/<endpoint>\n
An API key has advantages in situations where the primary zot authentication does not use the command line, such as a GUI login or social login. Also, you can reduce your security exposure by using an API key instead of your broader credentials, such as an LDAP username and password.
"},{"location":"developer-guide/api-user-guide/#using-api-keys","title":"Using API keys","text":""},{"location":"developer-guide/api-user-guide/#enabling-api-keys","title":"Enabling API keys","text":"
To enable the use of API keys, you must set the apikey attribute to true in the zot configuration file, as shown in the following example:
"},{"location":"developer-guide/api-user-guide/#creating-your-api-key","title":"Creating your API key","text":"
Before you can create or revoke an API key, you must first log in using a different authentication mechanism, such as logging in through the zot GUI. When you are logged in, you can create an API key for your identity using the following API command:
The API key (apiKey) is shown to the user only in the command output when the key is created. It cannot be later retrieved from zot with any other command.
"},{"location":"developer-guide/api-user-guide/#using-your-api-key-in-an-api-command","title":"Using your API key in an API command","text":"
The API key replaces a password in the API command, as shown in the following cURL example:
"},{"location":"developer-guide/api-user-guide/#uploading-a-certificate-for-notation","title":"Uploading a certificate for Notation","text":"
To upload a certificate for notation, use the following endpoint:
POST /v2/_zot/ext/notation\n
cURL command example:
curl --data-binary @certificate.crt -X POST \"http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca\"\n
"},{"location":"developer-guide/api-user-guide/#viewing-the-complete-zot-api-reference","title":"Viewing the complete zot API reference","text":"
You can find comprehensive details of all zot API commands in either of the following locations:
As text descriptions in the zot API Command Reference in the zot documentation.
As an interactive OpenAPI (swagger) JSON file in the zot Github project.
There are many ways to view a swagger file as an interactive document. If you have the npm package installed, for example, you can execute the following command:
$ npx open-swagger-ui swagger.json\n
This command creates a local web server at localhost:3355 where you can interact with the API reference using a browser.
"},{"location":"developer-guide/contributing/","title":"Contributing to zot Development","text":"
The zot project is built for developers by developers. The zot project welcomes the participation of the open source community in extending and improving zot.
zot is released under the Apache License 2.0. All contributions must adhere to this license and must explicitly state adherence.
"},{"location":"developer-guide/contributing/#submitting-a-pull-request-pr","title":"Submitting a Pull Request (PR)","text":"
First, fork the zot project on GitHub and submit a commit to your fork. Then open a new pull request (PR) to the zot project. All pull requests must meet these requirements:
License statement
Either the commit message or the PR description must contain the following statement:
\"By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.\"
Developer Certificate of Origin (DCO) and sign-off
All commits require a Developer Certificate of Origin via the \"Signed-off-by:\" commit message and commit signatures using GPG keys. Include the -s flag in your git commit command.
Commit message format
The commit message must follow the Convention Commits format. The message must begin with a keyword that categorizes the commit, followed by a colon. Validation of a commit message is determined by this expression:
An example of a valid commit message is \"docs: Fixes a typo in module.md.\"
In addition, any new PR requires a brief form to be completed by the submitter with details about the PR. Appropriate code owners are automatically identified and will be notified of the new PR.
We take code quality very seriously. All PRs must pass various CI/CD checks that enforce code quality such as code coverage, security scanning, performance regressions, distribution spec conformance, ecosystem client tool compatibility, etc.
Issues are broadly classified as functional bugs and security issues. The latter is treated a little differently due to the sensitive nature.
"},{"location":"developer-guide/contributing/#filing-a-functional-issue","title":"Filing a Functional Issue","text":"
No software is perfect, and we expect users to find issues with the zot code base. First, check whether your issue has already been filed by someone else by performing an issue search. If the issue is not found, file a new issue by clicking the New issue button on the zot/issues page and answering the questions. The more information that you can provide, the easier it becomes to triage the issue.
"},{"location":"developer-guide/contributing/#filing-a-security-issue","title":"Filing a Security Issue","text":"
Security issues are best filed by sending an email to security@zotregistry.dev. After 45 days, we will make the issue public and give credit to the original filer of the issue.
"},{"location":"developer-guide/contributing/#code-of-conduct","title":"Code of Conduct","text":"
To report a conduct-related incident occurring on the zot project, contact the zot project conduct committee by sending an email to conduct@zotregistry.dev. You can expect a response within three business days.
"},{"location":"developer-guide/extensions-dev/","title":"Developing New Extensions","text":"
You can add new functionality to the zot registry by developing extensions for integration into zot.
The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.
When planning the development of a new extension, be sure to familiarize yourself with the OCI documentation and guidelines for extensions.
The following extensions are currently available in the zot project:
metrics
sync
search
scrub
lint
You can examine the implementation of these extensions in the zot project extensions section. The operation and configuration of the current extensions is described in Configuring zot.
"},{"location":"developer-guide/extensions-dev/#guidelines-for-developing-new-extensions","title":"Guidelines for developing new extensions","text":"
Each file to be included in the binary for only a specific extension must contain the following syntax at the beginning of the file. For example, a file to be included in the build for extension foo must begin with the following lines:
- The first line (`//go:build foo`) is added automatically by the linter if not already present.\n\n- The second line and the third (blank) line are mandatory.\n
For each file that contains functions specific to the extension, create a corresponding \"no-op\" file that contains exactly the same function names. In this file:
Each function is a \"no-op,\" performing no action other than to return a \"success\" value if expected.
We recommend naming this \"no-op\" file by appending -disabled to the name of the original file. For example, if the extension is implemented by extension-foo.go, the corresponding \"no-op\" file could be named extension-foo-disabled.go.
The first two lines declare an \"anti-tag\" (for example, !foo). In the foo extension example, the \"no-op\" file will be included in binaries that don't implement the foo extension, but won't be included in binaries that implement the foo extension. The foo example \"no-op\" file begins with the following lines:
See extension lint-disabled.go in the zot project for an example of a \"no-op\" file.
When developing a new extension, you should create a blackbox test in which a binary containing the new extension can be tested in a usage scenario. See the test/blackbox folder in the zot project for examples of extension tests.
Create targets in Makefile for newly added blackbox tests. You should also add them as GitHub Workflows in .github/workflows/ecosystem-tools.yaml in the zot project.
When configuring multiple extensions in the extensions section of the zot configuration file, list new extensions after the current extensions in the recommended order, such as:
"},{"location":"developer-guide/extensions-dev/#building-zot-with-extensions","title":"Building zot with extensions","text":"
When you build the full zot image (for example, make binary), all extensions listed in the EXTENSIONS variable in Makefile are included in the build. When you've created a new extension, you must modify the EXTENSIONS variable in Makefile by adding the new extension.
To build an image with only selected extensions, you can specify the desired extensions by declaring them in the build command:
make binary EXTENSIONS=extension1,extension2,extension3...\n
For example, to build with only sync and scrub, the command would be:
make binary EXTENSIONS=sync,scrub\n
"},{"location":"developer-guide/onboarding/","title":"Onboarding zot for Development","text":"
zot is a production-ready, open-source, extensible OCI-native image registry, built for developers by developers.
Development is officially supported on Linux and Apple MacOS platforms. However, development should be possible on any platform that supports the golang toolchain.
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS (Apple M1)
Follow the golang instructions to install the golang toolchain. After installation, make sure that the path environment variable or your IDE can find the toolchain.
You must use a golang version of at least the minimum specified in go.mod or the build will fail.
To build zot, execute the make command in the zot directory using the following general syntax:
$ make OS=os ARCH=architecture {binary | binary-minimal}
The operating system and architecture options are listed in the Supported platforms and architectures table. If an option is not specified, the defaults are linux and amd64.
The binary option builds the full zot binary image with all extensions.
The binary-minimal option builds the minimal distribution-spec conformant zot binary image without extensions, reducing the attack surface.
For example, to build a zot image with extensions for an Intel-based linux server, use the following command:
make OS=linux ARCH=amd64 binary\n
The make command builds an executable image in the zot/bin directory. The original filename of the zot executable image will indicate the build options. For example, the filename of an Intel-based linux minimal image is zot-minimal-linux-amd64.
Click here to view an example of the getting started process.
To produce a zot binary that includes extensive debugging information, build zot with the binary-debug option, as shown in this example:
make OS=linux ARCH=amd64 binary-debug\n
You can then attach and run a debugging tool such as Delve to the running zot process.
Delve is a powerful open-source debugger for the Go programming language. Downloads and documentation for Delve are available on GitHub at https://github.com/go-delve/delve.
Performance profiling capabilities within zot allow a zot administrator to collect and export a range of diagnostic performance data such as CPU intensive function calls, memory allocations, and execution traces. The collected data can then be analyzed using Go tools and a variety of available visualization tools.
For detailed information about performance profiling, see Performance Profiling in zot.
/\n- pkg/ # Source code for all libraries\n - api/ # Source code for HTTP APIs\n - config/ # Global configuration model\n - storage/ # Source code for storage backends\n - cli/ # Source code for command line interface (cli)\n - common/ # Source code for common utility routines\n - compliance/ # Source code for dist-spec conformance tests\n - log/ # Source code for logging framework\n - test/ # Internal test scripts/data\n - extensions/ # Source code for all extensions\n - config/\n - sync/\n - monitoring/\n - sync/\n - exporter/ # Source code for metrics exporter\n- cmd/ # Source code for binary main()s\n - zot/ # Source code for zot binary\n - zli/ # Source code for zot cli\n - zb/ # Source code for zb, the dist-spec benchmarking tool\n- errors/ # Source code for error codes\n- examples/ # Configuration examples\n- swagger/ # Swagger integration\n- docs/ # Documentation\n
"},{"location":"developer-guide/onboarding/#additional-state-in-zot","title":"Additional state in zot","text":"
In addition to the storage of repository images, zot stores data for various processes in local and remote storage and databases. The following table shows the storage locations for different processes and types of data.
Data or Process Storage Location Description images local andAWS S3 Image blobs repository synchronization local/<repo_name>/.sync The sync operation temporarily copies the upstream blobs to: /<repo_name>/.sync/${UUID}/<repo_name>, then copies to /<repo_name> and deletes the temporary directory ${UUID} deduplication local/cache.db Cache for deduplication of files stored locally AWS DynamoDB Cache for deduplication of files stored in AWS CVE local/_trivy Database of Common Vulnerabilities and Exposures (CVE) information and scan results user sessions local/_sessions zot user session authentication (for zui) PKI authentication documents local/_cosign Private keys for signature verification using cosign local/_notation Certificates for signature verification using notation metadata local/repo.db Local storage of manifests, configurations, download counters, signature verification results AWS DynamoDB Cloud storage of manifests, configurations, download counters, signature verification results"},{"location":"general/architecture/","title":"Architecture","text":"
zot is an OCI-native container image registry. This document discusses the design goals, the overall architecture, and the design choices made in the implementation of the design goals.
HTTP APIs strictly conforms to the OCI Distribution Specification
zot intends to be a production reference implementation for the OCI Distribution Specification. In fact, zot does not support any other vendor protocol or specification.
Storage layout follows the OCI Image Specification
The default and only supported storage layout is the OCI Image Layout. The implications of this choice are that any OCI image layout can be served by zot and conversely, zot converts data on-the-wire into an OCI image layout.
zot is a single binary image with all features included so that deployment is extremely simple in various environments, including bare-metal, cloud, and embedded devices. Behavior is controlled by a single configuration file.
"},{"location":"general/architecture/#enable-only-what-you-need","title":"Enable Only What You Need","text":"
A clear separation exists between (1) the core OCI-compliant HTTP APIs and storage functionality, and (2) other add-on features modeled as extensions. The extension features can be selectively enabled both at build-time and run-time.
For more information, see \"Conditional Builds\" in zot's security posture document.
External interaction with zot consists of the following two types:
Client-initiated data or meta-data queries
Admin-initiated configuration
All client-side interaction occurs over HTTP APIs. The core data path queries are governed by the OCI Distribution Specification. All additional meta-data queries are handled based on the setting of the search extension:
If the search extension is enabled, enhanced registry searching and filtering is supported, using graphQL. A database is maintained by zot to efficiently answer complex queries on data stored in the database.
If the search extension is not enabled, basic queries are supported using the core APIs. These queries are less efficient and search actual storage, which is limited in content.
A single configuration file governs zot instance behavior. An exception can be made for security concerns, wherein configuration items containing sensitive credentials can be stored in separate files referenced by the main configuration file. Using separate files allows stricter permissions to be enforced on those files if stored locally. Also, modeling as external files allows for storing Kubernetes Secrets.
The configuration file is divided into sections for http, storage, log, and extension, governing the behavior of the respective components.
"},{"location":"general/architecture/#authentication-and-authorization","title":"Authentication and Authorization","text":"
A robust set of authentication and authorization options are supported natively in zot. These controls are enforced before access is allowed into the storage layer.
For more information, see User Authentication and Authorization with zot.
zot supports any modern local filesystem. Remote filesystems, such as AWS S3 or any AWS S3-compatible storage system, are supported. Additional driver support is planned in the roadmap.
Deduplication is supported for both local and remote filesystems, but deduplication requires a filesystem with hard-link support.
For more information, see Storage Planning with zot.
zot integrates with the trivy security scanner to scan container images for vulnerabilities. The database is kept current by periodically downloading any vulnerability database updates at a configurable interval. The user remains agnostic of the actual scanner implementation, which may change over time.
Several periodic tasks occur in the registry, such as garbage collection, sync mirroring, and scrubbing. A task scheduler handles these tasks in the background, taking care not to degrade or interrupt foreground tasks running in the context of HTTP APIs.
"},{"location":"general/concepts/","title":"Concepts","text":""},{"location":"general/concepts/#what-is-zot","title":"What is zot?","text":"
zot is a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.
Two broad trends are changing how we build, distribute, and consume software. The first trend is the increasing adoption of container technologies. The second trend is that software solutions are being composed by combining elements from various sources rather than being built entirely from scratch. The latter trend raises the importance of software provenance and supply chain security. In both trends, zot intends to play an important role by providing a production-ready, open-source, vendor-neutral container image registry server based purely on OCI standards.
"},{"location":"general/concepts/#what-is-an-oci-image-registry","title":"What is an OCI image registry?","text":"
An OCI image registry is a server-based application that allows you to store, manage, and share container images. A developer uploads (pushes) an image to the registry for distribution. Users can then download (pull) the image to run on their systems. The OCI Distribution Specification, published by the Open Container Initiative (OCI), defines a standard API protocol for these and other image registry operations.
An image registry can be a part of your continuous integration and continuous deployment (CI/CD) pipeline when you host zot on your public or private server. In its minimal form, you can also embed a zot registry in a product. In either case, zot provides a secure software supply chain for container images.
zot = OCI Distribution Specification + OCI Image Format
At its heart, zot is a production-ready, vendor-neutral OCI image registry with images stored in the OCI image format and with the OCI distribution specification on-the-wire. zot is built for developers by developers, offering features such as minimal deployment using a single binary image, built-in authentication and authorization, and inline garbage collection and storage deduplication.
Some of the principal advantages of zot are:
Open source
OCI standards-only both on-the-wire and on-disk
Clear separation between core distribution spec and zot-specific extensions
Software supply chain security, including support for cosign and notation
Security hardening
Single binary with many features built-in
Suitable for deployments in cloud, bare-metal, and embedded devices
zot fully conforms to the OCI Distribution Specification.
The following table lists additional advantages of zot:
Distribution Spec conformance yes CNCF project accepted as a Sandbox Project License Apache 2.0 On-premises deployment yes OCI conformance* yes Single binary image* yes Minimal build* yes Storage Layout OCI v1 Image Layout Authentication built-in Authorization built-in Garbage collection inline Storage deduplication inline Cloud storage support yes Delete by tag yes Vulnerability scanning built-in Command line interface (cli) yes UI yes External contributions beta available Image signatures built-in
* The minimal build feature is the ability to build a minimal Distribution Spec compliant registry in order to reduce library dependencies and the possible attack surface.
The OCI Distribution Specification supports extending the functionality of an OCI-compliant registry implementation by adding extensions. Extensions are new APIs developed outside of the core OCI specs. Developers may propose their extensions to the OCI for possible future addition to the Distribution Specification.
Wherever applicable, extensions can be dynamically discovered using the extensions support of the OCI Distribution Specification.
Extension features of zot are available only with a full zot image. They are excluded from the minimal zot image.
"},{"location":"general/extensions/#extensions-implemented-in-zot","title":"Extensions implemented in zot","text":"
The extensions implemented in zot include administrator-configured functionality and end-user features.
Currently, search, trust, and userprefs are the only zot extensions operable by end users. Only these extensions are accessible through HTTP APIs and are discoverable using the OCI extensions mechanism.
The following extensions are currently supported by zot:
One of the key functions of a container image registry (which is essentially a graph of blobs) is the ability to perform interesting image and graph traversal queries. The user interacts with the search extension via a graphQL endpoint. The schema is published with every release.
Examples of queries are:
\"Does an image exist?\"
\"What is its size?\"
\"Does an image depend on this image via its layers?\"
\"What vulnerabilities exist in an image or its dependent images?\"
You can deploy a local mirror pointing to an upstream zot instance with various container image download policies, including on-demand and periodic downloads. The sync function is useful to avoid overwhelming the upstream instance, or if the upstream instance has rate-limited access.
The lint extension helps to avoid image compliance issues by enforcing certain policies about the image or the image metadata. Currently, lint can check an uploaded image to enforce the presence of required annotations such as the author or the license.
Although container images are content-addressable with their SHA256 checksums, and validations are performed during storage and retrieval, it is possible that bit-rot sets in when not in use. The scrub extension actively scans container images in the background to proactively detect errors.
Images stored in zot can be signed with a digital signature to verify the source and integrity of the image. The digital signature can be verified by zot using public keys or certificates uploaded by the user through the zot API. The trust extension enables and configures this function.
The metrics extension adds a node exporter, which is not present in the minimal build.
"},{"location":"general/extensions/#graphical-user-interface","title":"Graphical user interface","text":"
Using the zot graphical user interface (GUI), you can browse a zot registry for container images and artifacts. From the web interface, you can copy the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.
The userprefs extension provides an API endpoint for adding configurable user preferences for a repository. This custom extension, not a part of the OCI distribution, is accessible only by authenticated users of the registry. Unauthenticated users are denied access.
The functions currently implemented by this extension include:
Toggling the star (favorites) icon for a repository.
Toggling the bookmark icon for a repository.
For information about configuring zot extensions, see Configuring zot.
"},{"location":"general/features/","title":"Summary of Key Features","text":"
Conforms to OCI distribution spec APIs
Uses OCI image layout for image storage
Can serve any OCI image layout as a registry
Single binary for all the features
Doesn't require root privileges
Clear separation between core dist-spec and zot-specific extensions
Supports container image signatures - cosign and notation
Supports helm charts
Behavior controlled via configuration
Binaries released for multiple operating systems and architectures
Supports advanced image queries using search extension
Supports image deletion by tag
Currently suitable for on-premises deployments (e.g. colocated with Kubernetes)
Compatible with ecosystem tools such as skopeo and cri-o
Vulnerability scanning of images
TLS support Authentication via:
TLS mutual authentication
HTTP Basic (local htpasswd and LDAP)
HTTP Bearer token
Supports Identity-Based Access Control
Supports live modifications on the configuration file while zot is running (Authorization configuration only)
Inline storage optimizations:
Automatic garbage collection of orphaned blobs
Layer deduplication using hard links when content is identical
Data scrubbing
Serve multiple storage paths (and backends) using a single zot server
Pull and synchronize from other dist-spec conformant registries
Supports rate limiting including per HTTP method
Metrics with Prometheus
Using a node exporter in case of minimal zot
Swagger based documentation
zli: command-line client support
zb: a benchmarking tool for dist-spec conformant registries
Released under Apache 2.0 License
"},{"location":"general/glossary/","title":"Glossary","text":""},{"location":"general/glossary/#documentation-icons","title":"Documentation Icons","text":"Icon Description Note \u2014 A point of emphasis or caution. Tip \u2014 A helpful suggestion or a reference to additional material not covered in this document. Warning \u2014 A suggestion or advisory intended to avoid a loss of service or data."},{"location":"general/glossary/#definitions","title":"Definitions","text":"Term Description artifact A file of any kind produced during a container build process or associated with the operation of a container. For example, a Helm chart is an artifact that might be stored along with a container. CNCF As part of the Linux Foundation, the Cloud Native Computing Foundation provides support, oversight, and direction for open-source, cloud native projects. cosign cosign is a tool that performs container signing, verification, and storage in an OCI registry. cosigned cosigned is an image admission controller that validates container images before deploying them. cri-o cri-o is an implementation of the Kubernetes Container Runtime Interface (CRI) to enable using OCI compatible runtimes. It is a lightweight alternative to using Docker as the runtime for Kubernetes. deduplication A storage space saving feature wherein only a single copy of specific content is maintained on disk while many different image manifests may hold references to that same content. digest A hashed checksum, such as SHA-256, for verifying the integrity of the downloaded image. Distribution Specification The OCI Distribution Specification project defines an API protocol to facilitate and standardize the distribution of content. extensions Additional registry features (APIs) that are not a part of the Distribution Specification can be added as Extensions. helm chart A helm chart is a package of files that orchestrate the deployment of Kubernetes resources into a Kubernetes cluster. manifest An image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system. node exporter A software component that collects hardware and operating system level metrics exposed by the kernel. OCI The Open Container Initiative (OCI) is an open governance structure for the express purpose of creating open industry standards around container formats and runtimes. ORAS OCI Registry as Storage (ORAS) is a tool for distributing OCI artifacts across OCI registries. prometheus Prometheus is a node exporter that exposes a wide variety of hardware- and kernel-related metrics. referrer An image containing a non-nil subject field with a descriptor to the referred image. registry A service that stores and distributes container images and artifacts. repository A collection of images with the same name, differentiated by tags. skopeo skopeo is a command line utility that performs various operations on container images and image repositories. stacker stacker is a standalone tool for building OCI images via a declarative yaml format. The output of the build process is a container image in an OCI layout. tag A label applied to an image that distinguishes the image from other images in the same repository. A common example is a version tag. zb A benchmarking tool, available as a zot companion binary, for benchmarking a zot registry or any other container image registry that conforms to the OCI Distribution Specification. zli A zot companion binary that implements a set of command line commands for interacting with the zot registry server. zui A zot companion binary that implements a graphical user interface (GUI) for interacting with the zot registry server. zxp A node exporter, available as a zot companion binary, that can be deployed with a minimal zot image in order to scrape metrics from the zot server."},{"location":"general/project/","title":"About the zot Project","text":""},{"location":"general/project/#project-repository","title":"Project Repository","text":"
"},{"location":"general/releases/","title":"Released Images for zot","text":"
This document describes the available zot images for the various supported hardware and software platforms, along with information about image variations, image locations, and image naming formats.
zot is supported on Linux and Apple MacOS platforms with Intel or ARM processors.
Table: Supported platforms and architectures
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS (Apple M1) freebsd amd64 Intel-based FreeBSD* freebsd arm64 ARM-based FreeBSD*
**NOTE:* While binary images are available for FreeBSD, building container images is not supported at this time."},{"location":"general/releases/#full-and-minimal-binary-images","title":"Full and minimal binary images","text":"
In addition to variations for specific platforms and architectures, binary images are also available in full and minimal flavors:
A full zot binary image is compiled with all extensions. Extensions include functions such as metrics, registry synchronization, search, and scrub.
A minimal distribution-spec conformant zot binary image is compiled with only a minimal set of code and libraries, reducing the attack surface. This option might be optimal for a registry embedded in a shipping product.
An executable binary image for zot is named using the target platform and architecture from the Supported platforms and architectures table. The general format of a binary image file name is one of these two:
zot-<os>-<architecture>
A full zot binary image with all extensions has a filename of the form zot-<os>-<architecture>. For example, the full binary image for an Intel-based linux server is zot-linux-amd64.
zot-<os>-<architecture>-minimal
A minimal distribution-spec conformant zot binary image has a filename of the form zot-<os>-<architecture>-minimal. For example, the minimal binary image for an Intel-based linux server is zot-linux-amd64-minimal.
For convenience, you can rename the binary image file to simply zot after downloading.
"},{"location":"general/releases/#where-to-get-zot","title":"Where to get zot","text":"
You can download native executable binary images or container (Docker) images.
The zot project is hosted on GitHub at project-zot.
To download a binary image, go to the zot releases and select a release. Go to the Assets section of the release page and download the binary for your platform and architecture.
You may need to use the chmod command to make the image executable.
When downloading a binary image for MacOS, download the darwin image.
It is now possible to bisect CVEs (zli cve diff) between two image tags/versions in the same repository. Furthermore, a CVE query for a particular image tag can return a detailed description of CVEs.
"},{"location":"general/whats-new/#documentation-for-immutable-image-tags","title":"Documentation for \"Immutable Image Tags\"","text":"
A new article has been added to document how image tags can be made immutable.
"},{"location":"general/whats-new/#cross-repo-tag-search-in-ui","title":"Cross-repo tag search in UI","text":"
You can now search for a tag across all repos by starting your query as ':' in the UI, which will return all images that have that tag."},{"location":"general/whats-new/#support-for-oras-artifacts-removed","title":"Support for ORAS Artifacts removed","text":"
OCI distribution spec 1.1.0 has added support \"artifacts\" which is likely to gain wider adoption. ORAS artifacts are not widely used or supported.
:warning: Support is removed starting from this version.\n
"},{"location":"general/whats-new/#v201","title":"v2.0.1","text":""},{"location":"general/whats-new/#support-for-hot-reloading-of-ldap-credentials-file","title":"Support for hot reloading of LDAP credentials file","text":"
Since v2.0.0, LDAP credentials have been specified in a separate file. Starting with this version, the file is watched and changes applied without restarting zot.
"},{"location":"general/whats-new/#bugfixes-and-performance-improvements","title":"Bugfixes and performance improvements","text":"
Under some configurations, zot consumes significant CPU and memory resources. This has been fixed in this release.
Support is added for OCI Distribution Spec v1.1.0-rc3 and OCI Image Spec v1.1.0-rc4. The OCI changes are summarized here. These specifications allow arbitrary artifact types and references so that software supply chain use cases can be supported (SBOMs, signatures, etc). Currently, oras and regclient support this spec.
For a demonstration of an end-to-end OCI artifacts workflow, see Software Provenance Workflow Using OCI Artifacts.
Support is deprecated for earlier OCI release candidates.
Using the new zot GUI, you can browse a zot registry for container images and artifacts. The web interface provides the shell commands for downloading an image using popular third-party tools such as docker, podman, and skopeo.
"},{"location":"general/whats-new/#support-for-social-logins","title":"Support for social logins","text":"
Support is added for OpenID authentication with GitHub, Google, and dex.
"},{"location":"general/whats-new/#group-policies-for-authorization","title":"Group policies for authorization","text":"
When creating authorization policies, you can assign multiple users to a named group. A group-specific authorization policy can then be defined, specifying allowed access and actions for the group.
Configuration syntax change: In the previous release, authorization policies were defined directly under the accessControl key in the zot configuration file. With the new ability to create authorization groups, it becomes necessary to add a new repositories key below accessControl. Beginning with zot v2.0.0, the set of authorization policies are now defined under the repositories key.
The validity of an image's signature can be verified by zot. Users can upload public keys or certificates to zot.
"},{"location":"general/whats-new/#ldap-credentials-stored-separately-from-configuration","title":"LDAP credentials stored separately from configuration","text":"
The LDAP credentials are removed from zot's LDAP configuration and stored in a separate file. See zot's LDAP documentation.
This LDAP configuration change is incompatible with previous zot releases. When upgrading, you must reconfigure your LDAP credentials if you use LDAP.
"},{"location":"general/whats-new/#storage-deduplication-on-startup","title":"Storage deduplication on startup","text":"
Deduplication, a storage space saving feature, now runs or reverts at startup depending on whether the feature is enabled or disabled. You can trigger deduplication by enabling it and then restarting zot.
In the zot GUI, you can bookmark an image so that it can be easily found later. Bookmarked images appear in search queries when the bookmarked option is enabled.
"},{"location":"general/whats-new/#ability-to-delete-tags-from-the-ui","title":"Ability to delete tags from the UI","text":""},{"location":"general/whats-new/#command-line-search","title":"Command line search","text":"
The zli search command allows smart searching for a repository by its name or for an image by its repo:tag.
"},{"location":"general/whats-new/#search-by-digest","title":"Search by digest","text":"
You can perform a global search for a digest (SHA hash) using either the UI or the CLI. This function is useful when an issue is found in a layer that is used by multiple images. In the UI Search box, for example, begin typing sha256: followed by a partial or complete digest value to see a dropdown list of images that contain the layer with the digest value.
"},{"location":"general/whats-new/#graphql-support-for-search","title":"GraphQL support for search","text":"
A GraphQL backend server within zot's registry search engine provides efficient and enhanced search capabilities. In addition to supporting direct GraphQL queries through the API, zot hosts the GraphQL Playground, which provides an interactive graphical environment for GraphQL queries.
"},{"location":"general/whats-new/#scheduling-of-background-tasks","title":"Scheduling of background tasks","text":"
You can adjust the background scheduler based on your deployment requirements for tasks that are handled in the background, such as garbage collection. See Configuring zot.
"},{"location":"general/whats-new/#performance-profiling-for-troubleshooting","title":"Performance profiling for troubleshooting","text":"
You can use zot's built-in profiling tools to collect and analyze runtime performance data.
"},{"location":"general/whats-new/#binaries-for-freebsd","title":"Binaries for FreeBSD","text":"
zot binary images are available for the FreeBSD operating system. Supported architectures are amd64 and arm64.
\u00a0zot container images for FreeBSD will be available in a future release.
The two types of state (images and image metadata) can both now be on remote storage so that zot process lifecycle and its storage can be managed and scaled independently.
"},{"location":"general/whats-new/#digest-collision-detection-during-image-deletion","title":"Digest Collision Detection During Image Deletion","text":"
When two or more image tags point to the same image digest and the image is deleted by digest causes data loss and dangling references. A new behavior-based policy called detectManifestCollision was added to prevent this.
"},{"location":"install-guides/install-guide-k8s/","title":"Installing zot with Kubernetes and Helm","text":"
Using Kubernetes with Helm charts for zot, you can easily deploy zot as an application in a Kubernetes cluster.
"},{"location":"install-guides/install-guide-k8s/#before-you-begin","title":"Before you begin","text":""},{"location":"install-guides/install-guide-k8s/#prerequisites","title":"Prerequisites","text":"
kubectl must be installed and a Kubernetes cluster must be ready.
Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.
"},{"location":"install-guides/install-guide-k8s/#installing-zot","title":"Installing zot","text":""},{"location":"install-guides/install-guide-k8s/#step-1-locate-the-helm-charts-in-a-remote-repository","title":"Step 1: Locate the Helm charts in a remote repository","text":"
Specify a remote repository that contains the Helm charts for zot. Give the repo a local name, such as project-zot, as in this example:
\"project-zot\" has been added to your repositories\n
The Helm charts for zot are currently hosted in these publicly-accessible repositories: - zotregistry.dev - artifacthub.io
Search the repository to see the Helm charts for zot installation. Search using the keyword 'project-zot' or 'zot', as in this example:
helm search repo project-zot
NAME CHART VERSION APP VERSION DESCRIPTION\nproject-zot/zot <chart-version> v2.1.0 A Helm chart for Kubernetes\n
The APP VERSION is the version/tag of the zot image used for the deployment.
Update to the latest information of available charts from the chart repository, as shown in this example:
helm repo update project-zot
Hang tight while we grab the latest from your chart repositories...\n...Successfully got an update from the \"project-zot\" chart repository\nUpdate Complete. \u2388Happy Helming!\u2388\n
Display the default information of the Helm chart, as shown in this example:
helm show all project-zot/zot
apiVersion: v2\n appVersion: v2.1.0\n description: A Helm chart for Kubernetes\n name: zot\n type: application\n version: <chart-version>\n\n # Default values for zot.\n # This is a YAML-formatted file.\n # Declare variables to be passed into your templates.\n replicaCount: 1\n image:\n repository: ghcr.io/project-zot/zot-linux-amd64\n pullPolicy: IfNotPresent\n tag: \"v2.1.0\"\n serviceAccount:\n create: true\n annotations: {}\n name: \"\"\n service:\n type: NodePort\n port: 5000\n
"},{"location":"install-guides/install-guide-k8s/#step-2-determine-any-needed-changes-from-the-helm-charts-defaults","title":"Step 2: Determine any needed changes from the Helm chart\u2019s defaults","text":"
Inspect the default information of the Helm chart, as shown in the previous step. In many cases, the default chart values may be acceptable. If your installation requires any non-default settings, you may be able to specify them during the installation. Not all chart values are configurable, but you can display those that are configurable using the command in the following example:
helm show values project-zot/zot
# Default values for zot.\n # This is a YAML-formatted file.\n # Declare variables to be passed into your templates.\n replicaCount: 1\n image:\n repository: ghcr.io/project-zot/zot-linux-amd64\n pullPolicy: IfNotPresent\n tag: \"v2.1.0\"\n serviceAccount:\n create: true\n annotations: {}\n name: \"\"\n service:\n type: NodePort\n port: 5000\n
The configurable settings in the chart are listed in the following table:
parameter description
replicaCount
Desired number of replicas of the application
image.repository
Repository and image name for the application
image.pullPolicy
Whether to pull the image from the repository. If not specified, the policy depends on image.tag:
If tag is :latest or no tag: Always
If tag is other than :latest: IfNotPresent
image.tag
Identifies different versions the image. default is the chart appVersion.
Examples: :latest (the default) or :v2.1.0
serviceAccount.create
Specifies whether a service account should be created
serviceAccount.annotations
Annotations to add to the service account
serviceAccount.name
Name of the service account to use. If name is not set and create is true, a name is generated using the fullname template.
service.type
ClusterIP (default), NodePort, LoadBalancer, ExternalName, or Headless
You can change multiple settings with one --set statement. For example, you might want your installation to have more replicas or a different port number:
--set replicaCount=2,service.port=5050
"},{"location":"install-guides/install-guide-k8s/#customizing-the-helm-chart-using-a-file","title":"Customizing the Helm chart using a file","text":"
You can also create a YAML file with your overrides and then add the new file by adding the -f flag to the helm install command. For example, to override the replica count and port number, the contents of your YAML file (for example, \"myfile.yaml\") would be:
replicaCount: 2\nservice:\n port: 5050\n
and the following flag would be added to the helm install command:
Install zot using the helm install command. The first example shows how to perform a default installation. The additional examples show different ways to modify the helm install command to override default settings in the Helm chart:
Example 1: use default chart parameters
helm install zot project-zot/zot
NAME: zot\nLAST DEPLOYED: Thu Aug 11 19:13:02 2022\nNAMESPACE: default\nSTATUS: deployed\nREVISION: 1\nNOTES:\n Get the application URL by running these commands:\n export NODE_PORT=$(kubectl get --namespace default -o jsonpath=\"{.spec.ports[0].nodePort}\" services zot)\n export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath=\"{.items[0].status.addresses[0].address}\")\n echo http://$NODE_IP:$NODE_PORT\n
Example 2: modify specific chart parameters with 'set'
helm install --set replicaCount=2,service.port=5050 zot project-zot/zot
Example 3: modify specific chart parameters with a file
helm install -f myfile.yaml zot project-zot/zot
Example 4: use a specific version of the Helm chart
helm install zot project-zot/zot --version 0.1.0
Example 5: link to a kubeconfig file
helm install zot project-zot/zot --kubeconfig $HOME/.kube/config
"},{"location":"install-guides/install-guide-k8s/#after-the-installation","title":"After the installation","text":""},{"location":"install-guides/install-guide-k8s/#verify-the-installation","title":"Verify the installation","text":"
List all releases that are either deployed or failed.
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION\nzot default 1 <datetime> deployed <chart-version> v2.1.0\n
This response indicates that zot is deployed.
After making sure that your pods are up and running, execute the following commands:
Should you need to uninstall zot, use the helm uninstall command, as in this example:
helm uninstall zot
"},{"location":"install-guides/install-guide-linux/","title":"Installing zot on Bare Metal Linux","text":"
Using an available executable zot image, you can easily deploy zot on a Linux server.
"},{"location":"install-guides/install-guide-linux/#before-you-begin","title":"Before you begin","text":""},{"location":"install-guides/install-guide-linux/#about-binary-images","title":"About binary images","text":"
Executable binary zot images are available for multiple platforms and architectures and with full or minimal implementations.
Refer to Released Images for zot for information about available zot images along with information about image variations, image locations, and image naming formats.
"},{"location":"install-guides/install-guide-linux/#installation","title":"Installation","text":""},{"location":"install-guides/install-guide-linux/#step-1-get-zot","title":"Step 1: Get zot","text":"
Using wget, download the appropriate zot binary image for your platform from the zot GitHub project. Download the image to the`/usr/bin/` directory and rename it to zot, as in this example:
"},{"location":"install-guides/install-guide-linux/#step-2-create-a-zot-configuration-file","title":"Step 2: Create a zot configuration file","text":"
Create a zot configuration file as /etc/zot/config.json.
See Configuration file options for an example file with options and recommendations. You can find other configuration file examples in the zot GitHub project and in Configuring zot.
"},{"location":"install-guides/install-guide-linux/#step-3-configure-a-local-authentication-account","title":"Step 3: Configure a local authentication account","text":"
If you want to use local authentication with zot, create a /etc/zot/htpasswd file with an initial account entry using the htpasswd command as in this example:
"},{"location":"install-guides/install-guide-linux/#step-4-define-the-zot-service","title":"Step 4: Define the zot service","text":"
Create a /etc/systemd/system/zot.service file to define the zot service in systemd. The following is an example service file for zot:
[Unit]\nDescription=OCI Distribution Registry\nDocumentation=https://zotregistry.dev/\nAfter=network.target auditd.service local-fs.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/zot serve /etc/zot/config.json\nRestart=on-failure\nUser=zot\nGroup=zot\nLimitNOFILE=500000\nMemoryHigh=30G\nMemoryMax=32G\n\n[Install]\nWantedBy=multi-user.target\n
Be sure to configure a dedicated non-root user ID as the User and Group in the zot service definition. The 'zot' user ID in this example is created in the next step.
"},{"location":"install-guides/install-guide-linux/#step-5-create-a-user-id-to-own-the-zot-service","title":"Step 5: Create a user ID to own the zot service","text":"
Create a non-root user ID to be the owner of the zot service and its resources.
In this example, the user ID 'zot' is created with the adduser command, and resource ownership is assigned.
With the adduser options shown, the 'zot' user ID has no local directory. There is no ability to log into the zot user account, and the account has no finger information.
When the zot service has started, you can check its status with this command:
sudo systemctl status zot\n
"},{"location":"install-guides/install-guide-linux/#after-the-installation","title":"After the installation","text":"
If your zot registry server is public facing, we recommend that you test your TLS configuration using a service such as the Qualys SSL Server Test.
Refer to Configuring zot for further information about maintaining your zot registry server.
"},{"location":"install-guides/install-guide-linux/#configuration-file-options-and-recommendations","title":"Configuration file options and recommendations","text":"
The following zot configuration file (config.json) can be used as a template for your own installation. You can modify this file to suit your own environment.
The example file enables registry synchronization with two other container registries. In the example, the zot server synchronizes with the Google and Docker container registries, as shown here:
"},{"location":"user-guides/user-guide-datapath/","title":"Push and Pull Image Content","text":"
zot is an OCI image registry that allows you to store, manage, and share container images.
A zot registry can store and serve a variety of content, but the type of content may dictate your choice of a client tool.
For various content types, this document shows examples of using a third-party client tool that supports the content. The following table shows which content and client tools are demonstrated.
"},{"location":"user-guides/user-guide-datapath/#pull-an-oci-image-to-a-private-docker-registry","title":"Pull an OCI image to a private docker registry","text":"
This example pulls the latest container image for the busybox application and stores the image to a local private docker registry.
In these examples, authentication is disabled for the source and destination. You can enable authentication by changing the command line options as follows:
--src-tls-verify=true\n--dest-tls-verify=true\n
You can also add credentials for authenticating with a source or destination repository:
"},{"location":"user-guides/user-guide-datapath/#common-tasks-using-regclient-for-oci-images","title":"Common tasks using regclient for OCI images","text":"
regclient is a client interface that performs various operations on OCI container images and image repositories. The command line interface for regclient is regctl.
For detailed information about regctl commands, see the regctl Documentation.
"},{"location":"user-guides/user-guide-datapath/#push-an-oci-image_1","title":"Push an OCI image","text":"
This example pushes version 1.20 of golang to a tools repository within the registry.
In the preceding examples, TLS authentication with the zot registry was disabled by the following command:
$ regctl registry set --tls=disabled localhost:5000\n
This command allows regctl to accept an HTTP response from the zot server. If TLS authentication is enabled on the zot registry server, you can omit this command from your regctl session.
"},{"location":"user-guides/user-guide-datapath/#common-tasks-using-oras-for-oci-artifacts","title":"Common tasks using oras for OCI artifacts","text":"
ORAS (OCI Registry As Storage) is a command line client for storing OCI artifacts on OCI repositories.
For detailed information about the oras commands in these examples, see the ORAS CLI documentation.
"},{"location":"user-guides/user-guide-datapath/#push-an-artifact","title":"Push an artifact","text":"
This example pushes version 2 of an artifact file named hello-artifact to a zot registry.
You will be prompted to manually enter a password.
"},{"location":"user-guides/user-guide-datapath/#common-tasks-using-crane-for-oci-images","title":"Common tasks using crane for OCI images","text":"
crane is an open-source project that provides a command-line interface (CLI) for interacting with container registries, such as Docker Hub and Google Container Registry.
For detailed information about crane commands, see the crane Documentation.
"},{"location":"user-guides/user-guide-datapath/#push-an-oci-image_2","title":"Push an OCI image","text":"
This example pushes the latest container image for the alpine application to a registry.
"},{"location":"user-guides/user-guide-datapath/#copy-an-oci-image-to-a-private-docker-registry","title":"Copy an OCI image to a private docker registry","text":"
This example pulls the latest container image for the alpine application and stores the image to a local private docker registry.
To authenticate with the registry server, log in at the start of your session using the following command:
$ crane auth login -u myUsername localhost:5000\n
"},{"location":"user-guides/user-guide-gui/","title":"Use the Web Interface to Find Images","text":"
Using a browser, you can browse a zot repository for container images and artifacts. The web interface also provides the commands for downloading an image using popular third-party tools.
If a zot registry is built with the optional zui package, the registry has a web interface.
"},{"location":"user-guides/user-guide-gui/#access-the-registry","title":"Access the registry","text":"
Depending on the security configuration of the zot registry, you might need to authenticate before being given access.
The initial page of the registry displays a sampling of the most popular images and recently updated images. To view all available images in the registry, click the View all link in the upper right of the page to go to the /explore page.
Wherever an image name appears, two icons follow the name, indicating the results of the vulnerability scan and the signature status. These icons are described in Icons and their meanings.
"},{"location":"user-guides/user-guide-gui/#find-an-image","title":"Find an image","text":"
To assist you in finding images specific to your requirements, the /explore page provides several sorting options along with faceted navigation in addition to a general search box.
Sorting criteria include relevance, most recently updated, alphabetical, and most downloaded.
Navigation facets include operating system, CPU architecture, and signature status.
When you locate the desired image, click its tile.
"},{"location":"user-guides/user-guide-gui/#inspect-the-image-properties","title":"Inspect the image properties","text":"
The OVERVIEW tab of the initial image description page contains a brief description of the image along with several details, such as the repository URL, number of downloads, last published, size, and license type.
Click the TAGS tab to view the available versions of the image.
Click the tag link of the desired version of the image. In the resulting page, you can view detailed information about the image, including its digest hash, and you can obtain a command to pull the image from the repository.
Tabs on this page provide the following information:
Tab Description LAYERS The build command and the digest hash USES A list of images used by this image USED BY A list of images that use this image VULNERABILITIES A list of known vulnerabilities
From the LAYERS tab, click Details to view an example of the image build command and the layer's digest hash.
"},{"location":"user-guides/user-guide-gui/#pull-an-image","title":"Pull an image","text":"
After opening the tag link of the desired image, click the Pull Image drop-down list to display the available pull commands. Docker, podman, and skopeo image management tools are supported.
Select a tool and click the pages icon next to the command to copy the full command to your clipboard. An example of the pull command using podman is:
To mark an image so that it can be easily found later, click the bookmark icon on the image page. Bookmarked images appear in search queries when the Bookmarked option is enabled.
The bookmark icon before selection:
The bookmark icon after selection:
"},{"location":"user-guides/user-guide-gui/#icons-and-their-meanings","title":"Icons and their meanings","text":"
These icons appear next to the image name, indicating the results of the vulnerability scan and the signature status.
Icon Description A vulnerability scan of the image found no vulnerabilities A vulnerability scan of the image failed(See severity icon in VULNERABILITIES tab) Critical severity High severity Medium severity Low severity The image signature is verified The image signature is not verified The image is not bookmarked by the user The image is bookmarked by the user"},{"location":"user-guides/zli/","title":"Using the command line interface (zli)","text":"
zli: The command line tool for zot servers
"},{"location":"user-guides/zli/#what-is-zli","title":"What is zli?","text":"
zli is a binary that implements a set of command line commands for interacting with the zot registry server.
We recommend installing zli when you install zot.
"},{"location":"user-guides/zli/#how-to-get-zli","title":"How to get zli","text":"
zli is hosted with zot on GitHub at project-zot. From GitHub, you can download the zli binary or you can build zli from the source.
zli is supported for the following operating systems and platform architectures:
OS ARCH Platform linux amd64 Intel-based Linux servers linux arm64 ARM-based servers and Raspberry Pi4 darwin amd64 Intel-based MacOS darwin arm64 ARM-based MacOS"},{"location":"user-guides/zli/#downloading-zli-binaries","title":"Downloading zli binaries","text":"
You can download the executable binary for your server platform and architecture under \"Assets\" on the GitHub zot releases page.
The binary image is named using the OS and architecture from the Supported platforms table. For example, the binary for an Intel-based MacOS server is zli-darwin-amd64.
"},{"location":"user-guides/zli/#building-zli-from-source","title":"Building zli from source","text":"
To build the zli binary, copy or clone the zot project from GitHub and execute the make cli command in the zot directory. Use the same command options that you used to build zot, as shown:
make OS=os ARCH=architecture cli
For example, the following command builds zli for an Intel-based MacOS server:
make OS=darwin ARCH=amd64 cli\n
In this example, the resulting executable file is zli-darwin-amd64 in the zot/bin directory.
"},{"location":"user-guides/zli/#common-tasks-using-zli","title":"Common tasks using zli","text":"
This section includes examples of common zot server tasks using the zli command line interface. For a detailed listing of zli commands, see the zli Command Reference in this guide.
The original filename of the zli executable file will reflect the build options, such as zli-linux-amd64. For convenience, you can rename the executable to simply zli. The instructions and examples in this guide use zli as the name of the executable file.
"},{"location":"user-guides/zli/#adding-a-zot-server-url","title":"Adding a zot server URL","text":"
You can modify the zot server configuration using the zli config add command. This example adds a zot server URL with an alias of remote-zot:
You can list all images hosted on a zot server using the zli image list command with the server\u2019s alias:
$ bin/zli image list --config local\n\nREPOSITORY TAG OS/ARCH DIGEST SIGNED SIZE \nalpine latest linux/amd64 3fc10231 false 84MB \nbusybox latest linux/amd64 9172c5f6 false 2.2MB\n
You can also filter the image list to view a specific image by specifying the image name:
$ bin/zli image name busybox:latest --config local\n\nREPOSITORY TAG OS/ARCH DIGEST SIGNED SIZE \nbusybox latest linux/amd64 9172c5f6 false 2.2MB\n
"},{"location":"user-guides/zli/#scanning-images-for-known-vulnerabilities","title":"Scanning images for known vulnerabilities","text":"
Using the zli cve list command, you can fetch the CVE (Common Vulnerabilities and Exposures) information for images hosted on the zot server. This example shows how to learn which images are affected by a specific CVE:
$ bin/zli cve affected CVE-2017-9935 --config remote-zot\n\nIMAGE NAME TAG DIGEST SIZE\nc3/openjdk-dev commit-5be4d92 ac3762e2 335MB\n
This example displays a list of all CVEs affecting a specific image:
$ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot\n\nID SEVERITY TITLE\nCVE-2015-8540 LOW libpng: underflow read in png_check_keyword()\nCVE-2017-16826 LOW binutils: Invalid memory access in the coff_s...\n
This example (--verbose) displays a list of all CVEs affecting a specific image with details:
$ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot --verbose\nLOW 2, UNKNOWN 1, TOTAL 3\n\nCVE-2015-8540\n...\n
Note that the details may display the package path in the image when the information is available.
This example displays the detailed CVEs in JSON format:
$ bin/zli cve list c3/openjdk-dev:0.3.19 --config remote-zot -f json\n{\n \"Tag\": \"0.3.19\",\n \"CVEList\": [\n {\n \"Id\": \"CVE-2019-17006\",\n \"Severity\": \"MEDIUM\",\n \"Title\": \"nss: Check length of inputs for cryptographic primitives\",\n \"Description\": \"A vulnerability was discovered in nss where input text length was not checked when using certain cryptographic primitives. This could lead to a heap-buffer overflow resulting in a crash and data leak. The highest threat is to confidentiality and integrity of data as well as system availability.\",\n \"PackageList\": [\n {\n \"Name\": \"nss\",\n \"InstalledVersion\": \"3.44.0-7.el7_7\",\n \"FixedVersion\": \"Not Specified\"\n },\n {\n \"Name\": \"nss-sysinit\",\n \"InstalledVersion\": \"3.44.0-7.el7_7\",\n \"FixedVersion\": \"Not Specified\"\n },\n {\n \"Name\": \"nss-tools\",\n \"InstalledVersion\": \"3.44.0-7.el7_7\",\n \"FixedVersion\": \"Not Specified\"\n }]\n }]\n}\n
This example lists all images on a specific zot server that are affected by a specific CVE:
$ bin/zli cve affected --config remote-zot CVE-2017-9935 --repo c3/openjdk-dev\n\nIMAGE NAME TAG DIGEST SIZE\nc3/openjdk-dev commit-2674e8a 71046748 338MB\nc3/openjdk-dev commit-bd5cc94 0ab7fc76\n
This example lists all images on a specific zot server where the CVE has been fixed:
$ bin/zli cve fixed c3/openjdk-dev CVE-2017-9935 --config remote-zot\n\nIMAGE NAME TAG DIGEST SIZE\nc3/openjdk-dev commit-2674e8a-squashfs b545b8ba 321MB\nc3/openjdk-dev commit-d5024ec-squashfs cd45f8cf 321MB\n
This example lists all CVEs that have been found in one image and not the other:
$ bin/zli cve diff c3/openjdk-dev:1.0.0 c3/openjdk-dev:2.0.0 --config remote-zot\n\nID SEVERITY TITLE\nCVE-2015-8540 LOW libpng: underflow read in png_check_keyword()\nCVE-2017-16826 LOW binutils: Invalid memory access in the coff_s...\n
For example, the above query lists all CVEs that have been found in c3/openjdk-dev:1.0.0 but not in c3/openjdk-dev:2.0.0
"},{"location":"user-guides/zli/#searching-for-repositories-and-images","title":"Searching for repositories and images","text":"
You can locate repositories and images hosted on a zot server using the zli search command.
To search for a repository, specify the full name with a colon or a partial name with no colon.
To search for an image, specify the full repository name followed by the tag or a prefix of the tag.
This example searches the zot registry named 'local' for a repository whose name contains the substring 'ng':
$ bin/zli search query ng --config local\n\nNAME SIZE LAST UPDATED DOWNLOADS STARS\nnginx 794MB 2023-03-01 18:44:17.707690369 +0000 UTC 0 0\nmongo 232MB 2022-10-18 15:03:40.7646203 +0300 +0300 0 0\ngolang 1.1GB 2023-06-22 00:32:38.613354854 +0000 UTC 0 0\n
This example searches the zot registry named 'local' for a repository named 'nginx'. Because the repository name is followed by a colon, the search results must match the name exactly.
"},{"location":"user-guides/zli/#sorting-the-output-of-a-zli-command","title":"Sorting the output of a zli command","text":"
For a zli command that can result in a lengthy output list, you can use the command flag --sort-by <option> to cause the output to be sorted by a specified property of the output data. The available sorting criteria vary for different commands, but examples of sorting criteria options are described in the following table:
flag option criteria alpha-asc alphabetical, ascending alpha-dsc alphabetical, descending relevance quality of match severity severity of condition update-time timestamp
For a given command that results in an output list, you can see the available sorting criteria in the usage information returned by the --help flag. For example, bin/zli image name --help returns usage information containing the following line under \"Flags\":
--sort-by string Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default \"alpha-asc\")
According to this information, the list of image names returned by the bin/zli image name command can be sorted in order of alphabetical ascending, alphabetical descending, or the timestamp of the latest update of the image. The default sorting method for this command, if no --sort-by flag is present, is alphabetical ascending.
This section provides detailed usage information for basic first-level zli commands. Many zli commands also support subcommands, which are listed as \"Available Commands\" in each command description. For example, zli search can be extended with either the query or subject subcommand. To see the detailed usage for each subcommand, type the command with the subcommand and append --help, such as zli search query --help. The zli search description below includes the subcommand help as an example.
$ bin/zli --help\n\nUsage:\n zli [flags]\n zli [command]\n\nAvailable Commands:\n completion Generate the autocompletion script for the specified shell\n config Configure zot registry parameters for CLI\n cve Lookup CVEs in images hosted on the zot registry\n help Help about any command\n image List images hosted on the zot registry\n repo List all repositories\n search Search images and their tags\n\nFlags:\n -h, --help help for zli\n -v, --version show the version and exit\n\nUse \"zli [command] --help\" for more information about a command.\n
This command generates the autocompletion script for zli for the specified shell. See each subcommand\u2019s help for details on how to use the generated script.
$ bin/zli completion --help\n\nUsage:\n zli completion [command]\n\nAvailable Commands:\n bash Generate the autocompletion script for bash\n fish Generate the autocompletion script for fish\n powershell Generate the autocompletion script for powershell\n zsh Generate the autocompletion script for zsh\n\nFlags:\n -h, --help help for completion\n\nUse \"zli completion [command] --help\" for more information about a command.\n
This command configures zot registry parameters for CLI.
$ bin/zli config --help\n\nUsage:\n zli config <config-name> [variable] [value] [flags]\n zli config [command]\n\nExamples:\n zli config add main https://zot-foo.com:8080\n zli config --list\n zli config main url\n zli config main --list\n zli config remove main\n\nAvailable Commands:\n add Add configuration for a zot registry\n remove Remove configuration for a zot registry\n\nFlags:\n -h, --help help for config\n -l, --list List configurations\n --reset Reset a variable value\n\nUse \"zli config [command] --help\" for more information about a command.\n\nUseful variables:\n url zot server URL\n showspinner show spinner while loading data [true/false]\n verify-tls enable TLS certificate verification of the server [default: true]\n
This command lists CVEs (Common Vulnerabilities and Exposures) of images hosted on the zot registry
$ ./zli cve --help\n\nUsage:\n zli cve [command]\n\nAvailable Commands:\n affected List images affected by a CVE\n fixed List tags where a CVE is fixedRetryWithContext\n list List CVEs by REPO:TAG or REPO@DIGEST\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n -h, --help help for cve\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nUse \"zli cve [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
This command lists images hosted on the zot registry.
$ ./zli image --help\n\nUsage:\n zli image [command]\n\nAvailable Commands:\n base List images that are base for the given image\n cve List all CVE's of the image\n derived List images that are derived from given image\n digest List images that contain a blob(manifest, config or layer) with the given digest\n list List all images\n name List image details by name\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n -h, --help help for image\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nUse \"zli image [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
This command lists all repositories in the zot registry.
$ ./zli repo --help\n\nUsage:\n zli repo [command]\n\nAvailable Commands:\n list List all repositories\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -h, --help help for repo\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n\nUse \"zli repo [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
The search command allows smart searching for a repository by its name or for an image by its repo:tag.
$ ./zli search --help\n\nSearch repos or images\n\nUsage:\n zli search [command]\n\nAvailable Commands:\n query Fuzzy search for repos and their tags.\n subject List all referrers for this subject.\n\nFlags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n -h, --help help for search\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nUse \"zli search [command] --help\" for more information about a command.\n\nRun 'zli config -h' for details on [config-name] argument\n
$ ./zli search query --help\n\nUsage:\n zli search query [repo]|[repo:tag] [flags]\n\nExamples:\n# For repo search specify a substring of the repo name without the tag\n zli search query \"test/repo\"\n\n# For image search specify the full repo name followed by the tag or a prefix of the tag.\n zli search query \"test/repo:2.1.\"\n\nFlags:\n -h, --help help for query\n --sort-by string Options for sorting the output: [relevance, update-time, alpha-asc, alpha-dsc] (default \"relevance\")\n\nGlobal Flags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nRun 'zli config -h' for details on [config-name] argument\n
$ ./zli search subject --help\n\nList all referrers for this subject. The subject can be specified by tag(repo:tag) or by digest\" or (repo@digest)\n\nUsage:\n zli search subject [repo:tag]|[repo@digest] [flags]\n\nExamples:\n# For referrers search specify the referred subject using it's full digest or tag:\n zli search subject \"repo@sha256:f9a0981...\"\n zli search subject \"repo:tag\"\n\nFlags:\n -h, --help help for subject\n --sort-by string Options for sorting the output: [update-time, alpha-asc, alpha-dsc] (default \"alpha-asc\")\n\nGlobal Flags:\n --config string Specify the registry configuration to use for connection\n --debug Show debug output\n -f, --format string Specify output format [text/json/yaml]\n --url string Specify zot server URL if config-name is not mentioned\n -u, --user string User Credentials of zot server in \"username:password\" format\n --verbose Show verbose output\n\nRun 'zli config -h' for details on [config-name] argument\n
"}]}
\ No newline at end of file
diff --git a/v2.1.0/sitemap.xml.gz b/v2.1.0/sitemap.xml.gz
index d6b57b1..390aec3 100644
Binary files a/v2.1.0/sitemap.xml.gz and b/v2.1.0/sitemap.xml.gz differ
diff --git a/versions.json b/versions.json
index 7a50599..6b74148 100644
--- a/versions.json
+++ b/versions.json
@@ -1 +1 @@
-[{"version": "v2.1.0", "title": "v2.1.0", "aliases": ["latest", "zot"]}, {"version": "v2.0.4", "title": "v2.0.4", "aliases": []}, {"version": "v2.0.3", "title": "v2.0.3", "aliases": []}, {"version": "v2.0.2", "title": "v2.0.2", "aliases": []}, {"version": "v2.0.1", "title": "v2.0.1", "aliases": []}, {"version": "v2.0.0", "title": "v2.0.0", "aliases": []}, {"version": "v1.4.3", "title": "v1.4.3", "aliases": []}]
\ No newline at end of file
+[{"version": "v2.1.0", "title": "v2.1.0", "aliases": ["zot", "latest"]}, {"version": "v2.0.4", "title": "v2.0.4", "aliases": []}, {"version": "v2.0.3", "title": "v2.0.3", "aliases": []}, {"version": "v2.0.2", "title": "v2.0.2", "aliases": []}, {"version": "v2.0.1", "title": "v2.0.1", "aliases": []}, {"version": "v2.0.0", "title": "v2.0.0", "aliases": []}, {"version": "v1.4.3", "title": "v1.4.3", "aliases": []}]
\ No newline at end of file