Skip to content

How the Cohesity App Marketplace Works

This page walks through the complete lifecycle of a Cohesity Marketplace application — from writing the AppSpec through deployment and updates.


The App Bundle

Every Marketplace app consists of three parts:

File Purpose
appspec.yaml Kubernetes-like manifest declaring Services, ReplicaSets/StatefulSets, and Jobs
app.json App metadata — display name, description, version, permissions
Docker image(s) One or more container images referenced by the AppSpec

These are packaged together and uploaded to the Cohesity DevPortal.


AppSpec Kinds

The Marketplace supports a restricted subset of Kubernetes resource kinds:

Kind When to use
Service Expose container ports (NodePort or ClusterIP)
ReplicaSet Long-running stateless applications (web servers, API proxies)
StatefulSet Long-running applications that need persistent storage
Job One-off or cleanup tasks (database migrations, one-time setup)

All other Kubernetes kinds are unsupported and will fail validation.


App Lifecycle

1. Development & Build

You write your application code, create an appspec.yaml and app.json, and build a Docker image. The image can be built with a standard Dockerfile — no Cohesity-specific base image is needed.

2. Validation

Before uploading, validate your AppSpec:

Bash
./appspecvalidator_exec appspec.yaml

The validator checks for unsupported kinds, missing required fields, and common configuration errors.

3. Packaging & Upload

Package the app bundle and upload it to the DevPortal (Cohesity cluster UI → Apps → Upload):

Bash
docker save my-app:latest -o my-app.tar
tar -czf my-app-bundle.tar.gz appspec.yaml app.json my-app.tar

4. Platform-Side Installation

After upload, the Marketplace:

  1. Loads and validates app.json and appspec.yaml.
  2. Loads the Docker images into the cluster's internal registry.
  3. Creates Kubernetes resources from the AppSpec.
  4. Assigns NodePorts for any Service with cohesityTag: ui.
  5. Injects environment variables declared with cohesityEnv into all pods.

5. Runtime

Once running, the Marketplace manages pod health. If a pod crashes, Kubernetes restarts it. Your wrapper.sh script provides an additional application-level restart loop.

6. Updates

To update an app, bump the version in app.json, rebuild the Docker image, and re-upload the bundle. The Marketplace performs a rolling update.


Cohesity AppSpec Extensions

The Marketplace extends Kubernetes YAML with several custom annotations and fields:

cohesityTag — Port Classification

YAML
ports:
  - port: 8080
    cohesityTag: ui       # Marks this port as the UI port

The ui tag does two things: 1. Makes the port accessible from the Marketplace app launcher. 2. Places the Cohesity token gate in front of the port (enforcing user auth).

cohesityEnv — Injected Environment Variables

YAML
ports:
  - port: 8002
    cohesityEnv: MCP_NODE_PORT   # Injects the actual assigned NodePort value

The platform reads the dynamically assigned NodePort and injects it into every pod as the named environment variable.

replicas.fixed and replicas.share

YAML
spec:
  replicas:
    fixed: 1        # Always exactly 1 replica
YAML
spec:
  replicas:
    share: 0.1      # Scale proportionally — 0.1 replicas per cluster node

cohesityTag: cleanup on Jobs

YAML
kind: Job
metadata:
  labels:
    cohesityTag: cleanup   # Runs this Job when the app is uninstalled

Auto-Injected Environment Variables

The Marketplace automatically injects these variables into every pod:

Variable Description
HOST_IP The IP address of the host node
APPS_API_ENDPOINT_IP IP of the Cohesity Apps API endpoint
APPS_API_ENDPOINT_PORT Port of the Cohesity Apps API endpoint
APP_AUTHENTICATION_TOKEN Short-lived token confirming Marketplace runtime
POD_UID Unique identifier for this pod instance

Your application can check for APP_AUTHENTICATION_TOKEN to detect whether it's running in the Marketplace or in a local development environment.


Network Topology

Text Only
External MCP Client / Browser
        │ TCP  (assigned NodePort)
Cohesity Node (HOST_IP)
        │ NodePort → Service → Pod
        ┌──────────────────────┐
        │  cohesityTag: ui     │
        │  Token Gate          │  ← Validates Cohesity session token
        │  (if ui tag present) │    (skipped if unrestricted_app_ui_access)
        └──────────┬───────────┘
        ┌──────────────────────┐
        │  Your Container      │
        └──────────────────────┘
        Gaia API (cluster-internal or Helios)

Example: Minimal AppSpec

YAML
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
  labels:
    app: my-app
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
    - port: 8080
      protocol: TCP
      name: http
      cohesityTag: ui

---

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas:
    fixed: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: my-app:latest
          resources:
            requests:
              cpu: 250m
              memory: 128Mi
          env:
            - name: GAIA_API_KEY
              value: "your-api-key"

Next Steps