For the complete documentation index, see llms.txt. This page is also available as Markdown.

Deployment best practices

Recommendations for deploying CARTO Self-Hosted

Overview

Follow these best practices to ensure a smooth and reliable CARTO Self-Hosted deployment.

Infrastructure

The recommendations in this section apply primarily to Kubernetes (Helm or Kots) deployments. For Single VM (embedded cluster) deployments, namespace and node pool management are handled automatically. We recommend focusing on choosing the right VM size, hardening the OS, and locking down firewall rules for ports 443 and 8800.

Use a dedicated Kubernetes namespace: We recommend deploying CARTO in its own namespace (e.g., carto or carto-prod). This isolates CARTO workloads from other applications, simplifies access control, and makes it easier to apply NetworkPolicies.

kubectl create namespace carto

Separate dev and prod environments: Never share a cluster or VM between development and production CARTO deployments. Use separate environments with separate licenses. See Instances, Licenses & Organizations.

Database

Use a managed PostgreSQL service: We recommend using a cloud-managed PostgreSQL service (Cloud SQL, RDS, Azure Database for PostgreSQL) for production. Enable:

  • Automated daily backups with at least 7-day retention

  • High availability / Multi-AZ failover

  • Automated storage scaling

Set connection limits appropriately: Configure max_connections on PostgreSQL to be at least 100, plus additional headroom for admin connections. CARTO's connection pool should be sized below this limit.

Use a dedicated database user: Create a dedicated PostgreSQL user for CARTO with only the permissions it needs (CREATE, CONNECT, schema ownership). Do not use the postgres superuser.

Networking

Use a dedicated domain: Assign a dedicated subdomain to CARTO (e.g., carto.yourcompany.com). This must match your CARTO license domain and cannot be a subdirectory path.

Terminate TLS at the ingress: Use TLS offloading at your load balancer or ingress controller. Automate certificate renewal using cert-manager + Let's Encrypt or your cloud provider's certificate management service.

Keep the cluster private: Deploy your Kubernetes cluster in a private VPC. Expose only the ingress controller to the internet. Nodes, database, and Valkey should have no public endpoints.

Use your cloud provider's native ingress controller (Kubernetes only): Prefer the cloud-native ingress controller (GKE Ingress, AWS ALB Controller, Azure AGIC) for better integration with cloud load balancing, certificate management, and observability. The Single VM embedded cluster uses its own built-in load balancer, so no external ingress controller is needed.

Cloud-specific recommendations

Google Cloud Platform

  • Use GKE Standard for reduced operational overhead

  • Enable Workload Identity so CARTO pods authenticate to GCS and other GCP services without long-lived service account keys. See Use Workload Identity in GCP

  • Deploy the PostgreSQL database on Cloud SQL with a Private IP — no public endpoint

Amazon Web Services

  • Use EKS with Managed Node Groups to reduce node lifecycle management overhead

  • Enable EKS Pod Identity so CARTO pods authenticate to S3 without long-lived access keys. See Use EKS Pod Identity in AWS

  • Deploy PostgreSQL on Amazon RDS for PostgreSQL with Multi-AZ enabled

  • Use a VPC with private subnets and a NAT gateway for outbound traffic

  • Use AWS Certificate Manager (ACM) with an ALB for free, auto-renewing TLS certificates

Microsoft Azure

  • Use AKS with a system-managed identity to avoid managing service principal credentials

  • Deploy PostgreSQL on Azure Database for PostgreSQL – Flexible Server (Single Server is deprecated)

  • Use Azure Private Link to connect to the database and storage from within your VNet without traversing the internet

  • Use Azure Application Gateway with Azure Key Vault certificates for TLS management

Last updated

Was this helpful?