From 8c4ef4e1acbc24e7a8a1c3f8fc9bd63b91d1faab Mon Sep 17 00:00:00 2001 From: rchincha Date: Thu, 22 Feb 2024 02:11:58 +0000 Subject: [PATCH] Deployed 9d8c6e5 to v2.0.1 with MkDocs 1.4.2 and mike 1.1.2 --- v2.0.1/404.html | 2 +- .../admin-configuration/index.html | 2 +- .../admin-getting-started/index.html | 2 +- v2.0.1/articles/authn-authz/index.html | 8 +- .../articles/benchmarking-with-zb/index.html | 2 +- .../building-ci-cd-pipeline/index.html | 2 +- v2.0.1/articles/clustering/index.html | 2 +- v2.0.1/articles/graphql/index.html | 2 +- v2.0.1/articles/kind-deploy/index.html | 2 +- v2.0.1/articles/mirroring/index.html | 2 +- v2.0.1/articles/monitoring/index.html | 2 +- v2.0.1/articles/pprofiling/index.html | 2 +- v2.0.1/articles/retention/index.html | 2 +- v2.0.1/articles/security-posture/index.html | 2 +- v2.0.1/articles/storage/index.html | 2 +- .../articles/verifying-signatures/index.html | 2 +- v2.0.1/articles/workflow/index.html | 2 +- .../developer-guide/api-reference/index.html | 2 +- .../developer-guide/api-user-guide/index.html | 2 +- .../developer-guide/contributing/index.html | 2 +- .../developer-guide/extensions-dev/index.html | 2 +- v2.0.1/developer-guide/onboarding/index.html | 2 +- v2.0.1/general/architecture/index.html | 2 +- v2.0.1/general/concepts/index.html | 2 +- v2.0.1/general/extensions/index.html | 2 +- v2.0.1/general/features/index.html | 2 +- v2.0.1/general/glossary/index.html | 2 +- v2.0.1/general/project/index.html | 2 +- v2.0.1/general/releases/index.html | 2 +- v2.0.1/general/whats-new/index.html | 2 +- v2.0.1/index.html | 2 +- .../install-guide-k8s/index.html | 4 +- .../install-guide-linux/index.html | 13 ++-- v2.0.1/pdf/document.pdf | Bin 5613037 -> 5642280 bytes v2.0.1/search/search_index.json | 2 +- v2.0.1/sitemap.xml | 70 +++++++++--------- v2.0.1/sitemap.xml.gz | Bin 552 -> 552 bytes .../user-guide-datapath/index.html | 2 +- v2.0.1/user-guides/user-guide-gui/index.html | 2 +- v2.0.1/user-guides/zli/index.html | 2 +- versions.json | 2 +- 41 files changed, 84 insertions(+), 81 deletions(-) diff --git a/v2.0.1/404.html b/v2.0.1/404.html index c3c135f..7bd6ad3 100644 --- a/v2.0.1/404.html +++ b/v2.0.1/404.html @@ -1 +1 @@ - zotregistry.dev
\ No newline at end of file + zotregistry.dev
\ No newline at end of file diff --git a/v2.0.1/admin-guide/admin-configuration/index.html b/v2.0.1/admin-guide/admin-configuration/index.html index 2f3b2af..a70550b 100644 --- a/v2.0.1/admin-guide/admin-configuration/index.html +++ b/v2.0.1/admin-guide/admin-configuration/index.html @@ -118,4 +118,4 @@

Toggle repository bookmark

This action sets the repository bookmark property to true if it is false, and to false if it is true.

Action Parameter Parameter Description
toggleBookmark repo The name of the repository whose bookmark is to be changed

This example toggles a bookmark on a repository named repoName:

PUT
 http://localhost:5000/v2/_zot/ext/userprefs?
 action=toggleBookmark&repo=repoName
-

Verifying the configuration file

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>


Last update: October 12, 2023
\ No newline at end of file +

Verifying the configuration file

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>


Last update: October 12, 2023
\ No newline at end of file diff --git a/v2.0.1/admin-guide/admin-getting-started/index.html b/v2.0.1/admin-guide/admin-getting-started/index.html index 244446e..7b0cca4 100644 --- a/v2.0.1/admin-guide/admin-getting-started/index.html +++ b/v2.0.1/admin-guide/admin-getting-started/index.html @@ -16,4 +16,4 @@ -v $(pwd)/custom-config.yml:/etc/zot/config.yml \ -v $(pwd)/registry:/tmp/zot \ zot:latest -

This command causes the registry to listen on port 8080 and to use /tmp/zot for content storage.

We recommend that, when deploying zot, you also install the command line (zli) and benchmarking (zb) packages.

Launching zot

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.

Next Steps

Configuring zot

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.


Last update: September 13, 2023
\ No newline at end of file +

This command causes the registry to listen on port 8080 and to use /tmp/zot for content storage.

We recommend that, when deploying zot, you also install the command line (zli) and benchmarking (zb) packages.

Launching zot

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.

Next Steps

Configuring zot

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.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/authn-authz/index.html b/v2.0.1/articles/authn-authz/index.html index b155202..1319fb0 100644 --- a/v2.0.1/articles/authn-authz/index.html +++ b/v2.0.1/articles/authn-authz/index.html @@ -145,12 +145,12 @@ }

Using Google, GitHub, or GitLab

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:

http://<zot-server>/auth/login?provider=<provider>&callback_ui=<zot-server>/<page>
 

For example, a user logging in to the zot home page using GitHub as the authentication provider sends this URL:

http://zot.example.com:8080/auth/login?provider=github&callback_ui=http://zot.example.com:8080/home
-

Based on the specified provider, zot redirects the login to a provider service with the following URL:

http://<zot-server>/auth/callback/<provider>
-

For the GitHub authentication example:

http://zot.example.com:8080/auth/callback/github
+

Based on the specified provider, zot redirects the login to a provider service with the following URL:

http://<zot-server>/zot/auth/callback/<provider>
+

For the GitHub authentication example:

http://zot.example.com:8080/zot/auth/callback/github
 

✏ If your network policy doesn't allow inbound connections, the callback will not work and this authentication method will fail.

Using dex

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:

staticClients:
   - id: zot-client
     redirectURIs:
-      - 'http://zot.example.com:8080/auth/callback/oidc'
+      - 'http://zot.example.com:8080/zot/auth/callback/oidc'
     name: 'zot'
     secret: ZXhhbXBsZS1hcHAtc2VjcmV0
 

In the zot configuration file, configure dex as an OpenID auth provider as in the following example:

  "http": {
@@ -185,4 +185,4 @@
       }
     }
   }
-

Last update: November 21, 2023
\ No newline at end of file +
Last update: February 5, 2024
\ No newline at end of file diff --git a/v2.0.1/articles/benchmarking-with-zb/index.html b/v2.0.1/articles/benchmarking-with-zb/index.html index a36324c..74c69b0 100644 --- a/v2.0.1/articles/benchmarking-with-zb/index.html +++ b/v2.0.1/articles/benchmarking-with-zb/index.html @@ -51,4 +51,4 @@ p99: 26.375356ms ... -
Last update: December 21, 2022
\ No newline at end of file +
Last update: December 21, 2022
\ No newline at end of file diff --git a/v2.0.1/articles/building-ci-cd-pipeline/index.html b/v2.0.1/articles/building-ci-cd-pipeline/index.html index 4fa6538..444b9d2 100644 --- a/v2.0.1/articles/building-ci-cd-pipeline/index.html +++ b/v2.0.1/articles/building-ci-cd-pipeline/index.html @@ -24,4 +24,4 @@ helm install cosigned -n cosign-system sigstore/cosigned \ --devel --set cosign.secretKeyRef.name=mysecret -
Last update: May 18, 2023
\ No newline at end of file +
Last update: May 18, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/clustering/index.html b/v2.0.1/articles/clustering/index.html index a802ac5..11b9726 100644 --- a/v2.0.1/articles/clustering/index.html +++ b/v2.0.1/articles/clustering/index.html @@ -73,4 +73,4 @@ "level": "debug" } } -
Last update: May 18, 2023
\ No newline at end of file +
Last update: May 18, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/graphql/index.html b/v2.0.1/articles/graphql/index.html index 8e8b6d4..7f91f72 100644 --- a/v2.0.1/articles/graphql/index.html +++ b/v2.0.1/articles/graphql/index.html @@ -595,4 +595,4 @@ ] } } -
Last update: November 15, 2023
\ No newline at end of file +
Last update: November 15, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/kind-deploy/index.html b/v2.0.1/articles/kind-deploy/index.html index 93481f8..8675566 100644 --- a/v2.0.1/articles/kind-deploy/index.html +++ b/v2.0.1/articles/kind-deploy/index.html @@ -121,4 +121,4 @@ kind delete cluster docker stop kind-registry docker rm kind-registry -
Last update: September 13, 2023
\ No newline at end of file +
Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/mirroring/index.html b/v2.0.1/articles/mirroring/index.html index 1fd35a6..b71e0df 100644 --- a/v2.0.1/articles/mirroring/index.html +++ b/v2.0.1/articles/mirroring/index.html @@ -245,4 +245,4 @@ "kube-proxy/kube-proxy" ] } -

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:


Last update: September 13, 2023
\ No newline at end of file +

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:


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/monitoring/index.html b/v2.0.1/articles/monitoring/index.html index 0b9f436..8a447f7 100644 --- a/v2.0.1/articles/monitoring/index.html +++ b/v2.0.1/articles/monitoring/index.html @@ -24,4 +24,4 @@ } } } -

💡 The zxp module does not have Prometheus integration.

The zxp module is not needed with a full zot image.


Last update: September 13, 2023
\ No newline at end of file +

💡 The zxp module does not have Prometheus integration.

The zxp module is not needed with a full zot image.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/pprofiling/index.html b/v2.0.1/articles/pprofiling/index.html index b8aeabf..20f1d03 100644 --- a/v2.0.1/articles/pprofiling/index.html +++ b/v2.0.1/articles/pprofiling/index.html @@ -29,4 +29,4 @@ 2023/09/21 16:58:58 Opening browser. Trace viewer is listening on http://127.0.0.1:62606

The go tool trace command installs and opens a local web server that provides a web interface for viewing and analyzing the trace data.

As an alternative, you can generate a pprof-like profile from the trace file using the following command:

$ go tool trace -pprof=[net|sync|syscall|sched] <filename>
 

For example:

$ go tool trace -pprof=net trace.prof
-

Last update: October 12, 2023
\ No newline at end of file +
Last update: October 12, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/retention/index.html b/v2.0.1/articles/retention/index.html index fbb1124..bb00bfe 100644 --- a/v2.0.1/articles/retention/index.html +++ b/v2.0.1/articles/retention/index.html @@ -96,4 +96,4 @@ "level": "debug" } } -
Last update: November 1, 2023
\ No newline at end of file +
Last update: November 1, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/security-posture/index.html b/v2.0.1/articles/security-posture/index.html index 8b1e410..090fe86 100644 --- a/v2.0.1/articles/security-posture/index.html +++ b/v2.0.1/articles/security-posture/index.html @@ -1 +1 @@ - Security Posture - zotregistry.dev
Skip to content

zot Security Posture

👉 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.

Build-time hardening

The following are the steps taken during build-time.

PIE build-mode

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.

Conditional builds

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.

CI/CD pipeline

zot CI/CD process attempts to align with the Open Source Security Foundation (OSSF) best practices guidelines to achieve high code quality.

Code reviews

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.

CI/CD checks

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.

Runtime hardening

The following steps can be taken to harden a zot deployment.

Unprivileged runtime process

Running zot doesn’t require root privileges. In fact, the recommended approach is to create a separate user/group ID for the zot process.

Authentication

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.

Access control

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.

Vulnerability scans

Apart from hardening the deployment itself, zot also supports security scanning of stored container images.

Reporting security issues

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.


Last update: December 21, 2022
\ No newline at end of file + Security Posture - zotregistry.dev
Skip to content

zot Security Posture

👉 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.

Build-time hardening

The following are the steps taken during build-time.

PIE build-mode

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.

Conditional builds

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.

CI/CD pipeline

zot CI/CD process attempts to align with the Open Source Security Foundation (OSSF) best practices guidelines to achieve high code quality.

Code reviews

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.

CI/CD checks

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.

Runtime hardening

The following steps can be taken to harden a zot deployment.

Unprivileged runtime process

Running zot doesn’t require root privileges. In fact, the recommended approach is to create a separate user/group ID for the zot process.

Authentication

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.

Access control

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.

Vulnerability scans

Apart from hardening the deployment itself, zot also supports security scanning of stored container images.

Reporting security issues

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.


Last update: December 21, 2022
\ No newline at end of file diff --git a/v2.0.1/articles/storage/index.html b/v2.0.1/articles/storage/index.html index 4d37b46..1529285 100644 --- a/v2.0.1/articles/storage/index.html +++ b/v2.0.1/articles/storage/index.html @@ -162,4 +162,4 @@ . } } -

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.


Last update: September 13, 2023
\ No newline at end of file +

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.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/verifying-signatures/index.html b/v2.0.1/articles/verifying-signatures/index.html index fb178f8..dbea199 100644 --- a/v2.0.1/articles/verifying-signatures/index.html +++ b/v2.0.1/articles/verifying-signatures/index.html @@ -83,4 +83,4 @@ } } } -
Last update: September 13, 2023
\ No newline at end of file +
Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/articles/workflow/index.html b/v2.0.1/articles/workflow/index.html index c646794..2c772a3 100644 --- a/v2.0.1/articles/workflow/index.html +++ b/v2.0.1/articles/workflow/index.html @@ -204,4 +204,4 @@ # stop zot zot_teardown -
Last update: October 6, 2023
\ No newline at end of file +
Last update: October 6, 2023
\ No newline at end of file diff --git a/v2.0.1/developer-guide/api-reference/index.html b/v2.0.1/developer-guide/api-reference/index.html index 0306611..c0726ea 100644 --- a/v2.0.1/developer-guide/api-reference/index.html +++ b/v2.0.1/developer-guide/api-reference/index.html @@ -309,4 +309,4 @@ "string" ] } -

Responses

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


Last update: November 17, 2023
\ No newline at end of file +

Responses

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


Last update: November 17, 2023
\ No newline at end of file diff --git a/v2.0.1/developer-guide/api-user-guide/index.html b/v2.0.1/developer-guide/api-user-guide/index.html index 9432143..e946785 100644 --- a/v2.0.1/developer-guide/api-user-guide/index.html +++ b/v2.0.1/developer-guide/api-user-guide/index.html @@ -74,4 +74,4 @@

Uploading a certificate for Notation

To upload a certificate for notation, use the following endpoint:

POST /v2/_zot/ext/notation
 

cURL command example:

curl --data-binary @certificate.crt -X POST "http://localhost:8080/v2/_zot/ext/notation?truststoreType=ca"
 

Viewing the complete zot API reference

You can find comprehensive details of all zot API commands in either of the following locations:

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
-

This command creates a local web server at localhost:3355 where you can interact with the API reference using a browser.


Last update: November 29, 2023
\ No newline at end of file +

This command creates a local web server at localhost:3355 where you can interact with the API reference using a browser.


Last update: November 29, 2023
\ No newline at end of file diff --git a/v2.0.1/developer-guide/contributing/index.html b/v2.0.1/developer-guide/contributing/index.html index c57bd8e..e3d8c30 100644 --- a/v2.0.1/developer-guide/contributing/index.html +++ b/v2.0.1/developer-guide/contributing/index.html @@ -1 +1 @@ - Contributing - zotregistry.dev
Skip to content

Contributing to zot Development

👉 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.

Submission Requirements

Summary: All contributions must meet these requirements:

  • Adhere to the Apache license
  • Be submitted by a pull request (PR) from your fork
  • Commits must have a

License

zot is released under the Apache License 2.0. All contributions must adhere to this license and must explicitly state adherence.

Submitting a Pull Request (PR)

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:

"^((build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.+\))?(!)?(: (.*\s*)*))"

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.

CI/CD Checks

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.

Reporting Issues

Issues are broadly classified as functional bugs and security issues. The latter is treated a little differently due to the sensitive nature.

Filing a Functional Issue

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.

Filing a Security Issue

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.

Code of Conduct

The zot project follows the CNCF Code of Conduct.

Reporting Conduct Incidents

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.


Last update: January 16, 2024
\ No newline at end of file + Contributing - zotregistry.dev
Skip to content

Contributing to zot Development

👉 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.

Submission Requirements

Summary: All contributions must meet these requirements:

  • Adhere to the Apache license
  • Be submitted by a pull request (PR) from your fork
  • Commits must have a

License

zot is released under the Apache License 2.0. All contributions must adhere to this license and must explicitly state adherence.

Submitting a Pull Request (PR)

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:

"^((build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(.+\))?(!)?(: (.*\s*)*))"

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.

CI/CD Checks

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.

Reporting Issues

Issues are broadly classified as functional bugs and security issues. The latter is treated a little differently due to the sensitive nature.

Filing a Functional Issue

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.

Filing a Security Issue

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.

Code of Conduct

The zot project follows the CNCF Code of Conduct.

Reporting Conduct Incidents

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.


Last update: January 16, 2024
\ No newline at end of file diff --git a/v2.0.1/developer-guide/extensions-dev/index.html b/v2.0.1/developer-guide/extensions-dev/index.html index 7b3df20..8216c7a 100644 --- a/v2.0.1/developer-guide/extensions-dev/index.html +++ b/v2.0.1/developer-guide/extensions-dev/index.html @@ -15,4 +15,4 @@ ... See extension lint-disabled.go in the zot project for an example of a "no-op" file.

Building zot with extensions

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...
 

For example, to build with only sync and scrub, the command would be:

make binary EXTENSIONS=sync,scrub
-

Last update: September 13, 2023
\ No newline at end of file +
Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/developer-guide/onboarding/index.html b/v2.0.1/developer-guide/onboarding/index.html index 81438c1..96c29d6 100644 --- a/v2.0.1/developer-guide/onboarding/index.html +++ b/v2.0.1/developer-guide/onboarding/index.html @@ -26,4 +26,4 @@ - examples/ # Configuration examples - swagger/ # Swagger integration - docs/ # Documentation -

Additional state in zot

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 and
AWS 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

Last update: October 12, 2023
\ No newline at end of file +

Additional state in zot

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 and
AWS 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

Last update: October 12, 2023
\ No newline at end of file diff --git a/v2.0.1/general/architecture/index.html b/v2.0.1/general/architecture/index.html index 21fd0a7..c99e2f7 100644 --- a/v2.0.1/general/architecture/index.html +++ b/v2.0.1/general/architecture/index.html @@ -1 +1 @@ - Architecture - zotregistry.dev
Skip to content

Architecture

👉 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.

Design Goals

OCI-first

  • 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.

Single binary model

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.

Enable Only What You Need

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.

Overall Architecture

As shown in the following figure, the architecture of zot is organized as:

👉 zot-full = zot-minimal + extensions

504567.jpg

The minimal build is the core OCI-compliant registry functionality as described by the OCI Distribution Specification.

The full build adds features that are not a part of the Distribution Specification, but are allowed to be added as Extensions.

External Interaction

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.

Configuration

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.

Authentication and Authorization

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.

Storage Driver Support

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.

Security Scanning

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.

Extensions

Additional registry features that are not a part of the Distribution Specification are added as Extensions.

✏ Extension features of zot are available only with a full zot image. They are not supported in a minimal zot image.

For more information about zot's extensions, see Extensions.

Background Tasks

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.


Last update: September 13, 2023
\ No newline at end of file + Architecture - zotregistry.dev
Skip to content

Architecture

👉 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.

Design Goals

OCI-first

  • 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.

Single binary model

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.

Enable Only What You Need

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.

Overall Architecture

As shown in the following figure, the architecture of zot is organized as:

👉 zot-full = zot-minimal + extensions

504567.jpg

The minimal build is the core OCI-compliant registry functionality as described by the OCI Distribution Specification.

The full build adds features that are not a part of the Distribution Specification, but are allowed to be added as Extensions.

External Interaction

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.

Configuration

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.

Authentication and Authorization

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.

Storage Driver Support

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.

Security Scanning

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.

Extensions

Additional registry features that are not a part of the Distribution Specification are added as Extensions.

✏ Extension features of zot are available only with a full zot image. They are not supported in a minimal zot image.

For more information about zot's extensions, see Extensions.

Background Tasks

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.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/general/concepts/index.html b/v2.0.1/general/concepts/index.html index 9326974..1021648 100644 --- a/v2.0.1/general/concepts/index.html +++ b/v2.0.1/general/concepts/index.html @@ -1 +1 @@ - Concepts - zotregistry.dev
Skip to content

Concepts

What is zot?

👉 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.

What is an OCI image registry?

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.

Why zot?

👉 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.

504566

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.


Last update: May 18, 2023
\ No newline at end of file + Concepts - zotregistry.dev
Skip to content

Concepts

What is zot?

👉 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.

What is an OCI image registry?

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.

Why zot?

👉 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.

504566

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.


Last update: May 18, 2023
\ No newline at end of file diff --git a/v2.0.1/general/extensions/index.html b/v2.0.1/general/extensions/index.html index 218bd66..6d9645f 100644 --- a/v2.0.1/general/extensions/index.html +++ b/v2.0.1/general/extensions/index.html @@ -1 +1 @@ - Extensions - zotregistry.dev
Skip to content

Extensions

👉 Extensions provide additional registry features that are not a part of the Distribution Specification.

The following extensions are currently available with zot:

  • Search (enhanced)
  • Sync
  • Lint
  • Scrub
  • Trust
  • Metrics
  • Graphical user interface
  • User preferences

💡 For detailed information about configuring zot extensions, see Configuring zot.

About extensions

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.

Extensions implemented in zot

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?"

Sync

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.

💡 docker.io is supported as an upstream mirror.

Lint

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.

Scrub

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.

Trust

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.

Metrics

The metrics extension adds a node exporter, which is not present in the minimal build.

Graphical user interface

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.

User preferences

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.


Last update: September 13, 2023
\ No newline at end of file + Extensions - zotregistry.dev
Skip to content

Extensions

👉 Extensions provide additional registry features that are not a part of the Distribution Specification.

The following extensions are currently available with zot:

  • Search (enhanced)
  • Sync
  • Lint
  • Scrub
  • Trust
  • Metrics
  • Graphical user interface
  • User preferences

💡 For detailed information about configuring zot extensions, see Configuring zot.

About extensions

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.

Extensions implemented in zot

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?"

Sync

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.

💡 docker.io is supported as an upstream mirror.

Lint

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.

Scrub

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.

Trust

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.

Metrics

The metrics extension adds a node exporter, which is not present in the minimal build.

Graphical user interface

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.

User preferences

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.


Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/general/features/index.html b/v2.0.1/general/features/index.html index 38f614a..cb15da0 100644 --- a/v2.0.1/general/features/index.html +++ b/v2.0.1/general/features/index.html @@ -1 +1 @@ - Key Features - zotregistry.dev
Skip to content

Summary of Key Features

  • 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

Last update: September 13, 2023
\ No newline at end of file + Key Features - zotregistry.dev
Skip to content

Summary of Key Features

  • 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

Last update: September 13, 2023
\ No newline at end of file diff --git a/v2.0.1/general/glossary/index.html b/v2.0.1/general/glossary/index.html index a644e43..2fd4aa7 100644 --- a/v2.0.1/general/glossary/index.html +++ b/v2.0.1/general/glossary/index.html @@ -1 +1 @@ - Glossary - zotregistry.dev
Skip to content

Glossary

Documentation Icons

Icon Description
✏ Note — A point of emphasis or caution.
💡 Tip — A helpful suggestion or a reference to additional material not covered in this document.
⚠ Warning — A suggestion or advisory intended to avoid a loss of service or data.

Definitions

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.

Last update: August 4, 2023
\ No newline at end of file + Glossary - zotregistry.dev
Skip to content

Glossary

Documentation Icons

Icon Description
✏ Note — A point of emphasis or caution.
💡 Tip — A helpful suggestion or a reference to additional material not covered in this document.
⚠ Warning — A suggestion or advisory intended to avoid a loss of service or data.

Definitions

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.

Last update: August 4, 2023
\ No newline at end of file diff --git a/v2.0.1/general/project/index.html b/v2.0.1/general/project/index.html index 78ed1ac..b439ce1 100644 --- a/v2.0.1/general/project/index.html +++ b/v2.0.1/general/project/index.html @@ -1 +1 @@ - About - zotregistry.dev
Skip to content
\ No newline at end of file + About - zotregistry.dev
Skip to content
\ No newline at end of file diff --git a/v2.0.1/general/releases/index.html b/v2.0.1/general/releases/index.html index 61a4830..f633d8c 100644 --- a/v2.0.1/general/releases/index.html +++ b/v2.0.1/general/releases/index.html @@ -1,3 +1,3 @@ Released Images - zotregistry.dev
Skip to content

Released Images for zot

👉 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.

Supported platforms

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.

Full and minimal binary images

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.

Binary image file naming

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.

Where to get zot

You can download native executable binary images or container (Docker) images.

Getting binary 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.

Getting container images

You can download a container image from ghcr.io by forming a URL with the desired image name, such as:

https://ghcr.io/project-zot/zot-<os>-<architecture>[-<build>]
 

If <build> is not specified, the default is full. For example, to download the minimal binary image for an Intel-based linux server. The URL is:

https://ghcr.io/project-zot/zot-linux-amd64-minimal
-

✏ When downloading a container image for MacOS, download the linux image, not the darwin image.

Licensing

zot is released under the Apache License 2.0.


Last update: July 31, 2023
\ No newline at end of file +

✏ When downloading a container image for MacOS, download the linux image, not the darwin image.

Licensing

zot is released under the Apache License 2.0.


Last update: July 31, 2023
\ No newline at end of file diff --git a/v2.0.1/general/whats-new/index.html b/v2.0.1/general/whats-new/index.html index 4494ab9..a6e4e69 100644 --- a/v2.0.1/general/whats-new/index.html +++ b/v2.0.1/general/whats-new/index.html @@ -1 +1 @@ - What's New - zotregistry.dev
Skip to content

What's New

v2.0.1

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.

Bugfixes and performance improvements

Under some configurations, zot consumes significant CPU and memory resources. This has been fixed in this release.

v2.0.0

Updated OCI support

Built-in UI support

  • 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.

Support for social logins

Group policies for authorization

  • 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.

Signature verification

  • The validity of an image's signature can be verified by zot. Users can upload public keys or certificates to zot.

LDAP credentials stored separately from configuration

  • 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.

Storage deduplication on startup

  • 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.

Retention policies

  • To optimize image storage, you can configure tag retention policies to remove images that are no longer needed.

CVE scanning support for image indexes

  • The trivy backend now supports vulnerability scanning of image indexes. Previously, only images were scanned.

Bookmarks

  • 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.

Ability to delete tags from the UI

  • The zli search command allows smart searching for a repository by its name or for an image by its repo:tag.

Search by digest

  • 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.

Scheduling of background tasks

  • 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.

Performance profiling for troubleshooting

Binaries for FreeBSD

  • zot binary images are available for the FreeBSD operating system. Supported architectures are amd64 and arm64.

    ✏  zot container images for FreeBSD will be available in a future release.


v1.4.3

Remote-only Storage Support

  • 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.

Digest Collision Detection During Image Deletion

  • 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.

Last update: January 25, 2024
\ No newline at end of file + What's New - zotregistry.dev
Skip to content

What's New

v2.0.1

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.

Bugfixes and performance improvements

Under some configurations, zot consumes significant CPU and memory resources. This has been fixed in this release.

v2.0.0

Updated OCI support

Built-in UI support

  • 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.

Support for social logins

Group policies for authorization

  • 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.

Signature verification

  • The validity of an image's signature can be verified by zot. Users can upload public keys or certificates to zot.

LDAP credentials stored separately from configuration

  • 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.

Storage deduplication on startup

  • 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.

Retention policies

  • To optimize image storage, you can configure tag retention policies to remove images that are no longer needed.

CVE scanning support for image indexes

  • The trivy backend now supports vulnerability scanning of image indexes. Previously, only images were scanned.

Bookmarks

  • 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.

Ability to delete tags from the UI

  • The zli search command allows smart searching for a repository by its name or for an image by its repo:tag.

Search by digest

  • 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.

Scheduling of background tasks

  • 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.

Performance profiling for troubleshooting

Binaries for FreeBSD

  • zot binary images are available for the FreeBSD operating system. Supported architectures are amd64 and arm64.

    ✏  zot container images for FreeBSD will be available in a future release.


v1.4.3

Remote-only Storage Support

  • 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.

Digest Collision Detection During Image Deletion

  • 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.

Last update: January 25, 2024
\ No newline at end of file diff --git a/v2.0.1/index.html b/v2.0.1/index.html index ea222e4..96b3f71 100644 --- a/v2.0.1/index.html +++ b/v2.0.1/index.html @@ -1 +1 @@ - Zot Registry - zotregistry.dev

Zot Registry

OCI-native container image registry, simplified

  accepted as a CNCF Sandbox Project

@zothub #zot Community

Get Started User Guide

Try out our beta deployment at zothub.io

Pair zot with stacker, an OCI-native Image Builder and other ecosystem tools

OCI-native Image Registry

  • OCI Standards

    Strongly conforms to OCI Standards (Distribution and Image Specifications)

  • Single Binary

    One statically built binary for simplified download and install with no additional dependencies or services.

  • Unprivileged

    Doesn't require elevated privileges on host.

  • Features vs Security

    Separate Full (all features included) or Minimal (stripped for security) builds.

  • Support For Multiple Platforms

    Linux, MacOS, Intel, Arm, Raspberry PI, Cloud, Bare-metal ...

  • Batteries Included

    All features such as security scanning, authentication, authorization, garbage collection, deduplication and so on, included in the same binary.

  • Open Source

    Released as an open source project under Apache2 License.

  • Sponsors

  • Adopters

+ Zot Registry - zotregistry.dev

Zot Registry

OCI-native container image registry, simplified

  accepted as a CNCF Sandbox Project

@zothub #zot Community

Get Started User Guide

Try out our beta deployment at zothub.io

Pair zot with stacker, an OCI-native Image Builder and other ecosystem tools

OCI-native Image Registry

  • OCI Standards

    Strongly conforms to OCI Standards (Distribution and Image Specifications)

  • Single Binary

    One statically built binary for simplified download and install with no additional dependencies or services.

  • Unprivileged

    Doesn't require elevated privileges on host.

  • Features vs Security

    Separate Full (all features included) or Minimal (stripped for security) builds.

  • Support For Multiple Platforms

    Linux, MacOS, Intel, Arm, Raspberry PI, Cloud, Bare-metal ...

  • Batteries Included

    All features such as security scanning, authentication, authorization, garbage collection, deduplication and so on, included in the same binary.

  • Open Source

    Released as an open source project under Apache2 License.

  • Sponsors

  • Adopters

\ No newline at end of file diff --git a/v2.0.1/install-guides/install-guide-k8s/index.html b/v2.0.1/install-guides/install-guide-k8s/index.html index e6b26da..6fa35f3 100644 --- a/v2.0.1/install-guides/install-guide-k8s/index.html +++ b/v2.0.1/install-guides/install-guide-k8s/index.html @@ -41,7 +41,7 @@ service: type: NodePort port: 5000 -

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.0.1

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

service.port

Port number for calling the service

Customizing the Helm chart using 'set'

To override the default values in the chart, you can pass your custom values by adding the --set flag in the helm install command.

For example, if your servers use an ARM processor instead of Intel, you must change the image.repository name from zot-linux-amd64 to zot-linux-arm64:

--set image.repository=ghcr.io/project-zot/zot-linux-arm64

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

Customizing the Helm chart using a file

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
+

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.0.1

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

service.port

Port number for calling the service

strategy.type

Kubernetes deployment strategy type. [More Info](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy)

Customizing the Helm chart using 'set'

To override the default values in the chart, you can pass your custom values by adding the --set flag in the helm install command.

For example, if your servers use an ARM processor instead of Intel, you must change the image.repository name from zot-linux-amd64 to zot-linux-arm64:

--set image.repository=ghcr.io/project-zot/zot-linux-arm64

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

Customizing the Helm chart using a file

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
 service:
   port: 5050
 

and the following flag would be added to the helm install command:

-f myfile.yaml

Additional information

See the Helm documentation for further information about modifying the Helm chart.

Step 3: Install zot

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
@@ -76,4 +76,4 @@
         "level": "debug"
     }
 }
-

The zot configuration file is located at /etc/zot/config.json.

Refer to Configuring zot for complete information on configuring the zot server with the zot configuration file.

Uninstalling zot

Should you need to uninstall zot, use the helm uninstall command, as in this example:

helm uninstall zot


Last update: January 16, 2024
\ No newline at end of file +

The zot configuration file is located at /etc/zot/config.json.

Refer to Configuring zot for complete information on configuring the zot server with the zot configuration file.

Uninstalling zot

Should you need to uninstall zot, use the helm uninstall command, as in this example:

helm uninstall zot


Last update: February 22, 2024
\ No newline at end of file diff --git a/v2.0.1/install-guides/install-guide-linux/index.html b/v2.0.1/install-guides/install-guide-linux/index.html index 24c5e8d..fa2a251 100644 --- a/v2.0.1/install-guides/install-guide-linux/index.html +++ b/v2.0.1/install-guides/install-guide-linux/index.html @@ -1,4 +1,6 @@ - Installing zot on Bare Metal Linux - zotregistry.dev
Skip to content

Installing zot on Bare Metal Linux

👉 Using an available executable zot image, you can easily deploy zot on a Linux server.

Before you begin

About binary images

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.

Installation

Step 1: Get zot

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:

wget -O /usr/bin/zot  https://github.com/project-zot/zot/releases/download/v2.0.1/zot-linux-amd64
+ Installing zot on Bare Metal Linux - zotregistry.dev      

Installing zot on Bare Metal Linux

👉 Using an available executable zot image, you can easily deploy zot on a Linux server.

Before you begin

About binary images

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.

Installation

Step 1: Get zot

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:

sudo wget -O /usr/bin/zot https://github.com/project-zot/zot/releases/download/v2.0.1/zot-linux-amd64
+

Then fix permissions to it:

sudo chmod +x /usr/bin/zot
+sudo chown root:root /usr/bin/zot
 

Step 2: Create a zot configuration file

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.

Step 3: Configure a local authentication account

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:

htpasswd -bnB myUserName myPassword > /etc/zot/htpasswd
 

To add additional local users, use the >> redirect as in this example:

htpasswd -bnB myUserName2 myPassword2 >> /etc/zot/htpasswd
 

Step 4: Define the zot service

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]
@@ -26,10 +28,11 @@
 sudo mkdir -p /var/log/zot
 sudo chown -R zot:zot /var/log/zot
 
-sudo chown root:root /usr/bin/zot
-sudo chown root:root config.json
-

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.

Step 6: Start zot

Enable and start the zot service with these commands:

sudo systemctl enable zot
+sudo chown -R root:root /etc/zot/
+

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.

Step 6: Start zot

Reload systemd config:

sudo systemctl daemon-reload
+

Enable and start the zot service with these commands:

sudo systemctl enable zot
 sudo systemctl start zot
+

Check if zot config is valid:

sudo -u zot zot verify /etc/zot/config.json
 

When the zot service has started, you can check its status with this command:

sudo systemctl status zot
 

After the installation

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.

Configuration file options and recommendations

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.

Click here to view the sample configuration file.
{
   "distSpecVersion":"1.0.1",
@@ -109,4 +112,4 @@
     }
   ]
 }
-

Last update: January 16, 2024
\ No newline at end of file +

Last update: February 22, 2024
\ No newline at end of file diff --git a/v2.0.1/pdf/document.pdf b/v2.0.1/pdf/document.pdf index 938ca9d8b9bccdf4f2b7d534dde18e6c00eab283..ba1e4eddff4bef27411e744cb5b3e22cf58bd5dd 100644 GIT binary patch delta 604104 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⋙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