# OCI CLI Usage

This page describes the common commands for OCI images and artifacts after you create and configure an OCI repository in Nexus.

## Pull and Push Container Images with Docker and Podman

Docker and Podman are container tools that can pull, tag, and push container images to OCI-compatible registries. Docker and Podman use the same image reference format for these commands.

- **Docker pull through a proxy repository (from upstream registry)**

```
  docker pull <NexusURL>/<repo>/<image>:<tag>
  ```
  
  For multi architectural images, a docker pull of a multi-architecture tag automatically selects the platform matching the client.

- **Podman pull through a proxy repository (from upstream registry):**

```
  podman pull <NexusURL>/<repo>/<image>:<tag>
  ```

- **Docker tag and push to a hosted repository:**

```
  docker tag <image>:<tag> <NexusURL>/<repo>/<image>:<tag>
  docker push <NexusURL>/<repo>/<image>:<tag>
  ```
  
  For multi architectural images:

```
  docker buildx build --platform linux/amd64,linux/arm64 -t
  [NexusURL]/<REPO_NAME>/<image>:<tag> --push .
  ```

- **Podman tag and push to a hosted repository:**

```
  podman tag <image>:<tag> <NexusURL>/<repo>/<image>:<tag>
  podman push <NexusURL>/<repo>/<image>:<tag>
  ```

Where,

- `<NexusURL>` \- Your Nexus repository URL, for example `example.nexus.com`  
- `<image>` \- Image name  
- `<tag>` \- Image tag, such as `1.0`

**Examples:**

```
  #docker pull
  docker pull example.nexus.com/oci-proxy/nginx:1.27

#docker tag
  docker tag nginx:1.27 example.nexus.com/oci-hosted/nginx:1.27

#docker push
  docker push example.nexus.com/oci-hosted/nginx:1.27

#podman pull
  podman pull example.nexus.com/oci-proxy/nginx:1.27

#podman push
  podman push example.nexus.com/oci-hosted/nginx:1.27

#multi architecture images
  docker buildx build \  --platform linux/amd64,linux/arm64 \  -t
  repo.example.com/oci-hosted/sample-app:1.0.0 \  --push .
  ```

## Pull and Push Helm Charts

Helm charts are stored and served as OCI artifacts. OCI support is generally available from Helm 3.8.0 and later.

- **Pull a Helm chart:**

```
  helm pull oci://<NexusURL>/<REPO_NAME>/mychart --version 0.1.0
  ```

- **Package and publish a chart to a hosted repository:**

```
  helm package mychart/                         # produces mychart-0.1.0.tgz
  helm push mychart-0.1.0.tgz oci://<NexusURL>/<REPO_NAME>
  ```

Where,

- `<NexusURL>` \- Your Nexus repository URL, for example `example.nexus.com`  
- `<REPO_NAME>` \- Your Nexus Repository name.

**Examples:**

```
  # Package a chart
  helm package nginx-chart/

# Push the packaged chart
  helm push nginx-chart-1.0.0.tgz oci://example.nexus.com/oci-hosted

# Pull a specific chart version
  helm pull oci://example.nexus.com/oci-hosted/nginx-chart --version 1.0.0
  ```

## Pull, Push and Attach OCI Artifacts (ORAS)

OCI Registry As Storage (ORAS) works with arbitrary OCI artifacts and the OCI 1.1 Referrers API. Use a recent ORAS 1.x release for finalized OCI 1.1 behaviour. The following are few commands that can be used along with Nexus Repository:

- **Pull a generic artifact:**

```
  oras pull [NexusURL]/<REPO_NAME>/<artifact>:v1
  ```

- **Push a generic artifact:**

```
  oras push [NexusURL]/<REPO_NAME>/<artifact>:v1 file.txt:text/plain
  ```

- **Attach an artifact to an image as a referrer:**

```
  oras attach --artifact-type application/spdx+json [NexusURL]/<REPO_NAME>/<image>:<tag>
sbom.spdx.json
  ```

- **Discover the referrers attached to an image (optionally filter by type):**

```
  oras discover [NexusURL]/<REPO_NAME>/<image>:<tag>
  oras discover [NexusURL]/<REPO_NAME>/<image>:<tag> --artifact-type application/spdx+json
  ```

- **Copy an image (preserves a multi-architecture index) and list tags:**

```
  oras cp [NexusURL]/<REPO_NAME>/<image>:<tag> [NexusURL]/<REPO_NAME>/<image>:copy
  oras repo tags [NexusURL]/<REPO_NAME>/<image>
  ```

Where,

- `[NexusURL]` \- Your Nexus repository URL, for example `example.nexus.com`  
- `<REPO_NAME>` \- Your Nexus Repository name  
- `<image>` \- Image name  
- `<tag>` \- Image tag, such as `1.0`

**Examples:**

```
  # Push a generic artifact
  oras push example.nexus.com/oci-hosted/sample-artifact:v1 \
    readme.txt:text/plain

# Pull the artifact
  oras pull example.nexus.com/oci-hosted/sample-artifact:v1

# Attach an SBOM to an image
  oras attach \
    --artifact-type application/spdx+json \
    example.nexus.com/oci-hosted/nginx:1.27 \
    sbom.spdx.json

# Discover attached referrers
  oras discover example.nexus.com/oci-hosted/nginx:1.27

# Discover only SPDX SBOM referrers
  oras discover \
    example.nexus.com/oci-hosted/nginx:1.27 \
    --artifact-type application/spdx+json

# Copy an image
  oras cp \
    example.nexus.com/oci-hosted/nginx:1.27 \
    example.nexus.com/oci-hosted/nginx:copy

# List available tags
  oras repo tags example.nexus.com/oci-hosted/nginx
  ```

## Sign and Verify Images (Cosign)

Cosign is an open-source command-line Sigstore client used to digitally sign, verify, and store signatures for container images and other OCI artifacts. Cosign 3.x stores signatures as OCI 1.1 referrers and attaches them to the image. They are discoverable with `oras discover`.

Internal Nexus registry signs with a local key pair rather than the public Sigstore infrastructure. Use the following flags to disable the Sigstore's public transparency log and keyless signing-config lookups:

- `--tlog-upload=false`
- `--use-signing-config=false`
- `--insecure-ignore-tlog=true`

Omit the flags only if you intend to use public Sigstore or Rekor.

```
  cosign generate-key-pair

# Sign with a local key
  cosign sign --key cosign.key [NexusURL]/<REPO_NAME>/<image>:<tag> \
    --tlog-upload=false --use-signing-config=false --yes

# Verify against the public key
  cosign verify --key cosign.pub [NexusURL]/<REPO_NAME>/<image>:<tag> --insecure-ignore-tlog=true
  ```

Where,

- `[NexusURL]` \- Your Nexus repository URL, for example `example.nexus.com`  
- `<REPO_NAME>` \- Your Nexus Repository name

**Example:**

```
  # Generate a key pair
  cosign generate-key-pair

# Sign an image
  cosign sign \
    --key cosign.key \
    example.nexus.com/oci-hosted/nginx:1.27 \
    --tlog-upload=false \
    --use-signing-config=false \
    --yes

# Verify the signature
  cosign verify \
    --key cosign.pub \
    example.nexus.com/oci-hosted/nginx:1.27 \
    --insecure-ignore-tlog=true
  ```

**Note**

Nexus Repository stores and serves the signatures from the Cosign client as referrers. Server-side enforcement, such as rejecting pulls of unsigned images, is not available.

## Use Crane and Skopeo with Nexus Repository

Crane and Skopeo are command-line tools for working with remote container images and registries. Use these tools to copy images, inspect manifests, view digests, and list tags. The following commands can be used with Nexus Repository:

- **To pull an image using Crane:**

```
  crane pull <NexusURL>/<REPO_NAME>/<image>:<tag> <image>.tar
  ```

- **To push an image using Crane:**

```
  crane push <image>.tar <NexusURL>/<REPO_NAME>/<image>:<tag>
  ```

- **To inspect an image using skopeo:**

```
  skopeo inspect docker://[NexusURL]/<REPO_NAME>/<image>:<tag>
  ```

- **To copy all image variants using skopeo:**

```
  skopeo copy --all docker://[NexusURL]/<REPO_NAME>/<image>:<tag>
docker://[NexusURL]/<REPO_NAME>/<image>:copy
  ```

Where,

**Examples:**

```
  # Pull an image to a local tarball
  crane pull example.nexus.com/oci-hosted/nginx:1.27 nginx.tar

# Push a local tarball to the repository
  crane push nginx.tar example.nexus.com/oci-hosted/nginx:1.27

# Inspect an image
  skopeo inspect \
    docker://example.nexus.com/oci-hosted/nginx:1.27

# Copy all image variants
  skopeo copy --all \
    docker://example.nexus.com/oci-hosted/nginx:1.27 \
    docker://example.nexus.com/oci-hosted/nginx:copy
  ```
