Certification track: Associate Cloud Engineer (ACE)
Paperless-ngx GKE Module — Configuration Guide
This guide describes every configuration variable available in the Paperless_GKE module. Paperless_GKE is a wrapper module that combines the generic App_GKE infrastructure module with the Paperless_Common shared application configuration to deploy Paperless-ngx — an open-source document management system with OCR, full-text search, and automated tagging — on Google Kubernetes Engine (GKE) Autopilot.
Most configuration options in Paperless 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 Paperless-ngx 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 Area | App GKE.md Section | Paperless-Specific Notes |
|---|---|---|
| Project & Identity | §2 IAM & Access Control | Identical. |
| Application Identity | §3.A Compute (GKE Autopilot) | Paperless-specific defaults; see Group 2: Application Identity. |
| Runtime & Scaling | §3.A Compute (GKE Autopilot) | Paperless-specific defaults for container_port, cpu_limit, memory_limit, and timeout_seconds; see Group 3: Runtime & Scaling. |
| Environment Variables & Secrets | §3 Core Service Configuration | Two secrets auto-generated by Paperless Common; see Group 5: Environment Variables & Secrets. |
| Networking & Network Policies | §3.D Networking & Network Policies | Identical. |
| Initialization Jobs & CronJobs | §3.E Initialization Jobs & CronJobs | A default db-init job (from Paperless Common) creates the database and user; Django migrations then run automatically on startup; see Group 8: Jobs & Scheduled Tasks. |
| Additional Services | §3.F Additional Services | additional_services can be used to add Gotenberg or Tika; see Group 8: Jobs & Scheduled Tasks. |
| Storage — NFS | §3.C Storage (NFS / GCS / GCS Fuse) | enable_nfs defaults to true; required when no explicit redis_host is provided; see Group 9: Storage & Filesystem — NFS. |
| Storage — GCS | §3.C Storage (NFS / GCS / GCS Fuse) | paperless-media GCS bucket provisioned automatically; GCS FUSE auto-mounted at /usr/src/paperless/media; see Group 10: Storage & Filesystem — GCS. |
| Database Configuration | §3.B Database (Cloud SQL) | PostgreSQL 15 required; see Group 11: Database Configuration. |
| Backup Schedule & Retention | §3.B Database (Cloud SQL) | Identical. |
| Custom SQL Scripts | §3.E Initialization Jobs & CronJobs | Identical. |
| Observability & Health Checks | §3.A Compute (GKE Autopilot) | Two-path probe system; see Group 13: Observability & Health. |
| Cloud Armor WAF | §4.A Cloud Armor WAF | Identical. |
| Identity-Aware Proxy | §4.B Identity-Aware Proxy (IAP) | Identical. |
| Binary Authorization | §4.C Binary Authorization | Identical. |
| VPC Service Controls | §4.D VPC Service Controls | Identical. |
| Secrets Store CSI Driver | §4.E Secrets Store CSI Driver | Always enabled — no configuration required. |
| Traffic & Ingress | §5 Traffic & Ingress | Identical. |
| CDN | §5.B CDN | Identical. |
| Custom Domain & Static IP | §5.C Static IP Reservation | Identical. |
| Cloud Build Triggers | §6.A Cloud Build Triggers | Identical. |
| Cloud Deploy Pipeline | §6.B Cloud Deploy Pipeline | Identical. |
| Image Mirroring | §6.C Image Mirroring | enable_image_mirroring defaults to true; Paperless-ngx images are hosted on GHCR. |
| Pod Disruption Budgets | §7.A Pod Disruption Budgets | enable_pod_disruption_budget defaults to false; see Group 14: Reliability Policies. |
| Topology Spread Constraints | §7.B Topology Spread Constraints | Identical. |
| Resource Quotas | §7.C Resource Quotas | Identical. |
| Auto Password Rotation | §7.D Auto Password Rotation | See Group 11: Database Configuration. |
| Redis Cache | §8.A Redis / Memorystore | enable_redis defaults to true — Redis is required, not optional; see Group 15: Redis (Celery Broker). |
| Backup Import | §8.B Backup Import | 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 Paperless GKE Relates to App GKE
Paperless GKE passes all variables through to App GKE and adds a Paperless Common sub-module that supplies Paperless-ngx-specific defaults and application configuration. The main effects are:
- PostgreSQL 15 is required. Paperless-ngx only supports PostgreSQL. The database type is fixed to
"POSTGRES_15". - Two secrets are auto-generated by
Paperless Common.PAPERLESS_ADMIN_PASSWORDandPAPERLESS_SECRET_KEYare created in Secret Manager and injected into the container automatically. You do not need to create or manage these manually. - A
paperless-mediaGCS bucket is provisioned automatically.Paperless Commonprovides apaperless-mediabucket definition. By default, the GCS FUSE CSI Driver mounts this bucket at/usr/src/paperless/mediainside the container. You do not need to define this bucket instorage_buckets. - Redis is mandatory. Paperless-ngx uses Redis as the Celery message broker for all background document processing, OCR, consumption pipeline jobs, and async task scheduling. Unlike some other modules where Redis is optional for caching, removing Redis from Paperless-ngx causes background document processing to stop entirely.
- A default
db-initjob is supplied byPaperless Common. Wheninitialization_jobsis empty, adb-initKubernetes Job (imagepostgres:15-alpine, scriptdb-init.sh) creates the PostgreSQL database and application user before the workload starts. Django schema migrations then run automatically on container startup via the entrypoint script. - Resource defaults are sized for OCR workloads. The default
cpu_limit(2 vCPU) andmemory_limit(2 Gi) reflect Tesseract OCR requirements. OCR on multi-page PDFs is CPU-intensive — consider increasingcpu_limitfor high-volume ingestion. - Image mirroring is enabled by default. Paperless-ngx images are hosted on GitHub Container Registry (GHCR). The module mirrors the image to Artifact Registry by default to avoid GHCR rate limits.
timeout_secondsdefaults to 300 seconds (the same as theApp_GKEfoundation default — not an override). OCR processing on large documents can be slow, so this generous default prevents Kubernetes from terminating slow ingestion requests prematurely.
Group 1: Project & Identity
Identical to App_GKE. See App_GKE.
| Variable | Default | Description |
|---|---|---|
project_id | (required) | GCP project ID. |
region | "us-central1" | GCP region for resource deployment. Used as fallback when network discovery cannot determine the region from existing VPC subnets. Also used as the storage bucket location for the paperless-media bucket. |
Group 2: Application Identity
These variables behave identically to App_GKE. See App_GKE for descriptions.
Paperless-specific defaults:
| Variable | Paperless GKE Default | App GKE Default | Notes |
|---|---|---|---|
application_name | "paperless" | "gkeapp" | Used as the base name for all GCP and Kubernetes resources. Do not change after deployment. |
display_name | "Paperless-ngx - Document Management System" | "App GKE Application" | Shown in the platform UI and dashboards. Can be changed freely. |
description | "Paperless-ngx - open-source document management system with OCR, full-text search, and automated tagging" | "App GKE Custom Application…" | Descriptive label. Can be changed freely. |
application_version | "latest" | "1.0.0" | Paperless-ngx image version tag. Pin to a specific version (e.g., "2.13.5") for production deployments to ensure reproducible builds. |
Group 3: Runtime & Scaling
Most variables behave identically to App_GKE. See App_GKE Group 3.
Paperless-specific defaults and behaviour:
| Variable | Paperless GKE Default | App GKE Default | Notes |
|---|---|---|---|
container_port | 8000 | 8080 | Paperless-ngx gunicorn listens on port 8000. Do not change unless your custom Dockerfile binds to a different port. |
cpu_limit | "2000m" | "1000m" | Tesseract OCR is CPU-intensive, especially for multi-page PDFs. 2 vCPU is the minimum recommended for production. Increase to 4000m for high-volume document ingestion pipelines. |
memory_limit | "2Gi" | "512Mi" | Paperless-ngx loads document thumbnails, Tesseract language models, and ML classification models into memory. 2 Gi is the minimum; increase to 4 Gi for deployments processing large documents or multiple languages simultaneously. |
min_instance_count | 1 | 1 | Always at least one pod running. Scale-to-zero is not recommended — keeping one pod alive ensures the Celery worker process is always listening on the consumption directory. |
max_instance_count | 3 | 3 | Maximum pod replicas. Increase for high-volume document ingestion. |
timeout_seconds | 300 | 300 | Not overridden — App_GKE's own default is already 300s, which comfortably covers OCR on large, multi-page PDFs. |
enable_cloudsql_volume | true | true | Cloud SQL Auth Proxy sidecar is required. Paperless-ngx connects to PostgreSQL via the Auth Proxy Unix socket. |
enable_image_mirroring | true | true | Not overridden — App_GKE already mirrors by default. Still important for Paperless-ngx: GHCR-hosted images benefit from the Artifact Registry copy to avoid rate limits and satisfy Binary Authorization requirements. |
The remaining runtime variables (deploy_application, container_image, container_build_config, enable_vertical_pod_autoscaling, container_protocol, container_resources, 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, App_GKE, and App_GKE.
| Variable | Default | Description |
|---|---|---|
enable_iap | false | Enables Identity-Aware Proxy authentication on the load balancer. Recommended for document management deployments where access should be restricted to your organisation. |
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. |
enable_custom_domain | true | Configures Ingress/Gateway for custom domain routing with managed SSL certificates. Enabled by default — a Gateway with a static IP is provisioned automatically. |
application_domains | [] | Custom domain names (e.g. ["paperless.example.com"]). |
reserve_static_ip | true | Reserves 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. The nfsserver tag is required for NFS connectivity. |
enable_cloud_armor | false | Enables 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_sc | false | Enables VPC Service Controls perimeter enforcement. |
enable_cdn | false | Enables Cloud CDN on the load balancer. |
Group 5: Environment Variables & Secrets
These variables behave identically to App_GKE. See App_GKE.
Paperless-specific auto-generated secrets:
Paperless Common automatically creates and manages two application-level secrets in Secret Manager:
| Secret | Description |
|---|---|
PAPERLESS_ADMIN_PASSWORD | Password for the initial superuser account. Auto-generated at deploy time. Retrieve from Secret Manager to log in for the first time. |
PAPERLESS_SECRET_KEY | Django application secret key. Used for session signing and CSRF protection. Auto-generated at deploy time; not rotated automatically — regenerating it invalidates all active user sessions. |
Both secrets are injected into the container at pod start via the Secrets Store CSI Driver. The plaintext is never written to Terraform state.
Paperless-ngx-specific application settings (time_zone, ocr_language, admin_user, admin_email) are documented in Group 15: Paperless-ngx Application Settings.
The standard secrets variables (environment_variables, secret_environment_variables, secret_rotation_period, secret_propagation_delay, manage_storage_kms_iam) behave as described in App_GKE.
Group 6: Backup & Maintenance
These variables behave identically to App_GKE. See App_GKE.
Paperless-specific defaults:
| Variable | Default | Notes |
|---|---|---|
backup_schedule | "0 2 * * *" | Daily at 02:00 UTC. Adjust to match your Recovery Point Objective and business hours. |
backup_retention_days | 7 | 7-day retention. Increase to 30–90 days for production deployments handling legal or compliance documents. |
Backup Import — Paperless GKE supports importing an existing database backup on first deployment:
| Variable | Default | Description |
|---|---|---|
enable_backup_import | false | When true, runs a one-time import job during deployment to restore the backup specified by backup_uri. |
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 (e.g. "gs://my-bucket/backups/paperless.sql") or Google Drive file ID. |
backup_format | "sql" | Format of the backup file. Supported values: sql, tar, gz, tgz, tar.gz, zip, auto. |
Note: A backup import restores the PostgreSQL database only. Document files stored in the GCS media bucket must be migrated separately — copy them into the
paperless-mediabucket after the database restore completes.
Group 7: CI/CD & GitHub Integration
Identical to App_GKE. See App_GKE.
Available variables: 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.
Group 8: Jobs & Scheduled Tasks
These variables behave as described in App_GKE.
Default db-init job: When initialization_jobs is empty (the default), Paperless Common supplies a db-init Kubernetes Job (image postgres:15-alpine, script scripts/db-init.sh, execute_on_apply = true) that creates the PostgreSQL database and application user. Django schema migrations then run automatically as part of the container entrypoint on first boot. Supplying a non-empty initialization_jobs list replaces the default job.
Gotenberg and Tika as additional services: Paperless-ngx supports optional integration with Gotenberg (advanced document conversion) and Apache Tika (content extraction from Office files). These are not provisioned by default. To add them, define them in additional_services:
| Service | Image | Port | Purpose |
|---|---|---|---|
| Gotenberg | gotenberg/gotenberg:7 | 3000 | Convert Office documents, HTML, and URLs to PDF before OCR |
| Tika | apache/tika:latest | 9998 | Extract text content from .docx, .xlsx, .pptx and other Office formats |
Once added, configure Paperless-ngx to use them by setting PAPERLESS_TIKA_ENABLED=true, PAPERLESS_TIKA_ENDPOINT, and PAPERLESS_TIKA_GOTENBERG_ENDPOINT in environment_variables.
CronJobs:
The cron_jobs variable is available for tasks such as periodic document re-classification or index rebuilds. See App_GKE for full schema documentation.
Note: Unlike Cloud Run–style jobs, GKE CronJobs use
restart_policy,concurrency_policy,failed_jobs_history_limit,successful_jobs_history_limit,starting_deadline_seconds, andsuspendfields. The Cloud Run–style fields (parallelism,paused,max_retries,task_count) are not available.
Group 9: Storage & Filesystem — NFS
These variables behave identically to App_GKE. See App_GKE.
Paperless-specific defaults:
| Variable | Default | Notes |
|---|---|---|
enable_nfs | true | NFS storage is enabled by default. When enable_redis = true and no external redis_host is provided, the module uses the NFS server IP as the Redis host. If you disable NFS, you must provide an explicit redis_host. |
nfs_mount_path | "/mnt/nfs" | The path where the NFS volume is mounted inside the container. This is distinct from the document storage path (/usr/src/paperless/media), which is mounted via GCS FUSE. |
Group 10: Storage & Filesystem — GCS
These variables behave identically to App_GKE. See App_GKE Group 9.
Paperless-specific auto-provisioned bucket:
Paperless Common automatically provisions a paperless-media GCS bucket and, by default, mounts it via the GCS FUSE CSI Driver at /usr/src/paperless/media inside the container. This is the path where Paperless-ngx stores:
- Original document files (before OCR processing)
- Processed document files (after OCR and classification)
- Thumbnail images for the web UI
- Temporary consumption directory for new document ingestion
| Bucket | name_suffix | Mount Path | Purpose |
|---|---|---|---|
| Auto-provisioned | paperless-media | /usr/src/paperless/media | Persistent document storage via GCS FUSE |
You do not need to define this bucket in storage_buckets. Override gcs_volumes to customise the mount options or add additional volume mounts.
GCS FUSE default mount options:
The default gcs_volumes configuration mounts the media bucket with implicit-dirs, stat-cache-ttl=60s, and type-cache-ttl=60s. These settings are appropriate for Paperless-ngx's sequential write pattern (documents are written once and then read). For high-throughput ingestion, consider reducing cache TTLs or using metadata-cache-ttl=0 to ensure immediate consistency.
The create_cloud_storage, storage_buckets, gcs_volumes, manage_storage_kms_iam, enable_artifact_registry_cmek, max_images_to_retain, delete_untagged_images, and image_retention_days variables behave as described in App_GKE Group 9.
Group 11: Database Configuration
These variables behave identically to App_GKE. See App_GKE.
Paperless-specific defaults and restrictions:
| Variable | Paperless GKE Default | App GKE Default | Notes |
|---|---|---|---|
db_name | "paperless" | "gkeappdb" | Name of the PostgreSQL database created for Paperless-ngx. Immutable after deployment — changing this value recreates the database and destroys all document metadata. |
db_user | "paperless" | "gkeappuser" | PostgreSQL user for Paperless-ngx. Immutable after deployment. |
database_password_length | 32 | 32 | Length of the auto-generated database password. Valid range: 16–64 characters. |
Important: Paperless-ngx requires PostgreSQL. Do not change
database_typeto a MySQL or SQL Server variant — Paperless-ngx's Django ORM only supports PostgreSQL.
Cloud SQL instance discovery:
| Variable | Default | Description |
|---|---|---|
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:
| Variable | Default | Description |
|---|---|---|
enable_auto_password_rotation | false | Deploys 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_sec | 90 | Seconds 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.
Available variables: enable_custom_sql_scripts, custom_sql_scripts_bucket, custom_sql_scripts_path, custom_sql_scripts_use_root.
Group 13: Observability & Health
These variables behave identically to App_GKE. See App_GKE.
Paperless-specific defaults:
Paperless-ngx runs Django database migrations and initialises Celery workers on first boot. The health probe defaults accommodate this startup delay.
Health probe routing
Paperless GKE exposes two parallel sets of probe variables that configure Kubernetes probes via different routing paths:
| Variable set | Passed to | Configures |
|---|---|---|
startup_probe, liveness_probe | Paperless Common sub-module | The application container's Kubernetes probe spec (initialDelaySeconds, path, failureThreshold, etc.) |
startup_probe_config, health_check_config | App GKE directly | The 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.
Startup probe (startup_probe → Paperless Common):
| Field | Paperless Default | Notes |
|---|---|---|
type | "HTTP" | HTTP GET probe against the root path. |
path | "/" | Paperless-ngx login page returns HTTP 200 when the application is ready. |
initial_delay_seconds | 60 | Allows 60 seconds before the first probe attempt, accommodating database migration time on first boot. |
timeout_seconds | 10 | Probe timeout per attempt. |
period_seconds | 10 | Probe interval. |
failure_threshold | 30 | Up to 300 seconds (30 × 10s) of startup allowance before the pod is restarted. |
Liveness probe (liveness_probe → Paperless Common):
| Field | Paperless Default | Notes |
|---|---|---|
type | "HTTP" | HTTP GET probe. |
path | "/" | Root path returns HTTP 200 when the application is healthy. |
initial_delay_seconds | 60 | Gives Paperless-ngx time to complete startup before liveness checks begin. |
period_seconds | 30 | Less frequent than startup probe — appropriate for a stable running service. |
failure_threshold | 3 | Three consecutive failures trigger a pod restart. |
App GKE-standard probes (startup_probe_config, health_check_config → App GKE):
| Variable | Paperless Default | Notes |
|---|---|---|
startup_probe_config | { enabled = true, type = "TCP", timeout_seconds = 240, period_seconds = 240, failure_threshold = 1 } | TCP probe on container_port (8000). Allows up to 240 seconds for startup. |
health_check_config | { enabled = true, type = "HTTP", path = "/" } | HTTP GET against /. Paperless-ngx's root path is the correct health endpoint. |
uptime_check_config: Defaults to { enabled = false, path = "/" } — uptime checks are disabled by default. Enable explicitly for production monitoring.
Group 14: Reliability Policies
These variables behave identically to App_GKE. See App_GKE.
Paperless-specific defaults:
| Variable | Paperless GKE Default | App GKE Default | Notes |
|---|---|---|---|
enable_pod_disruption_budget | false | true | PDB is disabled by default in Paperless GKE. Enable for production deployments where document processing continuity during node maintenance is important. |
pdb_min_available | 1 | 1 | Minimum pods that must remain available during disruptions. |
Available variables: enable_pod_disruption_budget, pdb_min_available, enable_topology_spread, topology_spread_strict.
Group 15: Paperless-ngx Application Settings
These variables are specific to Paperless-ngx and are passed directly to Paperless Common. They control the application's runtime behaviour and are not present in App_GKE.
| Variable | Default | Options / Format | Description & Implications |
|---|---|---|---|
time_zone | "UTC" | IANA timezone string (e.g. "Europe/London", "America/New_York") | Timezone used for document timestamps, scheduled task execution, and date parsing in document titles. Important for document date recognition: Paperless-ngx uses the configured timezone when parsing dates from document filenames and metadata. Set this to match the timezone of the documents you are scanning to avoid off-by-one-day errors on date-based filing rules. |
ocr_language | "eng" | ISO 639-2/T Tesseract language code. Combine multiple with + (e.g. "fra+eng", "deu+eng") | Primary OCR language pack loaded by Tesseract. Setting the correct language significantly improves OCR accuracy. For multilingual archives, combine codes — each additional language increases memory usage and OCR processing time. Available codes: eng (English), deu (German), fra (French), spa (Spanish), ita (Italian), nld (Dutch), por (Portuguese), and many others. |
admin_user | "admin" | String | Username for the initial Paperless-ngx superuser account, created on first startup. Used to log into the web UI and the REST API. Change to a non-default username to reduce exposure to credential guessing attacks. |
admin_email | "admin@example.com" | Valid email address | Email address associated with the initial admin account. Used for password recovery and system notifications. Set to a valid address you control before the first deployment. |
Validating Group 15 Settings
Google Cloud Console:
- Secret Manager: Navigate to Security → Secret Manager and confirm that
PAPERLESS_ADMIN_PASSWORDandPAPERLESS_SECRET_KEYexist. Use Access Secret Version to retrieve the admin password for first login. - GKE Workloads: Navigate to Kubernetes Engine → Workloads and confirm the Paperless-ngx deployment is running. Click the deployment to view the pod's environment variable configuration.
gcloud CLI / kubectl:
# Retrieve the admin password from Secret Manager
# (secret name pattern: secret-<resource-prefix>-paperless-admin-password)
gcloud secrets versions access latest \
--secret="secret-RESOURCE_PREFIX-paperless-admin-password" \
--project=PROJECT_ID
# Confirm the OCR language environment variable is set in the running pod
kubectl exec -n NAMESPACE POD_NAME -- env | grep PAPERLESS_OCR_LANGUAGE
# Confirm the timezone environment variable
kubectl exec -n NAMESPACE POD_NAME -- env | grep PAPERLESS_TIME_ZONE
# Check Paperless-ngx startup logs for migration output
kubectl logs -n NAMESPACE POD_NAME --since=10m | grep -i "migration\|celery\|ready"
Group 16: Redis (Celery Broker)
These variables configure Paperless-ngx's Redis integration. The underlying Redis infrastructure support is provided by App_GKE (see App_GKE). Redis is not optional for Paperless-ngx — it is the Celery message broker that drives all background document processing, OCR tasks, and the consumption pipeline.
Note: In
Paperless GKE, the Redis variables are in group 21.
| Variable | Default | Options / Format | Description & Implications |
|---|---|---|---|
enable_redis | true | true / false | Enables Redis as the Paperless-ngx Celery broker and result backend. Must remain true for Paperless-ngx to function. When true and redis_host is blank, the module defaults to using the NFS server IP as the Redis host. Disabling Redis causes all background OCR processing, document classification, and the consumption pipeline to stop. Documents dropped into the consumption directory will not be processed. |
redis_host | "" (defaults to NFS server IP) | Hostname or IP address | The hostname or IP address of the Redis server. Leave blank to use the automatically discovered NFS server IP (which 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 Google Cloud Memorystore. Example: "10.128.0.10". |
redis_port | "6379" | Port number string | The TCP port on which the Redis server is listening. The default 6379 is the standard Redis port. |
redis_auth | "" | String (sensitive) | Authentication password for the Redis server. Leave empty if the Redis instance does not require authentication. For Google Cloud Memorystore with AUTH enabled, set this to the instance's AUTH string. |
Validating Redis Settings
Google Cloud Console:
- Memorystore instance (if used): Navigate to Memorystore → Redis to confirm the instance exists, its IP address, port, and AUTH status.
- GKE pod environment: Navigate to Kubernetes Engine → Workloads, select the Paperless-ngx deployment, and check the pod's environment variables for
PAPERLESS_REDIS.
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 connection string is set in the Paperless-ngx pod
kubectl exec -n NAMESPACE POD_NAME -- env | grep PAPERLESS_REDIS
# Test Redis connectivity from inside the Paperless-ngx pod
kubectl exec -n NAMESPACE POD_NAME -- \
nc -zv REDIS_HOST 6379
# Check Celery worker status in logs
kubectl logs -n NAMESPACE POD_NAME | grep -i "celery\|broker\|ready"
Group 17: GKE Backend Configuration
Identical to App_GKE. See App_GKE.
Paperless-specific defaults:
| Variable | Paperless GKE Default | Notes |
|---|---|---|
session_affinity | "ClientIP" | Ensures document upload sessions are routed to the same pod replica. Without session affinity, multi-part uploads and admin sessions can experience failures when routed to different replicas. |
service_type | "LoadBalancer" | Exposes Paperless-ngx via a Google Cloud Load Balancer. |
termination_grace_period_seconds | 60 | Allows in-progress OCR tasks to complete before the pod is terminated. Consider increasing to 120+ seconds for deployments processing large documents. |
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, network_name, prereq_gke_subnet_cidr.
Group 18: Stateful Workloads
Identical to App_GKE. See the StatefulSet configuration described in App_GKE.
Setting stateful_pvc_enabled = true automatically selects workload_type = "StatefulSet". When using a StatefulSet for Paperless-ngx, the PVC provides a per-pod persistent volume in addition to the shared GCS FUSE media mount. This can be used to store the Paperless-ngx SQLite consumption database or temporary OCR working files.
| Variable | Default | Notes |
|---|---|---|
stateful_pvc_enabled | null | Set to true to enable StatefulSet with per-pod PVC. Auto-selects workload_type = "StatefulSet". |
stateful_pvc_size | "10Gi" | Initial PVC size. Expand as needed — GKE Autopilot supports PVC expansion. |
stateful_pvc_mount_path | "/data" | Container path where the per-pod PVC is mounted. Distinct from the GCS FUSE media mount at /usr/src/paperless/media. |
stateful_pvc_storage_class | "standard-rwo" | StorageClass for the PVC. standard-rwo provisions a Compute Engine Persistent Disk (ReadWriteOnce). |
stateful_headless_service | null | Create a headless service for stable pod DNS identities. |
stateful_pod_management_policy | null | "OrderedReady" or "Parallel". |
stateful_update_strategy | null | "RollingUpdate" or "OnDelete". |
stateful_fs_group | 0 | GID for the pod-level fsGroup in the security context. |
Module Outputs
Paperless GKE exposes the following Terraform outputs:
| Output | Description |
|---|---|
service_name | Name of the Kubernetes service |
service_cluster_ip | In-cluster ClusterIP of the Kubernetes service |
service_external_ip | External IP address of the load balancer |
project_id | GCP project ID |
deployment_id | Deployment ID suffix |
namespace | Kubernetes namespace |
database_instance_name | Name of the Cloud SQL instance |
database_name | Name of the application database |
database_user | Name of the application database user |
database_password_secret | Secret Manager secret name for the database password |
storage_buckets | Created GCS storage buckets (includes the auto-provisioned media bucket) |
container_image | Container image used for the deployment |
cicd_enabled | Whether the CI/CD pipeline is enabled |
github_repository_url | GitHub repository URL connected for CI/CD |
kubernetes_ready | true 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).
| Variable | Sensible Default | Risk | Consequence of Incorrect Value |
|---|---|---|---|
project_id | (required) | Critical | No default — deployment fails immediately. |
enable_redis | true | Critical | Redis is the Celery broker. Disabling it stops all background processing. Documents dropped into the consumption directory are silently queued but never processed. The Paperless-ngx web UI remains accessible but shows no new documents being ingested. |
redis_host | "" | High | Auto-resolves to NFS IP. If NFS is disabled and no explicit host is given, Celery cannot connect to its broker and the consumption pipeline fails at startup. |
enable_nfs | true | High | Required when redis_host is blank. Disabling NFS without providing an explicit Redis host causes Celery startup failure. |
container_port | 8000 | Critical | Paperless-ngx gunicorn listens on 8000. Changing this without matching the container's bound port causes all health probes to fail immediately. |
memory_limit | "2Gi" | High | Tesseract OCR loads language models and document thumbnails into memory. Under-provisioning (below 1Gi) causes OOM kills during document processing, particularly for multi-page PDFs or multi-language OCR. |
cpu_limit | "2000m" | Medium | OCR is CPU-intensive. Reducing below 1 vCPU slows OCR significantly; at 500m, large documents may time out before OCR completes. |
timeout_seconds | 300 | Medium | OCR on large PDFs can take several minutes. Reducing below 120 seconds causes gunicorn to kill slow OCR requests. |
ocr_language | "eng" | Medium | Using the wrong language pack produces garbage OCR output. Full-text search and auto-tagging based on document content will not work correctly for non-English documents unless the correct language pack is specified. |
time_zone | "UTC" | Low | Incorrect timezone causes document dates parsed from filenames and metadata to be off by hours. Date-based filing rules and scheduler tasks run at unexpected times. |
admin_email | "admin@example.com" | Medium | The initial admin account is created with this email. Set to a real address to enable password recovery. |
db_name | "paperless" | Critical | Immutable after deployment — changing this recreates the database and destroys all document metadata, tags, correspondents, and filing rules. |
db_user | "paperless" | Critical | Immutable after deployment — changing this recreates the user, invalidates credentials, and breaks Paperless-ngx's database connection. |
stateful_pvc_size | "10Gi" | Medium | If using StatefulSet with PVC for local storage, 10 Gi may fill quickly with temporary OCR working files. Monitor disk usage and expand as needed. |
backup_retention_days | 7 | Medium | Insufficient for compliance-sensitive document archives. Increase to 30–90 days for legal or regulatory document management deployments. |
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_budget | false | Medium | PDB is disabled by default. Without a PDB, node maintenance can terminate all pods simultaneously, interrupting active OCR processing and causing documents to be re-queued or lost from the pipeline. |