Skip to main content

Certification track: Associate Cloud Engineer (ACE)

Umami GKE Module — Configuration Guide

Umami GKE Module — Configuration Guide

This guide describes every configuration variable available in the Umami_GKE module. Umami_GKE is a wrapper module that combines the generic App_GKE infrastructure module with the Umami_Common shared application configuration to deploy the Umami privacy-focused web analytics platform on Google Kubernetes Engine (GKE) Autopilot.

Most configuration options in Umami GKE map directly to the same options in App GKE. Where a variable is identical in behaviour, this guide references the App GKE guide rather than repeating the same documentation. Only the variables and defaults that are specific to Umami are described in full here.

Note: Variables marked as platform-managed are set and maintained by the platform. You do not normally need to change them.


Standard Configuration Reference

The following configuration areas are provided by the underlying App_GKE module. Consult the linked sections of the App_GKE Configuration Guide for full documentation.

Configuration AreaApp GKE.md SectionUmami-Specific Notes
Project & Identity§2 IAM & Access ControlIdentical.
Application Identity§3.A Compute (GKE Autopilot)Umami-specific defaults; see Group 2: Application Identity.
Runtime & Scaling§3.A Compute (GKE Autopilot)Umami-specific defaults for container_port, cpu_limit, memory_limit; see Group 3: Runtime & Scaling.
Environment Variables & Secrets§3 Core Service ConfigurationAPP_SECRET auto-generated; DATABASE_URL assembled at runtime; see Group 5: Environment Variables & Secrets.
Networking & Network Policies§3.D Networking & Network PoliciesIdentical.
Initialization Jobs & CronJobs§3.E Initialization Jobs & CronJobsdb-init job supplied automatically by Umami Common; see Group 8: Jobs & Scheduled Tasks.
Additional Services§3.F Additional ServicesIdentical.
Storage — NFS§3.C Storage (NFS / GCS / GCS Fuse)enable_nfs defaults to false — Umami is stateless and needs no shared filesystem.
Storage — GCS§3.C Storage (NFS / GCS / GCS Fuse)No storage buckets provisioned by default; see Group 14: Cloud Storage.
Database Configuration§3.B Database (Cloud SQL)PostgreSQL required; see Group 16: Database Configuration.
Backup Schedule & Retention§3.B Database (Cloud SQL)Identical.
Custom SQL Scripts§3.E Initialization Jobs & CronJobsIdentical.
Observability & Health Checks§3.A Compute (GKE Autopilot)Health endpoint /api/heartbeat; see Group 10: Observability & Health.
Cloud Armor WAF§4.A Cloud Armor WAFIdentical.
Identity-Aware Proxy§4.B Identity-Aware Proxy (IAP)Identical.
Binary Authorization§4.C Binary AuthorizationIdentical.
VPC Service Controls§4.D VPC Service ControlsIdentical.
Secrets Store CSI Driver§4.E Secrets Store CSI DriverAlways enabled — no configuration required.
Traffic & Ingress§5 Traffic & IngressIdentical.
CDN§5.B CDNIdentical.
Custom Domain & Static IP§5.C Static IP ReservationSee Group 19: Custom Domain & Static IP.
Cloud Build Triggers§6.A Cloud Build TriggersIdentical.
Cloud Deploy Pipeline§6.B Cloud Deploy PipelineIdentical.
Image Mirroring§6.C Image MirroringEnabled by default to avoid GitHub Container Registry rate limits.
Pod Disruption Budgets§7.A Pod Disruption BudgetsIdentical.
Topology Spread Constraints§7.B Topology Spread ConstraintsIdentical.
Resource Quotas§7.C Resource QuotasIdentical.
Auto Password Rotation§7.D Auto Password RotationSee Group 16: Database Configuration.
Redis Cache§8.A Redis / MemorystoreRedis not wired — Umami does not require it; see Group: Redis Cache.
Backup Import§8.B Backup ImportSee Group 21: Backup Import.
Service Mesh (ASM)§8.C Service Mesh (ASM via Fleet)Identical.
Multi-Cluster Services§8.D Multi-Cluster Services (MCS)Identical.

How Umami GKE Relates to App GKE

Umami GKE passes all variables through to App GKE and adds a Umami Common sub-module that supplies Umami-specific defaults and application configuration. The main effects are:

  1. PostgreSQL is required. Umami requires PostgreSQL for all data storage. The database_type default is "POSTGRES" (the generic PostgreSQL option).
  2. DATABASE_URL is assembled at runtime. The custom Umami entrypoint constructs DATABASE_URL from platform-injected DB_* variables. This avoids storing a plaintext connection string in environment variables or Terraform state.
  3. APP_SECRET is auto-generated. Umami Common generates a 32-character alphanumeric secret and stores it in Secret Manager. It is injected into the pod as APP_SECRET.
  4. No storage buckets are provisioned by default. Umami is a stateless analytics service — all data lives in PostgreSQL. storage_buckets defaults to an empty list.
  5. A db-init job runs on first deployment. Umami Common supplies a default db-init Kubernetes Job that pre-creates the Umami PostgreSQL database and user. Umami then runs its own Prisma migrations on startup.
  6. Resource defaults are sized for Umami. The default cpu_limit (1 vCPU) and memory_limit (512Mi) reflect Umami's lightweight footprint.
  7. Health probes target /api/heartbeat. Umami's dedicated health endpoint, not a generic root path.
  8. Redis is not used. Umami stores everything in PostgreSQL; the module wires no Redis connection (the mirrored enable_redis declaration is not forwarded to the Foundation).
  9. Image mirroring is enabled by default. Umami is distributed via GitHub Container Registry (ghcr.io). The module mirrors the image to Artifact Registry to avoid rate limits in production.

Group 1: Project & Identity

Identical to App_GKE. See App_GKE.

VariableDefaultDescription
project_id(required)GCP project ID. Required.
region"us-central1"GCP region for Cloud SQL, GCS, and other resources.

Group 2: Application Identity

These variables behave identically to App_GKE. See App_GKE for descriptions.

Umami-specific defaults:

VariableUmami GKE DefaultApp GKE DefaultNotes
application_name"umami""gkeapp"Used as the base name for all GCP and Kubernetes resources. Do not change after deployment.
application_display_name"Umami""App GKE Application"Shown in the platform UI and dashboards. Can be changed freely.
application_description"Umami Analytics on GKE Autopilot""App GKE Custom Application…"Descriptive label. Can be changed freely.
application_version"postgresql-latest""1.0.0"The Umami release version to build and deploy. Must use a postgresql- prefixed tag.
deploy_applicationtruetrueSet false to provision supporting infrastructure only without deploying the Umami workload.

Group 3: Runtime & Scaling

Most variables behave identically to App_GKE. See App_GKE Group 3.

Umami-specific defaults and behaviour:

VariableUmami GKE DefaultApp GKE DefaultNotes
container_port30008080Umami's native Next.js port. Do not change unless your custom Dockerfile binds Umami to a different port.
container_resources{ cpu_limit="1000m", memory_limit="512Mi" }{ cpu_limit="1000m", memory_limit="512Mi" }Same defaults — Umami is lightweight. Increase memory_limit to 1Gi for high-traffic analytics dashboards.
min_instance_count1variesGKE default is 1 pod minimum. Set to a higher value for high-availability deployments.
max_instance_count103Umami scales horizontally safely — all state is in PostgreSQL, allowing many concurrent instances.
container_image_source"custom""custom"The custom mode builds a wrapper image that assembles DATABASE_URL from DB_* variables. Set to "prebuilt" only if providing DATABASE_URL manually.
enable_cloudsql_volumetruetrueCloud SQL Auth Proxy sidecar. Required for Umami to connect to Cloud SQL via Unix socket.
workload_type"Deployment""Deployment"Umami is stateless — Deployment is the correct workload type. Do not use StatefulSet unless attaching persistent local storage for a non-standard use case.

enable_vertical_pod_autoscaling: Defaults to false. Enable to allow GKE Autopilot to automatically right-size Umami pods based on observed resource usage. Useful for cost optimisation in production.

The remaining runtime variables (enable_image_mirroring, container_build_config, container_protocol, timeout_seconds, cloudsql_volume_mount_path, service_annotations, service_labels, termination_grace_period_seconds, deployment_timeout) behave as described in App_GKE Group 3.


Group 4: Access & Networking

These variables behave identically to App_GKE. See App_GKE, App_GKE, and App_GKE.

VariableDefaultDescription
enable_iapfalseEnables Identity-Aware Proxy authentication on the load balancer.
iap_authorized_users[]Individual users or service accounts granted IAP access.
iap_authorized_groups[]Google Groups granted IAP access.
iap_oauth_client_id""OAuth client ID for IAP configuration.
iap_oauth_client_secret""OAuth client secret for IAP configuration.
iap_support_email""Support email shown on the Google OAuth consent screen.
enable_cloud_armorfalseAttaches a Cloud Armor security policy to the GKE Ingress backend.
admin_ip_ranges[]Admin CIDR ranges permitted through Cloud Armor.
cloud_armor_policy_name"default-waf-policy"Name of the Cloud Armor security policy to attach.
enable_vpc_scfalseEnables VPC Service Controls perimeter enforcement.
network_name""VPC network name. Leave empty to auto-discover.
network_tags[]Firewall tags applied to GKE cluster nodes.
enable_network_segmentationfalseApplies Kubernetes NetworkPolicy rules to restrict pod-to-pod traffic.

IAP note for Umami: IAP protects the Umami analytics dashboard. If applying IAP, note that the tracking script endpoint (/script.js) and event collection endpoint (/api/send) must remain publicly accessible for tracked websites to report data. Consider routing architecture carefully if restricting access.


Group 5: Environment Variables & Secrets

These variables behave identically to App_GKE. See App_GKE.

Umami-specific behaviour:

Umami Common generates APP_SECRET and injects it as the APP_SECRET environment variable. No SMTP defaults are pre-populated — Umami does not send email natively.

Use environment_variables for Umami configuration options:

environment_variables = {
DISABLE_TELEMETRY = "1" # Disable Umami's anonymous telemetry reporting
TRACKER_SCRIPT_NAME = "analytics.js" # Rename tracking script to avoid ad blockers
ALLOWED_FRAME_URLS = "https://example.com" # Allow Umami to be embedded in iframes
}
VariableDefaultDescription
environment_variables{}Plain-text environment variables injected into the pod at runtime.
secret_environment_variables{}Secret Manager references injected as environment variables.
secret_rotation_period'2592000s'Rotation period for Secret Manager secrets (30 days).
secret_propagation_delay30Seconds to wait after secret creation before proceeding.

Group 6: GKE Cluster

VariableDefaultDescription
gke_cluster_name""Name of the target GKE Autopilot cluster. Leave empty to auto-discover.
namespace_name""Kubernetes namespace. Auto-generated from application_name and tenant_deployment_id when empty.
service_type"LoadBalancer"Kubernetes Service type. "LoadBalancer" (the default) exposes Umami directly on an external IP; use "ClusterIP" for internal-only access behind an Ingress.
session_affinity"None"Session affinity mode. "None" is correct for Umami — all state is in PostgreSQL, so any pod can handle any request.
enable_multi_cluster_servicefalseRegisters the service with GKE Multi Cluster Services.
configure_service_meshfalseInjects Anthos Service Mesh (Istio) sidecar proxies.
termination_grace_period_seconds30Seconds Kubernetes waits for the pod to terminate before force-killing.
deployment_timeout600Maximum seconds to wait for the GKE deployment to reach a healthy state.
gke_cluster_selection_mode"primary"Strategy for choosing the target cluster.

Group 7: Backup & Maintenance

VariableDefaultNotes
backup_schedule"0 2 * * *"Daily at 02:00 UTC. Adjust to your preferred maintenance window.
backup_retention_days77-day retention. Increase for production deployments (30–90 days recommended).

Group 8: Jobs & Scheduled Tasks

These variables behave as described in App_GKE, with one important Umami-specific behaviour.

Umami default db-init job:

When initialization_jobs is left as the default (empty list []), Umami Common automatically supplies a db-init job:

FieldValue
Job namedb-init
ImagePostgreSQL client image
PurposePre-creates the Umami PostgreSQL database and user before Umami runs its own Prisma migrations
Execute on every applytrue
CPU / Memory1000m / 512Mi

Override initialization_jobs with a non-empty list to replace this default with your own jobs. Each custom job must specify at least one of command, args, or script_path.

CronJobs: The cron_jobs and additional_services variables are available and behave identically to App_GKE. Use cron_jobs for tasks such as regular analytics data exports or database maintenance.

Note: The cron_jobs schema in Umami GKE uses Kubernetes CronJob fields — restart_policy, concurrency_policy, failed_jobs_history_limit, successful_jobs_history_limit, starting_deadline_seconds, suspend.


Group 9: Reliability Policies

Identical to App_GKE. See App_GKE.

VariableDefaultNotes
enable_pod_disruption_budgettrueEnabled by default. Prevents all Umami pods from being evicted simultaneously during cluster maintenance.
pdb_min_available"1"At least one Umami pod must remain available during voluntary disruptions.
enable_topology_spreadfalseEnable for high-availability deployments to distribute pods across zones.
topology_spread_strictfalseWhen true, uses DoNotSchedule spread constraint.

Group 10: Observability & Health

These variables behave identically to App_GKE. See App_GKE.

Umami health endpoint: Umami exposes /api/heartbeat as its dedicated health endpoint. This endpoint returns HTTP 200 when Umami is running and connected to PostgreSQL. All probe configuration defaults use this path.

VariableUmami GKE DefaultNotes
startup_probe_config{ enabled=true, path="/api/heartbeat", initial_delay_seconds=30, failure_threshold=30 }High failure_threshold accommodates first-boot Prisma migrations.
health_check_config{ enabled=true, path="/api/heartbeat", initial_delay_seconds=30, failure_threshold=3 }Liveness probe — restarts unhealthy pods.
uptime_check_config{ enabled=false, path="/api/heartbeat" }Cloud Monitoring uptime check. Disabled by default.
alert_policies[]Custom Cloud Monitoring metric alert policies.

Startup probe note: The failure_threshold = 30 with period_seconds = 10 gives Umami up to 5 minutes (plus the 30-second initial delay) to complete startup and run Prisma migrations on a fresh database. On subsequent restarts (migrations already applied), startup is much faster.


Group 11: Workload Automation (Jobs)

VariableDefaultDescription
initialization_jobs[]Kubernetes Jobs to run before the Umami application starts. Leave empty for Umami Common to supply the default db-init job.
cron_jobs[]Recurring Kubernetes CronJob resources.
additional_services[]Sidecar or helper services deployed alongside the main Umami container.

Group 12: CI/CD & GitHub Integration

Identical to App_GKE. See App_GKE.

VariableDefaultDescription
enable_cicd_triggerfalseProvisions a Cloud Build GitHub trigger.
github_repository_url""Full HTTPS URL of the GitHub repository.
github_token""GitHub Personal Access Token. Sensitive.
github_app_installation_id""GitHub App installation ID.
cicd_trigger_config{ branch_pattern = "^main$" }Advanced Cloud Build trigger configuration.
enable_cloud_deployfalseSwitches to a managed Google Cloud Deploy pipeline.
cloud_deploy_stages[dev, staging, prod(approval)]Ordered promotion stages.
enable_binary_authorizationfalseEnforces Binary Authorization policy on the GKE cluster.
binauthz_evaluation_mode"ALWAYS_ALLOW"Binary Authorization enforcement mode. Not referenced.

Group 13: NFS

Umami does not require NFS. enable_nfs defaults to false. All Umami data is stored in PostgreSQL.

VariableDefaultDescription
enable_nfsfalseProvisions a Cloud Filestore (NFS) instance. Not required for Umami.
nfs_mount_path"/mnt/nfs"Container NFS mount path. Only used when enable_nfs = true.
nfs_instance_name""Name of an existing NFS GCE VM. Auto-discovered when empty.
nfs_instance_base_name"app-nfs"Base name for an inline NFS GCE VM.
nfs_volume_name"nfs-data-volume"Kubernetes volume name for the NFS mount.

Group 14: Cloud Storage

Umami does not require GCS buckets. storage_buckets defaults to an empty list.

VariableDefaultDescription
create_cloud_storagetrueControls whether the module provisions GCS buckets defined in storage_buckets.
storage_buckets[]GCS bucket configurations. Empty by default — Umami is stateless.
gcs_volumes[]GCS buckets to mount via GCS Fuse CSI driver.
manage_storage_kms_iamfalseCreates a CMEK KMS keyring for GCS buckets.
enable_artifact_registry_cmekfalseCreates an Artifact Registry KMS key for at-rest image encryption.
max_images_to_retain7Maximum container images to keep in Artifact Registry.
delete_untagged_imagestrueAutomatically deletes untagged images from Artifact Registry.
image_retention_days30Days after which images are eligible for deletion.

Group 16: Database Configuration

These variables behave identically to App_GKE. See App_GKE.

Umami-specific defaults and restrictions:

VariableUmami GKE DefaultApp GKE DefaultNotes
database_type"POSTGRES""POSTGRES"Umami requires PostgreSQL. Do not change to MySQL or NONE.
application_database_name"umami""gkeappdb"Do not change after deployment — changing recreates the database and destroys all analytics data.
application_database_user"umami""gkeappuser"Do not change after deployment.
database_password_length3232Auto-generated password length. Range: 16–64.

Automatic password rotation:

VariableDefaultDescription
enable_auto_password_rotationfalseDeploys an automated database password rotation job.
rotation_propagation_delay_sec90Seconds to wait after rotation before restarting pods.

PostgreSQL extensions:

VariableDefaultDescription
enable_postgres_extensionsfalseEnables installation of PostgreSQL extensions after provisioning.
postgres_extensions[]List of extensions to install (e.g., ['uuid-ossp', 'pg_trgm']).

Group 19: Custom Domain & Static IP

Identical to App_GKE. See App_GKE.

VariableDefaultDescription
enable_custom_domaintrueProvisions a Kubernetes Ingress resource for custom domain routing. Enabled by default.
application_domains[]Custom domain names (e.g., ["analytics.example.com"]).
reserve_static_iptrueReserves a Global Static IP for the load balancer. Recommended for production deployments.
static_ip_name""Name for the reserved IP. Auto-generated if empty.
enable_cdnfalseEnables Cloud CDN on the GKE Ingress backend.
network_tags[]VPC firewall network tags applied to GKE nodes.
network_name""VPC network name. Auto-discovered when empty.

Group 21: Backup Import

VariableDefaultDescription
enable_backup_importfalseTriggers a one-time database import job during deployment.
backup_source"gcs"Source for the backup file: "gcs" or "gdrive".
backup_file"backup.sql"Filename of the backup to import.
backup_format"sql"Backup format: sql, tar, gz, tgz, tar.gz, zip, auto.

Group 8: Resource Quota

Identical to App_GKE. See App_GKE.

VariableDefaultDescription
enable_resource_quotafalseCreates a Kubernetes ResourceQuota in the application namespace.
quota_cpu_requests""Total CPU requests allowed in the namespace.
quota_cpu_limits""Total CPU limits allowed in the namespace.
quota_memory_requests""Total memory requests. Must use binary unit suffixes (e.g., "4Gi", "8192Mi").
quota_memory_limits""Total memory limits. Must use binary unit suffixes.

Warning: quota_memory_requests and quota_memory_limits must use binary suffixes (Gi, Mi) when set. Bare integers (e.g., "4") are treated as bytes by Kubernetes and will block all pod scheduling with a quota-exceeded error.


Redis Cache

Umami does not use Redis — it stores all analytics data directly in PostgreSQL with no caching layer. The enable_redis variable is declared in Umami_GKE only to satisfy Foundation variable mirroring; it is not forwarded to the App_GKE call, so changing it has no effect.

VariableDefaultDescription
enable_redistrueInert declaration (Foundation mirroring only) — not forwarded to App_GKE, so no Redis env vars are injected regardless of value.

If you require Redis for a custom integration or adjacent service, use additional_services to deploy a Redis sidecar, or configure Memorystore independently.


Group 22: VPC Service Controls

VariableDefaultDescription
enable_vpc_scfalseEnforces VPC Service Controls perimeters around GCP APIs.
vpc_cidr_ranges[]VPC subnet CIDR ranges for VPC-SC network access level.
vpc_sc_dry_runtrueLogs violations without blocking.
organization_id""GCP Organization ID for VPC-SC. Auto-discovered when empty.
enable_audit_loggingfalseEnables detailed Cloud Audit Logs.

Exploring with the GCP Console

After a successful deployment, explore the Umami installation in the GCP Console:

GKE workload: Navigate to Kubernetes Engine → Workloads. Find the Deployment named after your application_name and tenant_deployment_id. Click to view:

  • Pod status, restart count, and age.
  • Logs tab — streams container logs from running Umami pods.
  • Details tab — shows the Deployment spec, resource limits, probe configuration, and environment variables (non-sensitive).
  • Revision history — lists previous ReplicaSets.

GKE Services & Ingress: Navigate to Kubernetes Engine → Services & Ingress. Find the Service for your Umami deployment. View:

  • The external IP address (if service_type = "LoadBalancer" or reserve_static_ip = true).
  • Port mappings.
  • Load balancer health check status.

Cloud SQL instance: Navigate to SQL. Find the instance named app-sql-<deployment_id>. Explore:

  • Overview — connection name, PostgreSQL version, storage usage.
  • Databases — the umami database with all analytics tables.
  • Users — the umami application user.
  • Operations — history of maintenance, failovers, and backups.

Secret Manager: Navigate to Security → Secret Manager. Find the secret-<tenant_resource_prefix>-<application_name>-app-secret secret (injected as APP_SECRET) for this deployment. Click to view:

  • Secret versions and creation timestamps.
  • Access log showing when GKE pods read the secret.
  • Rotation configuration.

Artifact Registry: Navigate to Artifact Registry. Find the repository for this deployment. View mirrored Umami images from GitHub Container Registry, their tags, and retention policy.

Cloud Monitoring: If uptime_check_config.enabled = true was set, navigate to Monitoring → Uptime checks to view the /api/heartbeat uptime check results across GCP regions. Navigate to Monitoring → Dashboards to find the auto-provisioned GKE dashboard with CPU, memory, and request metrics.


Exploring with gcloud and kubectl

Use these commands to inspect the Umami GKE deployment. Replace PROJECT_ID, CLUSTER_NAME, REGION, NAMESPACE, and DEPLOYMENT_NAME with your values.

# Get GKE cluster credentials
gcloud container clusters get-credentials CLUSTER_NAME \
--region=REGION \
--project=PROJECT_ID

# List pods in the Umami namespace
kubectl get pods -n NAMESPACE

# Describe the Umami deployment
kubectl describe deployment DEPLOYMENT_NAME -n NAMESPACE

# View Umami pod logs
kubectl logs -n NAMESPACE -l app=DEPLOYMENT_NAME --tail=100

# Follow live logs from all Umami pods
kubectl logs -n NAMESPACE -l app=DEPLOYMENT_NAME -f

# Check resource usage across Umami pods
kubectl top pods -n NAMESPACE

# Check HPA status (horizontal pod autoscaling)
kubectl get hpa -n NAMESPACE

# Describe the Kubernetes Service
kubectl get service -n NAMESPACE
kubectl describe service SERVICE_NAME -n NAMESPACE

# Check pod environment variables (non-sensitive)
kubectl exec -n NAMESPACE POD_NAME -- env | grep -v PASSWORD | grep -v SECRET

# Test health endpoint from inside a pod
kubectl exec -n NAMESPACE POD_NAME -- \
wget -qO- http://localhost:3000/api/heartbeat

# Check Cloud SQL instance
gcloud sql instances describe INSTANCE_NAME \
--project=PROJECT_ID \
--format="table(name,state,databaseVersion,settings.tier)"

# List databases
gcloud sql databases list \
--instance=INSTANCE_NAME \
--project=PROJECT_ID

# Check Secret Manager secrets
gcloud secrets list \
--project=PROJECT_ID \
--filter="name~umami" \
--format="table(name,createTime)"

# List Artifact Registry images
gcloud artifacts docker images list \
REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME \
--project=PROJECT_ID \
--format="table(image,tags,createTime)"

# Check Kubernetes namespace resource quota (if enabled)
kubectl describe resourcequota -n NAMESPACE

# View PodDisruptionBudget
kubectl get pdb -n NAMESPACE

# Check recent Kubernetes events for the namespace
kubectl get events -n NAMESPACE --sort-by='.metadata.creationTimestamp' | tail -20

# Check Cloud Monitoring uptime checks
gcloud monitoring uptime list-configs \
--project=PROJECT_ID \
--format="table(displayName,httpCheck.path,period,timeout)"

Module Outputs

Umami GKE exposes the following Terraform outputs:

OutputDescription
service_nameName of the Kubernetes Service.
service_urlExternal URL of the GKE load balancer.
service_external_ipExternal IP address of the load balancer.
project_idGCP project ID.
deployment_idDeployment ID suffix.
namespaceKubernetes namespace.
database_instance_nameName of the Cloud SQL instance.
database_nameName of the application database.
database_userName of the application database user.
database_password_secretSecret Manager secret name for the database password.
storage_bucketsCreated GCS storage buckets (empty for Umami).
container_imageContainer image used for the deployment.
cicd_enabledWhether the CI/CD pipeline is enabled.
github_repository_urlGitHub repository URL connected for CI/CD.
kubernetes_readytrue when the GKE cluster endpoint is reachable and all Kubernetes workload resources are deployed. false on the first apply of a new inline cluster — re-run apply to complete the deployment.

Configuration Pitfalls & Sensible Defaults

Risk levels: Critical (data loss, full outage, security breach) — High (service unavailable or significant degradation) — Medium (degraded function or increased cost) — Low (minor impact).

VariableSensible DefaultRiskConsequence of Incorrect Value
project_id(required)CriticalNo default — deployment fails immediately.
database_type"POSTGRES"CriticalUmami requires PostgreSQL. Setting to MySQL or NONE causes DATABASE_URL assembly to fail and Umami cannot connect to the database.
application_database_name"umami"CriticalChanging this after initial deployment destroys all collected analytics data. The database is recreated empty while the old data remains orphaned in Cloud SQL.
application_database_user"umami"CriticalChanging this after initial deployment recreates the Cloud SQL user, invalidating credentials and breaking all database connectivity.
container_port3000CriticalUmami listens on 3000. Mismatching this causes all health probes to fail and Kubernetes to continuously restart the pod.
container_image_source"custom"HighThe official Umami image does not accept individual DB_* variables — it requires a fully-formed DATABASE_URL. Using "prebuilt" without manually setting DATABASE_URL in environment_variables will cause Umami to fail at startup with a missing database connection error.
application_version"postgresql-latest"HighMust use a postgresql- prefixed tag. Plain tags (e.g., latest) do not exist for the PostgreSQL variant of Umami. An invalid tag causes the container pull to fail.
admin_password(change on first login)CriticalDefault credentials (admin / umami) are publicly known. Leaving them unchanged exposes the analytics dashboard and all tracked data to anyone who knows the service URL.
container_resources.memory_limit"512Mi"Medium512Mi is sufficient for light to moderate traffic. Under heavy concurrent dashboard use or complex analytics queries, Umami may OOM. Increase to 1Gi if memory pressure is observed.
enable_cloudsql_volumetrueCriticalUmami connects to Cloud SQL via the Auth Proxy Unix socket. Disabling this removes the socket, causing all database connections to fail.
startup_probe_config.failure_threshold30HighWith period_seconds = 10, a failure_threshold of 30 gives Umami up to 5 minutes to start and run Prisma migrations. Reducing this below 10 may cause Kubernetes to restart the pod before migrations complete, creating a restart loop on fresh deployments.
session_affinity"None"LowUmami is fully stateless — no session affinity is required. All requests can be handled by any pod without consistency issues.
min_instance_count1MediumAt least one Umami pod must always be running for analytics data to be collected. Scale-to-zero would cause data gaps during periods of no dashboard traffic.
quota_memory_requests / quota_memory_limits""Critical (GKE-specific)Must use binary suffixes (Gi, Mi) when set. Bare integers are treated as bytes, blocking all pod scheduling with a quota-exceeded error.
enable_pod_disruption_budgettrueMediumAlready enabled by default. Disabling allows all pods to be terminated simultaneously during GKE Autopilot node upgrades, causing brief service interruptions.
backup_retention_days7MediumAnalytics data loss is difficult to recover from. Increase to 30+ days for production deployments where historical analytics data has business value.
enable_backup_importfalseHighSetting this to true triggers a database restore on every apply. Only enable for the initial migration from an existing Umami instance; set back to false immediately after.
enable_vpc_scfalseMediumVPC-SC perimeter is only active when organization_id is also set. Without both, enable_vpc_sc = true has no enforcement effect.