Skip to main content

SearXNG on Google Kubernetes Engine (GKE Autopilot)

This document provides a comprehensive reference for the modules/SearXNG_GKE Terraform module. It covers architecture, IAM, configuration variables, SearXNG-specific behaviours, and operational patterns for deploying SearXNG on GKE Autopilot.


1. Module Overview

SearXNG is a privacy-respecting, self-hosted metasearch engine with 10,000+ GitHub stars that aggregates results from 70+ search services without tracking users or serving ads. SearXNG GKE is a wrapper module built on top of App GKE. It uses App GKE for all GCP infrastructure provisioning and injects SearXNG-specific application configuration via SearXNG Common.

Key Capabilities:

  • Compute: GKE Autopilot, Kubernetes Deployment. min_instance_count = 1 (hardcoded in searxng.tf), max_instance_count user-configurable (default: 3). Default resources: 500m CPU / 512 Mi.
  • Stateless: SearXNG does not use a database. No Cloud SQL instance is provisioned.
  • IAM: Workload Identity binds the Kubernetes SA to a GCP SA for Secret Manager access (SEARXNG_SECRET).
  • Redis (optional): Redis for rate limiting and bot detection via enable_redis.
  • SEARXNG_SECRET: Auto-generated by SearXNG Common and stored in Secret Manager. Injected via the CSI Secret Manager driver.
  • Health: Health probes target /healthz.

Project & Application Identity

VariableGroupTypeDefaultDescription
project_id1stringGCP project ID. Required.
tenant_deployment_id2string'demo'Short suffix appended to all resource names.
support_users2list(string)[]Email recipients for monitoring alerts.
resource_labels2map(string){}Labels applied to all provisioned resources.
application_name3string'searxng'Base resource name. Do not change after initial deployment.
application_display_name3string'SearXNG Search'Human-readable name.
application_description3string'SearXNG — privacy-respecting metasearch engine on GKE Autopilot'Application description.
application_version3string'latest'SearXNG image version tag.

Wrapper architecture: SearXNG GKE calls SearXNG Common to produce the application configuration. min_instance_count = 1 is hardcoded in the searxng_module merge in searxng.tf. SEARXNG_BIND_ADDRESS, ENABLE_REDIS, and REDIS_URL are injected via module_env_vars. The SEARXNG_SECRET is injected via Kubernetes secret (CSI Secret Manager driver) rather than a direct environment variable reference.


2. IAM & Access Control

Workload Identity binds the Kubernetes SA to a GCP SA. The only Secret Manager secret accessed is SEARXNG_SECRET. SearXNG Common outputs the explicit secret value so the CSI driver can inject it without read-after-write consistency issues on first apply.


3. Core Service Configuration

A. Compute (GKE Autopilot)

VariableGroupDefaultDescription
deploy_application4trueSet false for infrastructure-only deployment.
container_image_source4'prebuilt''prebuilt' (official image) or 'custom'.
container_image4""Container image URI override.
container_resources4{ cpu_limit="500m", memory_limit="512Mi" }CPU/memory limits and requests.
min_instance_count41 [fixed in searxng.tf]Minimum pod replicas. Hardcoded to 1 in the module merge.
max_instance_count43Maximum pod replicas.
container_port48080SearXNG's HTTP port.
enable_vertical_pod_autoscaling4falseEnables VPA.
enable_image_mirroring4trueMirrors the SearXNG image into Artifact Registry.

B. GKE Backend Configuration

VariableGroupDefaultDescription
gke_cluster_name""GKE cluster name. Leave empty to auto-discover.
namespace_name""Kubernetes namespace. Leave empty to auto-generate.
service_type'ClusterIP'Kubernetes Service type. Use 'LoadBalancer' for external access.
workload_typenull'Deployment' (default for SearXNG) or 'StatefulSet'.

C. Environment Variables

VariableGroupDefaultDescription
environment_variables{}Additional plain-text env vars for SearXNG configuration.

SEARXNG_BIND_ADDRESS, ENABLE_REDIS, and REDIS_URL are injected automatically via module_env_vars.

D. Observability

VariableGroupDefaultDescription
startup_probe{ path="/healthz", initial_delay_seconds=10, failure_threshold=6 }Startup probe.
liveness_probe{ path="/healthz", initial_delay_seconds=15, failure_threshold=3 }Liveness probe.

4. Redis Integration

VariableGroupDefaultDescription
enable_redis15falseEnables Redis for rate limiting and bot detection.
redis_host15""Redis hostname/IP. Defaults to 127.0.0.1 when enable_redis = true and no host is specified.
redis_port15'6379'Redis TCP port.
redis_auth15""Redis AUTH password. Sensitive.

5. CI/CD

VariableGroupDefaultDescription
enable_cicd_trigger8falseProvisions a Cloud Build GitHub trigger.
github_repository_url8""Full HTTPS URL of the GitHub repository.
enable_cloud_deploy8falseProvisions a Cloud Deploy pipeline.

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
SEARXNG_SECRET (auto-generated by Common)(auto-generated — stored in Secret Manager)CriticalSearXNG uses SEARXNG_SECRET to sign sessions and HMAC parameters. On GKE, the secret is stable (stored in Secret Manager and injected at pod start). However, if the secret is somehow different across pod replicas (e.g., due to a custom override that generates per-pod values), session cookies from one pod are invalid on another pod, breaking load-balanced sessions. Use the auto-generated Secret Manager value — never override with a per-pod random.
min_instance_count1HighGKE default is 1 (required). If HPA scales to zero, the next scale-up triggers a cold start with no session continuity. For SearXNG, ensure HPA minimum replicas remain at 1 or more.
enable_redisfalseHighWithout Redis, SearXNG has no rate limiting or result caching. Public-facing deployments without Redis are vulnerable to scraping and upstream API quota exhaustion. Enable Redis and set redis_host for production.
redis_host""HighWhen enable_redis = true and redis_host is empty, SearXNG defaults to 127.0.0.1 (no reachable Redis in a GKE pod). Rate limiting and caching are silently disabled. Set to the Memorystore Redis IP from Services GCP.
memory_limit"512Mi"MediumSearXNG is lightweight but aggregates results from many engines concurrently. Under high load, 256Mi causes OOM kills. Scale to 1Gi for heavy-traffic public instances.
cpu_limit"1000m"MediumResult aggregation and de-duplication are CPU-bound. Below 500m, high-concurrency requests degrade in latency.
stateful_pvc_enablednullLowSearXNG is stateless — no PVC is needed. Leave null. Setting stateful_pvc_enabled = true provisions an unused disk, wasting cost.
workload_typenullLowSearXNG is stateless — Deployment is the correct workload type. Using StatefulSet without a PVC is unnecessary and wastes scheduler resources.
application_version"latest"MediumUsing "latest" makes deployments non-reproducible. Pin to a specific SearXNG version for production.
enable_iapfalseMediumFor internal-only search deployments, enable IAP to restrict access to authenticated users. For public meta-search, rely on Redis rate limiting.
SerpAPI key / engine API keys (env vars)(not set)MediumMany search engines require API keys for reliable scraping. Inject via secret_environment_variables for production to avoid key exposure in logs.
quota_memory_requests""CriticalIf enable_resource_quota = true and set without binary suffixes (e.g. "4" instead of "4Gi"), Kubernetes treats it as bytes, blocking all pod scheduling. Always use Gi or Mi.
max_instance_count1MediumMultiple SearXNG replicas share Redis for session state. Ensure Redis maxmemory-policy = allkeys-lru to prevent unbounded growth as session keys accumulate across replicas.

6. Outputs

OutputDescription
service_nameName of the Kubernetes Service.
service_urlURL of the SearXNG deployment.
project_idGCP project ID.
deployment_idDeployment ID suffix used in resource names.