> For the complete documentation index, see [llms.txt](https://docs.carto.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.carto.com/carto-self-hosted/quickstarts/quickstart-kubernetes-helm.md).

# Advanced Orchestrated container deployment

<img src="/files/8gcUtLEi7XgPb1vQuIPr" alt="Advanced Orchestrated container deployment" width="52">

{% hint style="info" %}
**Estimated time:** \~45–60 minutes
{% endhint %}

This quickstart walks you through the minimum steps to deploy CARTO Self-Hosted on a Kubernetes cluster using Helm. It uses default values wherever possible to reduce time-to-deployment.

For a full production-ready installation with all configuration options, see the [Advanced Orchestrated container deployment guide](/carto-self-hosted/deployment/kubernetes-helm.md).

{% hint style="warning" %}
Quickstarts are not suitable for production. For a production-grade installation with full configuration options, use the [Deployment Guides](/carto-self-hosted/deployment.md).
{% endhint %}

## Before you begin

Complete every item below before starting. Each prerequisite has a dedicated setup guide. Do not skip them.

* [ ] **License & customer package** (`carto-values.yaml` + `carto-secrets.yaml`) received from CARTO Support → [License / Customer Package](/carto-self-hosted/planning/prerequisites/license.md)
* [ ] **Kubernetes cluster** meets the hardware requirements for Advanced Orchestrated deployments → [Hardware & Software Requirements](/carto-self-hosted/planning/prerequisites/hardware-requirements.md)
* [ ] **Metadata database** (PostgreSQL 14+) provisioned and accessible from the cluster → [Metadata Database prerequisites](/carto-self-hosted/planning/prerequisites/metadata-database.md)
* [ ] **Object storage buckets** created, CORS configured, and IAM permissions set → [Object Storage prerequisites](/carto-self-hosted/planning/prerequisites/object-storage.md)
* [ ] **Network egress** open for all required CARTO services → [Network egress requirements](/carto-self-hosted/planning/prerequisites/network/egress.md)
* [ ] `kubectl` and `helm` v3.6+ installed and connected to your cluster
* [ ] A domain name and TLS certificate ready

## Steps

### 1. Create the CARTO namespace

```bash
kubectl create namespace carto
```

### 2. Create your customizations.yaml

Create a new file called `customizations.yaml` in the same directory as your customer package files.

#### 2.1 Domain and database

```yaml
# customizations.yaml

appConfigValues:
  selfHostedDomain: "carto.yourcompany.com"  # Replace with your domain

# External PostgreSQL connection
internalPostgresql:
  enabled: false
externalPostgresql:
  host: "your-postgres-host"
  port: "5432"
  database: "carto_workspace"
  user: "carto_workspace_admin"
  existingSecret: "carto-postgresql"
  existingSecretPasswordKey: "user-password"
```

{% hint style="warning" %}
Supply the database password via a Kubernetes secret, not as plaintext. Create the secret before installing:

```bash
kubectl create secret generic carto-postgresql \
  --namespace carto \
  --from-literal=user-password="<your-db-password>"
```

{% endhint %}

#### 2.2 Object storage

Make sure your buckets are already created and CORS is configured (see [Object Storage prerequisites](/carto-self-hosted/planning/prerequisites/object-storage.md)). Then add the storage configuration to your `customizations.yaml` for your cloud provider:

{% tabs %}
{% tab title="Google Cloud Storage" %}

```yaml
appConfigValues:
  storageProvider: "gcp"
  workspaceImportsBucket: <import_bucket_name>
  workspaceImportsPublic: "false"
  workspaceThumbnailsBucket: <thumbnails_bucket_name>
  workspaceThumbnailsPublic: "true"
  thumbnailsBucketExternalURL: https://storage.googleapis.com/<thumbnails_bucket_name>/
  googleCloudStorageProjectId: <gcp_project_id>
appSecrets:
  googleCloudStorageServiceAccountKey:
    value: |
      <paste your service account JSON key>
```

{% endtab %}

{% tab title="AWS S3" %}

```yaml
appConfigValues:
  storageProvider: "s3"
  workspaceImportsBucket: <import_bucket_name>
  workspaceImportsPublic: "false"
  workspaceThumbnailsBucket: <thumbnails_bucket_name>
  workspaceThumbnailsPublic: "true"
  thumbnailsBucketExternalURL: https://<thumbnails_bucket_name>.s3.amazonaws.com/
  awsS3Region: <region>
appSecrets:
  awsAccessKeyId:
    value: "<your-access-key-id>"
  awsAccessKeySecret:
    value: "<your-secret-access-key>"
```

{% endtab %}

{% tab title="Azure Blob Storage" %}

```yaml
appConfigValues:
  storageProvider: "azure-blob"
  azureStorageAccount: <storage_account_name>
  workspaceImportsBucket: <import_container_name>
  workspaceImportsPublic: "false"
  workspaceThumbnailsBucket: <thumbnails_container_name>
  workspaceThumbnailsPublic: "true"
  thumbnailsBucketExternalURL: https://<storage_account>.blob.core.windows.net/<thumbnails_container>/
appSecrets:
  azureStorageAccessKey:
    value: "<your-access-key>"
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
For full bucket configuration options including keyless auth (Workload Identity, EKS Pod Identity) and export bucket setup, see [Configure your own buckets](/carto-self-hosted/configuration/data-and-storage/configure-your-own-buckets.md).
{% endhint %}

### 3. Add the CARTO Helm repository

```bash
helm repo add carto https://helm.carto.com
helm repo update carto
```

### 4. Install CARTO with Helm

```bash
helm install carto carto/carto \
  --namespace carto \
  -f carto-values.yaml \
  -f carto-secrets.yaml \
  -f customizations.yaml
```

### 5. Watch the rollout

```bash
kubectl rollout status deployment -n carto
kubectl get pods -n carto
```

All pods should reach `Running` status. This may take 3–5 minutes on first install.

### 6. Set up domain access

Once the deployment is running, get your cluster's load balancer IP or hostname:

```bash
kubectl get svc carto-router -n carto
```

**Option A — Cloud cluster with a LoadBalancer IP/hostname:**

Map the domain to the external IP in `/etc/hosts` for a quick local test:

```bash
echo '34.x.x.x carto.yourcompany.com' >> /etc/hosts
```

**Option B — Local cluster or no LoadBalancer (kind, minikube, etc.):**

Use `kubectl port-forward` to access CARTO directly on localhost:

```bash
kubectl port-forward -n carto svc/carto-router 8080:80
```

Then open `http://localhost:8080` in your browser (no TLS in this mode).

For production DNS setup, see [Load Balancing best practices](/carto-self-hosted/best-practices/deployment/load-balancing-best-practices.md).

## Verify first success

Once deployment completes, confirm the following:

* [ ] All pods are running: `kubectl get pods -n <namespace>`
* [ ] The CARTO application loads at your configured domain over HTTPS
* [ ] You can log in with your admin credentials
* [ ] A basic map renders successfully

If any check fails, see [Troubleshooting](/carto-self-hosted/operations/troubleshooting.md) and [Debug mode and logs](/carto-self-hosted/operations/troubleshooting/debug-mode-and-logs.md).

## Next steps

For a production-ready installation with full configuration options, use the [Advanced Orchestrated container deployment guide](/carto-self-hosted/deployment/kubernetes-helm.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.carto.com/carto-self-hosted/quickstarts/quickstart-kubernetes-helm.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
