Skip to main content

Ghost GKE Module — Configuration Guide

This guide describes every configuration variable available in the Ghost_GKE module. Ghost_GKE is a wrapper module that combines the generic App_GKE infrastructure module with the Ghost_Common shared application configuration to deploy the Ghost publishing platform on Google Kubernetes Engine (GKE) Autopilot.

Most configuration options in Ghost 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 Ghost 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 SectionGhost-Specific Notes
Module Metadata & Configuration§1 Module OverviewGhost-specific module_description, module_documentation, and module_services defaults are pre-set.
Project & Identity§2 IAM & Access ControlIdentical.
Application Identity§3.A Compute (GKE Autopilot)Ghost-specific defaults; see Group 2: Application Identity.
Runtime & Scaling§3.A Compute (GKE Autopilot)Ghost-specific defaults for container_port, cpu_limit, memory_limit, and min_instance_count; see Group 3: Runtime & Scaling.
Environment Variables & Secrets§3 Core Service Configurationdatabase__client = "mysql" is injected automatically. SMTP defaults pre-populated; see Group 5: Environment Variables & Secrets.
Networking & Network Policies§3.D Networking & Network PoliciesIdentical.
Initialization Jobs & CronJobs§3.E Initialization Jobs & CronJobsdb-init MySQL job supplied automatically by Ghost 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 true; see Group 9: Storage & Filesystem — NFS.
Storage — GCS§3.C Storage (NFS / GCS / GCS Fuse)ghost-content GCS bucket provisioned automatically; see Group 10: Storage & Filesystem — GCS.
Database Configuration§3.B Database (Cloud SQL)MySQL 8.0 required; see Group 11: 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)Two-path probe system; see Group 13: 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 ReservationGhost URL must be configured to match; see Group 16: 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 MirroringIdentical.
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 11: Database Configuration.
Redis Cache§8.A Redis / Memorystoreenable_redis defaults to true; see Group 15: Redis Cache.
Backup Import§8.B Backup ImportExposes both backup_uri (full GCS URI or Drive ID) and backup_file (filename in module backup bucket); see Group 6: Backup & Maintenance.
Service Mesh (ASM)§8.C Service Mesh (ASM via Fleet)Identical.
Multi-Cluster Services§8.D Multi-Cluster Services (MCS)Identical.

How Ghost GKE Relates to App GKE

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

  1. MySQL 8.0 is required. Ghost 6.x requires MySQL 8.0 and will not work with PostgreSQL. The database_type default is overridden to "MYSQL_8_0".
  2. database__client = "mysql" is injected automatically. Ghost 6.x will silently fall back to SQLite without this environment variable, even when all other database connection variables are present. The module injects it automatically — you do not need to set it yourself.
  3. A ghost-content GCS bucket is provisioned automatically. Ghost Common provides a ghost-content bucket definition that is merged into the module's bucket list. You do not need to define it in storage_buckets.
  4. A db-init job runs on first deployment. Ghost Common supplies a default db-init Kubernetes Job using a mysql:8.0-debian image that initialises the Ghost MySQL schema. Override initialization_jobs to replace it with a custom job.
  5. Resource defaults are sized for Ghost. The default cpu_limit (2 vCPU) and memory_limit (4 Gi) are higher than the App GKE defaults to match Ghost 6.x's resource requirements.
  6. Redis caching is enabled by default. Ghost uses Redis for page caching. See Group 15: Redis Cache and App_GKE §8.A for details.
  7. Health probes are tuned for Ghost's slow startup. Ghost runs database migrations and compiles themes on first boot. The default startup probe allows 90 seconds of initial delay before checking.

Group 0: Module Metadata & Configuration

The behaviour of these variables is identical to App_GKE. See App_GKE §1 for a full description.

Ghost-specific defaults:

VariableGhost GKE DefaultNotes
module_description"Ghost: Deploy Ghost publishing platform on GKE Autopilot…"Pre-populated with Ghost-specific description.
module_documentation"https://docs.radmodules.dev/docs/modules/Ghost_GKE"Points to the Ghost GKE documentation page.
module_servicesIncludes Ghost-relevant servicesAdds Cloud SQL (MySQL 8.0) and SMTP Integration to the standard list.

Group 1: Project & Identity

Identical to App_GKE. See App_GKE §2.

Ghost GKE-specific addition in this group:

VariableDefaultDescription
deployment_region"us-central1"GCP region for resource deployment. Used as a fallback when network discovery cannot determine the region from existing VPC subnets. Also used as the storage bucket location for the ghost-content bucket provisioned by Ghost Common.

Group 2: Application Identity

These variables behave identically to App_GKE. See App_GKE §3.A for descriptions.

Ghost-specific defaults:

VariableGhost GKE DefaultApp GKE DefaultNotes
application_name"ghost""gkeapp"Used as the base name for all GCP and Kubernetes resources. Do not change after deployment.
application_display_name"Ghost Blog""App GKE Application"Shown in the platform UI and dashboards. Can be changed freely.
display_name"Ghost Publishing Platform"(not in App GKE)Ghost GKE-specific alias for a human-readable UI name. Passed through to Ghost Common.
application_description"Ghost Publishing Platform on GKE Autopilot""App GKE Custom Application…"Descriptive label. Can be changed freely.
description"Ghost Publishing Platform on GKE Autopilot"(not in App GKE)Ghost GKE-specific alias for the deployment description. Passed to Ghost Common as the db-init job description.
application_version"6.14.0""1.0.0"The Ghost release version to build and deploy. Incrementing this value triggers a new Cloud Build run.

Group 3: Runtime & Scaling

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

Ghost-specific defaults and behaviour:

VariableGhost GKE DefaultApp GKE DefaultNotes
container_port23688080Ghost's native HTTP port. Do not change unless your custom Dockerfile binds Ghost to a different port.
max_instance_count5 [fixed in main.tf]3Ghost is more resource-intensive than a generic application; the higher ceiling accommodates traffic spikes during newsletter sends or content publication. The variable default is 5, and main.tf also hardcodes max_instance_count = 5 in the locals merge — changing the variable has no effect without editing main.tf directly.
cpu_limit"2000m""1000m"Ghost 6.x requires a minimum of 1 vCPU; 2 vCPU (2000m) is recommended for production to handle concurrent membership and admin requests without degradation.
memory_limit"4Gi""512Mi"Ghost 6.x uses significantly more memory than the base default. 4 Gi is recommended for production; do not set below 512 Mi or Ghost will OOMKill during theme compilation.
container_image_source"custom""custom"Ghost Common supplies a Dockerfile-based build by default so that Ghost can be customised with plugins and themes before deployment. Set to "prebuilt" to deploy the official Docker Hub Ghost image directly.
enable_cloudsql_volumetruetrueThe Cloud SQL Auth Proxy sidecar is required for Ghost to connect to Cloud SQL via a Unix socket. Only disable if connecting to Cloud SQL directly over a private TCP connection.

min_instance_count: The variable default is 1 (always at least one pod running — no scale-to-zero on GKE). Like max_instance_count, the value 1 is also hardcoded in the main.tf locals merge, so changing the variable via tfvars has no effect without editing main.tf directly.

container_resources: The variable default is { cpu_limit = "1000m", memory_limit = "512Mi" } (the App GKE base default). However, Ghost Common produces a config with cpu_limit = var.cpu_limit (default "2000m") and memory_limit = var.memory_limit (default "4Gi"), which are merged into container_resources in the main.tf locals block. This means the effective container resources for Ghost are 2 vCPU / 4 Gi by default, regardless of the container_resources variable default. To override both the cpu_limit / memory_limit shorthand variables and the container_resources object for consistency, set cpu_limit, memory_limit, and container_resources together.

The remaining runtime variables (deploy_application, container_image, container_build_config, enable_image_mirroring, enable_vertical_pod_autoscaling, container_protocol, container_resources, timeout_seconds, cloudsql_volume_mount_path, service_annotations, service_labels) behave as described in App_GKE Group 3.


Group 4: Access & Networking

These variables behave identically to App_GKE. See App_GKE §4, App_GKE §5, and App_GKE §3.D.

Note: The ingress_settings and vpc_egress_setting variables appear in Ghost GKE's variable definitions but are not passed through to App GKE. Setting these variables has no effect on the deployed infrastructure in the current implementation.

The following networking variables are available in Ghost 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_custom_domainfalseConfigures Ingress/Gateway for custom domain routing with managed SSL certificates.
application_domains[]Custom domain names (e.g. ["ghost.example.com"]).
reserve_static_iptrueReserves a Global Static IP for the load balancer.
static_ip_name""Name for the reserved IP; auto-generated if blank.
network_tags["nfsserver"]Firewall tags applied to GKE cluster nodes.
enable_cloud_armorfalseEnables a Cloud Armor WAF security policy.
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.
ingress_settings"all"Controls which traffic sources may reach the application (all, internal, internal-and-cloud-load-balancing).
vpc_egress_setting"PRIVATE_RANGES_ONLY"Controls whether only private-range traffic or all egress is routed through the VPC.

Group 5: Environment Variables & Secrets

These variables behave identically to App_GKE. See App_GKE §3.

Ghost-specific defaults:

Ghost pre-populates environment_variables with SMTP settings so that Ghost's email delivery (newsletter sends, member sign-up confirmations, password resets) can be configured without additional setup:

VariableDefault
SMTP_HOST"" (set to your SMTP server hostname)
SMTP_PORT"25"
SMTP_USER""
SMTP_PASSWORD""
SMTP_SSL"false"
EMAIL_FROM"ghost@example.com"

The database__client = "mysql" variable is injected automatically by the module. Do not set it manually in environment_variables — the module handles this to ensure Ghost 6.x connects to MySQL rather than falling back to SQLite.

Override environment_variables with a complete map to replace the SMTP defaults and add any additional Ghost configuration variables. To add variables without overriding the SMTP defaults, merge them in your Terraform configuration:

environment_variables = merge(
{
SMTP_HOST = "smtp.mailgun.org"
SMTP_PORT = "587"
SMTP_USER = "postmaster@mg.example.com"
SMTP_PASSWORD = "your-smtp-password"
SMTP_SSL = "true"
EMAIL_FROM = "noreply@example.com"
},
{
NODE_ENV = "production"
}
)

The remaining secrets variables (secret_environment_variables, secret_rotation_period, secret_propagation_delay, manage_storage_kms_iam) behave as described in App_GKE §3.


Group 6: Backup & Maintenance

These variables behave identically to App_GKE. See App_GKE §3.B.

Ghost-specific defaults:

VariableDefaultNotes
backup_schedule"0 2 * * *"Daily at 02:00 UTC. Adjust to match your Recovery Point Objective and traffic patterns.
backup_retention_days77-day retention. Increase for production deployments (30–90 days recommended).

Backup Import — Ghost GKE also supports importing an existing backup on first deployment:

VariableDefaultDescription
enable_backup_importfalseWhen true, runs a one-time import job during deployment to restore the backup specified by backup_uri. Configure backup_source, backup_uri, and backup_format before enabling.
backup_source"gcs"Source system for the backup file. "gcs" imports from a Cloud Storage URI; "gdrive" imports from a Google Drive file ID.
backup_uri""Full GCS URI ("gs://my-bucket/backups/ghost.sql") or Google Drive file ID. Mapped to backup_file in App GKE.
backup_file"backup.sql"Filename of a backup stored in the module's automatically created backups GCS bucket. An alternative to backup_uri for backups already placed in the module-managed bucket.
backup_format"sql"Format of the backup file. Supported values: sql, tar, gz, tgz, tar.gz, zip, auto.

Group 7: CI/CD & GitHub Integration

Identical to App_GKE. See App_GKE §6.

The following CI/CD variables are available: enable_cicd_trigger, github_repository_url, github_token, github_app_installation_id, cicd_trigger_config, enable_cloud_deploy, cloud_deploy_stages, enable_binary_authorization, binauthz_evaluation_mode (default "ALWAYS_ALLOW"; options: ALWAYS_ALLOW, REQUIRE_ATTESTATION, ALWAYS_DENY — controls enforcement mode when enable_binary_authorization is true).


Group 8: Jobs & Scheduled Tasks

These variables behave as described in App_GKE §3.E, with one important Ghost-specific behaviour.

Ghost default db-init job:

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

FieldValue
Job namedb-init
Imagemysql:8.0-debian
PurposeInitialises the Ghost MySQL database schema and user
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 and Additional Services:

The cron_jobs and additional_services variables are available and behave identically to App_GKE. See App_GKE §3.E for full documentation.

Note: The cron_jobs schema in Ghost GKE uses Kubernetes CronJob fields — restart_policy, concurrency_policy, failed_jobs_history_limit, successful_jobs_history_limit, starting_deadline_seconds, suspend — rather than the Cloud Run–style fields (parallelism, paused, max_retries, task_count) used in Ghost CloudRun. The secret_env_vars field is also not available in GKE cron jobs (secrets are managed via secret_environment_variables at the module level).


Group 9: Storage & Filesystem — NFS

These variables behave identically to App_GKE. See App_GKE §3.C.

Ghost-specific defaults:

VariableDefaultNotes
enable_nfstrueNFS storage is enabled by default. Ghost stores uploaded images, themes, and other content files on the shared NFS volume so that all pod replicas access the same filesystem. Disable only if using GCS Fuse exclusively for content storage.
nfs_mount_path"/mnt/nfs"The path where the NFS volume is mounted inside the Ghost container. Configure your Ghost Dockerfile to use this path for the content directory.

Group 10: Storage & Filesystem — GCS

These variables behave identically to App_GKE. See App_GKE Group 9.

Ghost-specific defaults:

Ghost Common automatically provisions a ghost-content GCS bucket in addition to any buckets defined in storage_buckets. This bucket is used for Ghost media storage via GCS Fuse. You do not need to define it manually.

Bucketname_suffixPurpose
Auto-provisionedghost-contentGhost media storage (images, files, themes) via GCS Fuse CSI Driver

The create_cloud_storage, storage_buckets, and gcs_volumes variables behave as described in App_GKE Group 9.


Group 11: Database Configuration

These variables behave identically to App_GKE. See App_GKE §3.B.

Ghost-specific defaults and restrictions:

VariableGhost GKE DefaultApp GKE DefaultNotes
database_type"MYSQL_8_0""POSTGRES"Ghost 6.x requires MySQL 8.0. Do not change this to a PostgreSQL or SQL Server variant — Ghost will not start.
application_database_name"gkeappdb""gkeappdb"Override to "ghost" or a meaningful name such as "ghost_prod".
application_database_user"gkeappuser""gkeappuser"Override to "ghost" or a meaningful name such as "ghost_svc".
db_name"ghost"(not in App GKE)Shorthand variable for the database name passed to Ghost Common. Controls the db_name field in the application_config used by Ghost (distinct from application_database_name, which controls what App GKE provisions in Cloud SQL).
db_user"ghost"(not in App GKE)Shorthand variable for the database user passed to Ghost Common. Controls the db_user field in the Ghost application_config (distinct from application_database_user).

Important: Ghost 6.x will silently use SQLite instead of MySQL if the database__client variable is not set. This module injects database__client = "mysql" automatically. Do not remove or override it.

Note: Unlike Ghost CloudRun (where database_type is fixed inside Ghost Common and not user-configurable), Ghost GKE exposes database_type as a user-configurable variable with a default of "MYSQL_8_0". The variable can technically be changed, but doing so will break Ghost — the application only supports MySQL 8.0.

Cloud SQL instance discovery:

VariableDefaultDescription
sql_instance_name""Name of an existing Cloud SQL instance to use. Leave empty to auto-discover a Services GCP-managed instance or create an inline instance.
sql_instance_base_name"app-sql"Base name for the inline Cloud SQL instance when no existing instance is found. Deployment ID is appended.

Automatic password rotation is also supported:

VariableDefaultDescription
enable_auto_password_rotationfalseDeploys an automated database password rotation job. When true, the database password is rotated on the schedule defined by secret_rotation_period and GKE pods are restarted to pick up the new credential.
rotation_propagation_delay_sec90Seconds to wait after rotation before restarting pods, to allow Secret Manager replication to complete.

Group 12: Custom SQL Scripts

Identical to App_GKE. See App_GKE §3.E.


Group 13: Observability & Health

These variables behave identically to App_GKE. See App_GKE §3.A.

Ghost-specific defaults:

Ghost 6.x performs database migrations and theme compilation during startup, which means the first boot after a fresh deployment takes significantly longer than subsequent boots. The health probe defaults are tuned to accommodate this.

Health probe routing

Ghost GKE exposes two parallel sets of probe variables that configure Kubernetes probes via different routing paths:

Variable setPassed toConfigures
startup_probe, liveness_probeGhost Common sub-moduleThe application container's Kubernetes probe spec (initialDelaySeconds, path, failureThreshold, etc.)
startup_probe_config, health_check_configApp GKE directlyThe App GKE-standard probe configuration used for load balancer health checks and GKE infrastructure probes

These are parallel paths, not aliases. Changing startup_probe does not affect startup_probe_config, and vice versa.

Important: startup_probe_config and health_check_config both default to path = "/healthz". Ghost does not expose a /healthz endpoint — its root path (/) returns HTTP 200 when healthy. If you rely on the App GKE-standard probes, override both variables to use path = "/" to match Ghost's actual health endpoint.

Startup probe (startup_probeGhost Common):

FieldGhost DefaultApp GKE DefaultNotes
path"/""/healthz"Ghost does not expose a dedicated /healthz endpoint; the root path is used instead.
initial_delay_seconds9010Allows Ghost 90 seconds before the first probe attempt, giving it time to run migrations.
failure_threshold103Ghost may take up to 100 seconds on first boot; 10 × period_seconds (10s) = 100s total allowance.

Liveness probe (liveness_probeGhost Common):

FieldGhost DefaultApp GKE DefaultNotes
path"/""/healthz"Same as startup probe — Ghost's root path returns HTTP 200 when healthy.
initial_delay_seconds6015Gives Ghost additional time to stabilise before liveness checks begin.

App GKE-standard probes (startup_probe_config, health_check_configApp GKE):

VariableGhost DefaultNotes
startup_probe_config{ enabled = true, path = "/healthz" }Override path to "/" for Ghost. Ghost's root path is the correct health endpoint.
health_check_config{ enabled = true, path = "/healthz" }Override path to "/" for Ghost. Same reason as above.

uptime_check_config: In Ghost GKE the default is { enabled = false, path = "/" } — uptime checks are disabled by default (unlike Ghost CloudRun where they are enabled). Enable explicitly for production monitoring.

The uptime_check_config and alert_policies variables behave as described in App_GKE §3.A.


Group 14: Reliability Policies

Identical to App_GKE. See App_GKE §7.

Available variables: enable_pod_disruption_budget, pdb_min_available, enable_topology_spread, topology_spread_strict.


Group 8: Resource Quota

Identical to App_GKE. See App_GKE §7.C.

Available variables: enable_resource_quota, quota_cpu_requests, quota_cpu_limits, quota_memory_requests, quota_memory_limits, quota_max_pods (default ""; max pods in namespace), quota_max_services (default ""; max services in namespace), quota_max_pvcs (default ""; max PVCs in namespace).


Group 16: Custom Domain & Static IP

Identical to App_GKE. See App_GKE §5.

Ghost URL configuration: Ghost must know its public URL at startup. When using a custom domain, configure the url Ghost setting (typically via an environment variable or the Ghost config.json) to match the domain in application_domains. Ghost uses this URL to generate links in newsletters and member emails — incorrect URL configuration will result in broken links.


Group 17: GKE Backend Configuration

Identical to App_GKE. See App_GKE §3.A.

Available variables: gke_cluster_name, namespace_name, workload_type, service_type, session_affinity, enable_multi_cluster_service, configure_service_mesh, enable_network_segmentation, termination_grace_period_seconds, deployment_timeout, gke_cluster_selection_mode (default "primary"; options: explicit, round-robin, primary), network_name (default ""; auto-discovered when empty), prereq_gke_subnet_cidr (default "10.201.0.0/24"; CIDR for inline GKE subnet creation).

Session affinity note: session_affinity defaults to "ClientIP" in Ghost GKE. This is important for Ghost: without session affinity, the Ghost admin panel and membership portal can experience intermittent authentication failures when requests are routed to different pod replicas that do not share session state.


Group 18: Stateful Workloads

Identical to App_GKE. See the StatefulSet configuration described in App_GKE §3.A (workload_type = "StatefulSet") and the associated StatefulSet variables.

Available variables: stateful_pvc_enabled, stateful_pvc_size, stateful_pvc_mount_path, stateful_pvc_storage_class, stateful_headless_service, stateful_pod_management_policy, stateful_update_strategy.


Group 15: Redis Cache

These variables configure Ghost's Redis integration. The underlying Redis infrastructure support is provided by App_GKE (see App_GKE §8.A); the variables below are Ghost-specific overrides and additions. Ghost uses Redis for page caching and session caching, which significantly reduces database load and improves page delivery speed for high-traffic sites.

Note: In Ghost GKE, the Redis variables are in group 15 (not group 21 as in Ghost CloudRun).

VariableDefaultOptions / FormatDescription & Implications
enable_redistruetrue / falseEnables Redis as Ghost's caching backend. When true and redis_host is blank, the module defaults to using the NFS server IP as the Redis host. Recommended for all production deployments. Disable only in development or testing environments where the additional infrastructure is not required. When disabled, Ghost serves all pages without a cache, which increases database query load and raises page load times under concurrent traffic.
redis_host"" (defaults to NFS server IP)Hostname or IP addressThe hostname or IP address of the Redis server Ghost connects to for caching. Leave blank to use the automatically discovered NFS server IP (which typically co-hosts a Redis process in the platform's default configuration). Override with an explicit IP or hostname when using a dedicated Redis instance — such as a Google Cloud Memorystore for Redis instance — for higher reliability and throughput. Example: "10.128.0.10", "redis.example.internal".
redis_port"6379"Port number stringThe TCP port on which the Redis server is listening. The default 6379 is the standard Redis port. Change only if your Redis instance is configured to listen on a non-standard port.
redis_auth""String (sensitive)The authentication password for the Redis server. Leave empty if the Redis instance does not require authentication (typical for the platform's default NFS co-hosted Redis). For production deployments using Google Cloud Memorystore with AUTH enabled, set this to the instance's AUTH string. This value is treated as sensitive and is never stored in Terraform state in plaintext.

Validating Group 15 Settings

Google Cloud Console:

  • Memorystore instance (if used): Navigate to Memorystore → Redis to confirm the instance exists, its IP address, port, and AUTH status.
  • Ghost cache status: Once deployed, navigate to the Ghost Admin panel (Settings → Labs) or check the Ghost container logs for cache connection confirmation messages.

gcloud CLI / kubectl:

# List Memorystore Redis instances in the project (if using Memorystore)
gcloud redis instances list \
--region=REGION \
--project=PROJECT_ID \
--format="table(name,host,port,state,memorySizeGb,authEnabled)"

# Confirm the Redis environment variables are set in the Ghost pod
kubectl exec -n NAMESPACE POD_NAME -- env | grep -i redis

# Test Redis connectivity from inside the Ghost pod
kubectl exec -n NAMESPACE POD_NAME -- \
nc -zv REDIS_HOST 6379

Module Outputs

Ghost GKE exposes the following Terraform outputs:

OutputDescription
service_nameName of the Kubernetes service
service_urlService URL
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
nfs_server_ipNFS server internal IP (sensitive)
nfs_mount_pathNFS mount path inside containers
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 — the cluster is created but the endpoint is not yet readable, so Kubernetes resources are skipped. The CI/CD pipeline must 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"MYSQL_8_0"CriticalGhost requires MySQL. Setting to POSTGRES or NONE causes Ghost to fail at startup with a database driver error. The GKE module wires MySQL credentials automatically; mismatched database type breaks all credential injection.
enable_redistrueHighRedis is on by default. When redis_host = "" the module falls back to the NFS server IP. If enable_nfs = false and redis_host is also empty, Ghost cannot connect to its caching layer and will crash at startup.
redis_host""HighAuto-resolves to NFS IP. If NFS is disabled and no explicit host is given, Ghost caching fails at boot.
enable_nfstrueCriticalGhost content (images, themes, uploaded files) must be stored on a shared volume. Without NFS, the /var/lib/ghost/content directory is isolated per pod — content uploaded to one pod is invisible to others, and all content is lost on pod restart.
container_image_source"custom"HighGhost requires a custom-built image to wire Cloud SQL socket paths and NFS content mounts. Using the upstream Ghost Docker Hub image with "prebuilt" will fail to connect to Cloud SQL via Unix socket.
container_port2368CriticalGhost listens on 2368. Changing this without matching the container's bound port causes all health probes to fail.
container_resources.memory_limit"4Gi" (via memory_limit)HighThe GKE container_resources default is only 512Mi. Ghost 6.x requires at least 1Gi at rest; active newsletter sends require 2–4Gi. Under-provisioning causes Node.js OOM crashes.
session_affinity"ClientIP"HighGhost uses server-side sessions for the admin panel. Without session affinity, admin users are logged out on every request that routes to a different pod. Keep "ClientIP" for any multi-replica Ghost GKE deployment.
db_name"ghost"CriticalImmutable after deployment — changing this recreates the database and destroys all Ghost content.
db_user"ghost"CriticalImmutable after deployment — changing this recreates the user, invalidates credentials, and breaks Ghost's database connection.
environment_variables (SMTP){ SMTP_HOST = "", ... }HighGhost relies on SMTP for member emails and password resets. An empty SMTP_HOST disables all outbound email. Configure a valid SMTP provider before inviting members.
min_instance_count1Medium0 allows scale-to-zero, causing cold starts during which Ghost runs database migrations. First requests after scale-up time out. Set to 1 for publications with consistent traffic.
workload_typenullMediumSetting stateful_pvc_enabled = true automatically selects StatefulSet. Do not set workload_type = "Deployment" alongside stateful_pvc_enabled = true — this fails at plan time.
stateful_pvc_size"10Gi"MediumGhost content directories can grow quickly with media uploads. 10Gi is a minimum — provision 50–100Gi for active publications accepting media uploads. PVC size can be expanded but not reduced.
backup_retention_days7MediumToo short for active publications. Increase to 30+ days.
quota_memory_requests / quota_memory_limits""Critical (GKE-specific)Must use binary suffixes (Gi, Mi) when set. Bare integers are treated as bytes and prevent all pods from being scheduled.
enable_pod_disruption_budgettrueMediumAlready enabled. Disabling allows all pods to be terminated simultaneously during node upgrades.
pdb_min_available"1"MediumWith a single replica, PDB prevents voluntary disruptions indefinitely. Use at least 2 replicas in production to allow rolling maintenance.
startup_probe initial_delay_seconds90HighGhost runs migrations on first boot. Reducing initial_delay_seconds below 60 causes Kubernetes to restart the pod before Ghost finishes initialising, creating a restart loop.
enable_cloud_armorfalseMediumWithout Cloud Armor, Ghost admin (/ghost) is protected only by Ghost's own authentication. Enable for any publicly accessible deployment.