Dawarich Helm Chart
Private location history with the official Dawarich image, PostGIS and authenticated Redis. Rails, Sidekiq and the public NGINX proxy run together in a single Recreate Pod so local attachments and watched imports have consistent storage ownership and scheduling.
Installation
Create an administrator password Secret through the cluster’s approved secret management workflow, then configure the stable browser-visible origin:
server:
publicUrl: https://locations.example.com
bootstrap:
email: [email protected]
existingSecret: dawarich-administrator
passwordKey: password
ingress:
enabled: true
ingressClassName: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
nginx.ingress.kubernetes.io/proxy-body-size: 100m
hosts:
- host: locations.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: locations-tls
hosts: [locations.example.com]
networkPolicy:
ingressFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm upgrade --install dawarich helmforge/dawarich \
--namespace locations --create-namespace --values production-values.yaml
The initial password requires at least 16 characters and at most 72 UTF-8 bytes. If an existing Secret or explicit password is omitted, the chart generates and retains an initial credential. It does not reset an existing account when the credential changes.
Administrator and registration policy
Initialization applies native schema and data migrations, creates the first user through the native Rails model and its password/API-key callbacks, and only then runs the upstream seeds. This prevents the known demo account from becoming the initial public administrator. No HTTP server runs during model provisioning. An existing unsafe demo credential blocks startup and requires explicit repair.
The public proxy forwards to a Rails listener bound exclusively to loopback. It denies the unconditional native API registration routes, Apple/Google enrollment, the OAuth web namespace and the public signup page. The chart implements a local-account policy; enabling an OAuth environment variable does not remove these guards.
A chart-owned initializer uses the Rails middleware extension point to reject Devise account creation after
Rack::MethodOverride has interpreted HTML form methods. This preserves the distinction between registration and
authenticated PUT/PATCH/DELETE profile operations. The bootstrap also disables the native cached registration setting.
These are explicit chart adaptations, not an upstream universal registration flag.
Native administrator user management and trusted Rails console access remain operator responsibilities. The policy does not attempt to restrict a cluster administrator with Pod exec access.
Data and identity
The application PVC contains native local storage, the shared public directory, imports and an identity fingerprint. Separate bounded emptyDirs provide temporary files, Rails logs and NGINX scratch space. The application runs as UID/GID 1000 with a read-only image filesystem, dropped capabilities and no Kubernetes API token.
The retained identity Secret holds SECRET_KEY_BASE, OTP_ENCRYPTION_PRIMARY_KEY, OTP_ENCRYPTION_DETERMINISTIC_KEY
and OTP_ENCRYPTION_KEY_DERIVATION_SALT. An existing user database must match the fingerprint on its PVC. Preserve all
four keys when replacing Pods, upgrading or restoring data. Changing them is an explicit native key-rotation operation.
Quiesce both Rails and Sidekiq before coordinating a PostGIS dump with a complete filesystem snapshot or archive. Retain the matching identity and dependency Secrets. PVC retention alone does not provide an off-cluster backup or prove that a backup can be restored.
PostGIS and Redis
The PostgreSQL subchart uses the official PostGIS 18-3.6 image, pinned by digest and verified with PostgreSQL 18.6, and
installs postgis and pgcrypto in the application database. The verified bundled image targets amd64; the database
Pod has a matching architecture selector. An ARM application deployment requires a separately operated, compatible
PostGIS database.
Disable postgresql.enabled and configure database.* for external PostGIS. The application role needs migration
privileges and must own its application objects; the DBA installs the required extensions first. External TLS uses libpq
verify-full and requires an explicit CA Secret.
Disable redis.enabled and configure cache.* independently for external Redis. Cache and job queues require distinct
logical databases. Redis Cluster is not a drop-in replacement. Credentials are URL-encoded, including reserved
characters and IPv6 host formatting. Custom Redis CA trust augments the image’s system bundle for Ruby/OpenSSL clients;
it does not disable certificate or hostname verification. That additional trust is process-wide. Rotate trust and
credentials through a controlled restart.
Bundled Redis enables authentication, persistence and noeviction. Its NetworkPolicy accepts only this release’s
application Pods and denies egress. External connections need explicit networkPolicy.extraEgress rules for their
destination addresses and ports. Reverse-geocoding services are not configured by default.
Exposure and health
Use Ingress or canonical gatewayAPI.httpRoutes[] with explicit parent references. Controllers must support the
selected HTTPS origin, upload limits and WebSocket upgrades. The internal proxy streams responses without buffering
large exports into its temporary volume. proxy.bodySize bounds incoming requests.
Startup and liveness use native HTTP health. Readiness additionally executes a fresh PostGIS query and authenticated Redis PING. Dependency outages remove readiness without making database availability a web liveness restart condition. Actual queued import completion is validated separately from HTTP health.
Worker readiness checks its native Sidekiq heartbeat and rejects stale or quiet processes. runtime.threads sets the
native Rails thread/database pool limit and must cover worker.concurrency. The default single Pod deliberately keeps
jobs and local files together; this topology does not provide horizontal scaling or zero-downtime maintenance.
Native monitoring and object storage
Optional authenticated web and Sidekiq exporters expose two private targets. The ServiceMonitor reads credentials from a
retained or existing Secret; a PrometheusRule detects unavailable targets. Restrict metrics.ingressFrom to the
monitoring namespace. Public /metrics remains inaccessible.
Native S3 storage supports existing credential Secrets, HTTPS endpoints and verified custom CA trust. It retains the application PVC for shared files and identity. S3 primary storage is independent of backup retention and recovery.
Operational guides
- Identity, administrator and native 2FA
- PostGIS and Redis dependencies
- Native Prometheus monitoring
- Storage and coordinated recovery
- Architecture and supported boundaries
Validation status
Isolated behavioral scenarios have passed native administrator login, closed registration, browser profile forms, queued GPX imports, two-factor enrollment, TOTP and recovery-code replay rejection, verified external PostGIS/Redis TLS, authenticated Prometheus scraping, S3 storage and Pod replacement. Acceptance checks original attachment bytes and retained identity keys as well as HTTP health.
Coordinated recovery into a fresh PostGIS database and PVC passed, including a custom spatial reference, original attachment bytes, exact coordinates and native 2FA. Production acceptance also verifies tokenless dependency Pods and withdrawn readiness for a quiet worker.
The complete make validate-chart CHART=dawarich gate passed on 2026-09-11: 23 validation layers, 36 Helm unit tests
and 13 isolated k3d scenarios, including all CI profiles. It covers real CRD schemas, ESO, dual-stack Services, Ingress,
Gateway API, browser interaction, private Prometheus scraping, external TLS, coordinated recovery and original S3 object
bytes. Application and dependency Pods had no unexpected restarts or crash terminations in the accepted scenarios.
Security Scan: dawarich
| Framework | Score |
|---|---|
| Overall | 98.53% |
| MITRE | 98.32% |
| NSA | 97.57% |
| SOC2 | 94.29% |
Kubescape 4.0.13, default rendered manifests, 2026-09-11. C-0012 flags the literal
ALLOW_EMAIL_PASSWORD_REGISTRATION=false policy setting and TLS admission code that reads credential environment
variables; neither contains a credential value. No controls were suppressed.
C-0034 identifies a real default limitation in the released Redis subchart: its Pod does not explicitly disable service-account token mounting. The production example configures Redis to reuse the chart-created tokenless ServiceAccount. Rails, Sidekiq and PostgreSQL already disable token mounting. The scan covers manifests; it does not replace image vulnerability management or application review.
Sources
identity details
The chart creates its initial administrator through Dawarich’s native Rails model before running upstream seeds. Password hashing, API-key generation and user callbacks remain native. No HTTP listener runs in that init container. An existing user database is admitted only with its retained identity fingerprint and an active administrator; initialization never silently resets an existing account.
Supply bootstrap.existingSecret with the key named by bootstrap.passwordKey, or let Helm generate a retained
password. Use at least 16 characters and no more than 72 UTF-8 bytes, matching the native password hashing boundary.
Store the Secret through your normal secret-management workflow and change the initial email before the first
installation. Later changes to bootstrap values do not rename users or rotate their passwords.
Registration policy
Rails binds only to loopback on port 3010. The public NGINX listener denies native API registration and Apple/Google
enrollment, the signup page and web OAuth routes. A documented Rails middleware initializer rejects Devise account
creation after Rack::MethodOverride, so authenticated profile update and deletion retain their native HTTP methods.
Native registration is also disabled in the cached setting.
This is a local-account deployment. The upstream environment flag alone does not close every registration route, and a readiness probe is not an enrollment barrier. Create additional accounts through trusted native administrator operations. Do not add a Service or ingress rule for the private Rails listener.
Two-factor authentication
Native TOTP setup is available because the chart supplies all three OTP encryption keys alongside SECRET_KEY_BASE.
Users enroll through Dawarich and retain their recovery codes securely. Password authentication for an enrolled user
returns a challenge rather than an API key; the challenge is completed with TOTP or a recovery code. These are native
Dawarich mechanisms, not a chart-managed authenticator.
The retained identity Secret contains:
SECRET_KEY_BASEOTP_ENCRYPTION_PRIMARY_KEYOTP_ENCRYPTION_DETERMINISTIC_KEYOTP_ENCRYPTION_KEY_DERIVATION_SALT
An existing user database must match the fingerprint on the application PVC before migrations start. Back up the matching Secret, database and PVC together. Key rotation requires a reviewed native migration; replacing the Secret with unrelated random values is not a password reset and will fail admission.
Trusted administration
Kubernetes exec, Secret access and namespace policy administration are trusted operator capabilities. The chart creates no Role or RoleBinding for the application and disables its projected API token. Use least-privilege RBAC for human operators.
For a reviewed native Rails maintenance script already placed in the Pod, the runtime wrapper initializes the same connection environment as the application:
kubectl exec -n locations deployment/dawarich-dawarich -c dawarich -- \
sh -ec 'unset BUNDLE_PATH BUNDLE_BIN; exec bundle exec ruby /helmforge/entrypoint.rb runner /tmp/reviewed-maintenance.rb'
Use the actual Deployment name from helm status. Do not print API keys, passwords, OTP seeds or backup codes into
operational logs.
dependencies details
Both dependencies are required. Select each independently: enable the HelmForge subchart or disable it and configure the corresponding external connection. Conflicting bundled and external connection settings fail Helm rendering.
Bundled PostGIS
HelmForge PostgreSQL 2.0.5 runs the official PostGIS image, pinned by manifest digest. The selected 18-3.6 image
contains PostgreSQL 18.6 and targets amd64. The database Pod is scheduled accordingly. An ARM-only cluster needs
external PostGIS; the chart does not silently substitute an unofficial ARM database image.
The DBA init script installs postgis and pgcrypto in the application database. The application role owns application
objects and runs migrations without being a superuser. The image is read-only, with bounded temporary and socket
volumes. The subchart sets PGDATA explicitly inside its persistent data mount.
Bundled connections use authenticated plaintext inside the configured namespace network boundary. Bundled TLS overrides are rejected; use the external contract for verified database TLS.
External PostGIS
Disable postgresql.enabled and configure database.host, port, name, username, passwordSecret and
passwordKey. Install both extensions as DBA before installing the application. The application role needs privileges
to create and migrate its own objects; avoid granting superuser privileges to make an extension error disappear.
External TLS defaults to enabled and uses libpq verify-full. An explicit CA Secret is required through
database.tls.caSecret and caKey. The hostname must match the certificate. No insecure hostname or CA bypass is
introduced by the chart.
Redis
The bundled HelmForge Redis runs standalone with authentication, persistence and noeviction. Cache and Sidekiq queues
use distinct logical databases, configured by cache.database and cache.queueDatabase. Redis Cluster is outside this
contract.
External Redis uses cache.host, port, username, passwordSecret and passwordKey. Credentials are encoded into
the native URI without changing their meaning; punctuation in passwords does not become URL syntax. Optional TLS
verifies the server certificate and hostname. A custom cache.tls.caSecret augments the image CA bundle for
Ruby/OpenSSL processes. This additional trust is process-wide; it is not a per-connection certificate pin.
The bundled Redis dependency does not expose Pod token automount in its released values contract. Its dedicated account has no RBAC grants and its NetworkPolicy denies egress. The production example shares the parent ServiceAccount, whose automount is disabled, so Redis also inherits that setting.
Network access and upgrades
Set networkPolicy.extraEgress for external endpoints. Default egress allows DNS and the bundled database/cache peers,
and does not enable general Internet access. Reverse-geocoding providers are unset by default; configure credentials and
the provider’s required egress explicitly if using them.
Native schema and data migration commands run sequentially, before web and worker start. Existing imports with pending
migration 20260125100000 require operator review: that upstream historical backfill compares an integer source column
with string names and rescues the resulting error. The chart blocks that affected upgrade instead of treating a
successful CLI exit as proof that historical backfill ran. An empty new installation has no historical imports to
backfill.
monitoring details
Enable metrics.enabled to expose native metrics through a private Service. The public application endpoint continues
to return 404 for /metrics.
The metrics Service has two authenticated ports:
| Endpoint | Default port | Purpose |
|---|---|---|
metrics |
9464 | Rails, ActiveRecord and Puma metrics, with native Sidekiq aggregation |
worker-metrics |
9394 | Direct native Sidekiq exporter availability and queue/job metrics |
The private NGINX listener exposes only /metrics. Basic authentication is enforced by the native application and
worker, using the same Secret. The chart generates and retains a random password unless metrics.auth.existingSecret is
configured. Secret key names are configurable; the ServiceMonitor reads those keys directly.
Prometheus Operator
Enable metrics.serviceMonitor.enabled after installing Prometheus Operator CRDs. Configure labels to match the
operator’s ServiceMonitor selector and set metrics.ingressFrom to its scraper Pods/namespaces. A second direct worker
target is intentional: the aggregate web endpoint can return web-only metrics if the worker exporter fails, so its HTTP
200 response alone does not prove worker health.
metrics.prometheusRule.enabled installs an availability rule for either target. Use additionalRules for
workload-specific thresholds. Useful native signals include sidekiq_jobs_success_total, sidekiq_jobs_failed_total,
sidekiq_jobs_waiting_count, sidekiq_jobs_retry_count, sidekiq_jobs_dead_count, sidekiq_queue_latency and
rails_requests_total. Select endpoint="worker-metrics" when alerting on direct worker metrics to avoid counting the
aggregate and direct copies together.
Readiness and operational scope
Web startup/liveness use native HTTP health. Web readiness adds a new PostGIS query and authenticated cache PING. Worker readiness checks the current Pod’s native Sidekiq heartbeat and rejects a stale or quiet process. A real queued GPX import is part of behavioral acceptance; neither a running PID nor a TCP port proves job execution.
CPU, memory and PVC alerts remain responsibilities of cluster monitoring. These application metrics do not implement distributed tracing or a backup system.
storage-recovery details
The application PVC retains local ActiveStorage objects, public assets, watched imports and the identity fingerprint. Rails and Sidekiq share those paths in one Recreate Pod. A writable private TMPDIR is created with mode 0700 for Ruby multipart uploads; making the container image writable is unnecessary.
Native S3
Set storage.driver: s3 with storage.s3.bucket, region and existingSecret. The Secret supplies access and secret
keys. endpoint is optional for AWS S3 and must use HTTPS when configured. A private CA can be supplied with
caSecret/caKey; the native AWS SDK receives it through AWS_CA_BUNDLE without disabling verification.
The pinned upstream storage configuration explicitly accepts credentials; ambient IAM identity and arbitrary SDK options are not chart promises. In particular, upstream does not expose a force-path-style setting. For compatible endpoints, the SDK chooses addressing from endpoint and bucket rules; the acceptance fixture uses a dotted bucket name over HTTPS and confirms native path addressing. Verify your backend’s naming and addressing requirements before migrating existing objects.
S3 changes where ActiveStorage stores objects. It does not remove the application PVC, create a backup policy or make the co-located workload horizontally scalable. Native signed object URLs are bearer links; protect them as access credentials. Apply bucket access, encryption, versioning and retention controls separately.
Recovery sequence
- Stop public writes and quiesce both Rails and Sidekiq. Allow in-flight jobs to finish within the maintenance window; inspect queued/retrying work.
- Take a checked PostgreSQL dump and a matching full filesystem archive/snapshot. For S3, preserve the corresponding object versions as well.
- Retain all four identity keys, connection Secrets and the application origin. Keep backups encrypted and access-controlled outside the cluster.
- Restore into a compatible PostGIS database and a fresh application PVC. Install extensions as DBA, restore application objects under the application role, and preserve custom spatial reference rows with the required DBA privileges.
- Point the release at the restored database and PVC. Let the serialized native migration/admission sequence finish before restoring traffic.
- Verify the actual database name, native login including 2FA, imported coordinates, completed import state and the original attachment bytes. Review queues and external integrations before resuming writers.
The dedicated ci/restore-values.yaml fixture uses pg_dump/pg_restore, a new database and a new PVC. It retains the
source until disposable namespace cleanup. PostGIS extension creation entries are handled by the DBA; custom
spatial_ref_sys rows are restored separately with checked errors rather than discarded. Native ActiveStorage downloads
verify the original GPX bytes after recovery.
This is a coordinated offline recovery strategy. PVC retention is not an off-cluster backup, and the chart does not claim an application-consistent live filesystem copy, automatic downgrade or transparent recovery of every interrupted Sidekiq job.
production-ingress example
# SPDX-License-Identifier: Apache-2.0
server:
publicUrl: https://locations.example.com
bootstrap:
email: [email protected]
existingSecret: dawarich-administrator
passwordKey: password
identity:
existingSecret: dawarich-identity
serviceAccount:
name: dawarich-runtime
redis:
serviceAccount:
create: false
name: dawarich-runtime
ingress:
enabled: true
ingressClassName: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: '3600'
nginx.ingress.kubernetes.io/proxy-body-size: 100m
hosts:
- host: locations.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: locations-tls
hosts: [locations.example.com]
networkPolicy:
ingressFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
external-tls example
# SPDX-License-Identifier: Apache-2.0
postgresql:
enabled: false
redis:
enabled: false
database:
host: postgis.database.svc.cluster.local
name: dawarich
username: dawarich
passwordSecret: dawarich-database
passwordKey: password
tls:
enabled: true
caSecret: database-ca
cache:
host: redis.database.svc.cluster.local
passwordSecret: dawarich-redis
tls:
enabled: true
caSecret: redis-ca
networkPolicy:
extraEgress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: database
ports:
- protocol: TCP
port: 5432
- protocol: TCP
port: 6379
monitoring example
# SPDX-License-Identifier: Apache-2.0
metrics:
enabled: true
auth:
existingSecret: dawarich-monitoring
ingressFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
serviceMonitor:
enabled: true
labels:
release: kube-prometheus-stack
prometheusRule:
enabled: true
labels:
release: kube-prometheus-stack
s3 example
# SPDX-License-Identifier: Apache-2.0
storage:
driver: s3
s3:
bucket: locations.example.com
region: us-east-1
endpoint: https://s3.storage.example.com
existingSecret: dawarich-object-storage
caSecret: object-storage-ca
# Replace this documentation address with the actual endpoint CIDR.
networkPolicy:
extraEgress:
- to:
- ipBlock:
cidr: 192.0.2.10/32
ports:
- protocol: TCP
port: 443
gateway-api example
# SPDX-License-Identifier: Apache-2.0
server:
publicUrl: https://locations.example.com
gatewayAPI:
enabled: true
httpRoutes:
- parentRefs:
- name: public
namespace: gateway-system
sectionName: https
hostnames: [locations.example.com]
networkPolicy:
ingressFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: gateway-system
Complete values
# SPDX-License-Identifier: Apache-2.0
# -- Override the chart name used in labels.
nameOverride: ''
# -- Override generated resource names.
fullnameOverride: ''
# -- Additional labels on chart resources.
commonLabels: {}
# -- One co-located Rails and Sidekiq Pod; other replica counts are rejected.
replicaCount: 1
# -- Registry authentication Secrets.
imagePullSecrets: []
# -- Additional upstream environment variables; managed identity, connections and policy settings are protected.
extraEnv: []
# -- Application ServiceAccount without RBAC grants.
serviceAccount:
# -- Create this resource.
create: true
# -- Resource name.
name: ''
# -- Additional resource annotations.
annotations: {}
# -- Configure automount service account token.
automountServiceAccountToken: false
# -- Public application Service.
service:
# -- Configure type.
type: ClusterIP
# -- Listener or Service port.
port: 3000
# -- Additional resource annotations.
annotations: {}
# -- Configure ip family policy.
ipFamilyPolicy: ''
# -- Configure ip families.
ipFamilies: []
# -- Ingress exposure for the application listener.
ingress:
# -- Enable this optional configuration.
enabled: false
# -- Configure ingress class name.
ingressClassName: ''
# -- Additional resource annotations.
annotations: {}
# -- Configure hosts.
hosts: []
# -- TLS settings.
tls: []
# -- Canonical Gateway API HTTPRoute configuration.
gatewayAPI:
# -- Enable this optional configuration.
enabled: false
# -- Configure http routes.
httpRoutes: []
# -- External Secrets Operator items for externally managed credentials.
externalSecrets:
# -- Enable this optional configuration.
enabled: false
# -- Configure refresh interval.
refreshInterval: 1h
# -- Configure items.
items: []
# -- Native web startup, readiness and liveness checks.
probes:
# -- Configure startup.
startup:
# -- Enable this optional configuration.
enabled: true
# -- Configure failure threshold.
failureThreshold: 60
# -- Configure period seconds.
periodSeconds: 5
# -- Configure timeout seconds.
timeoutSeconds: 5
# -- Configure readiness.
readiness:
# -- Enable this optional configuration.
enabled: true
# -- Configure failure threshold.
failureThreshold: 3
# -- Configure period seconds.
periodSeconds: 10
# -- Configure timeout seconds.
timeoutSeconds: 5
# -- Configure liveness.
liveness:
# -- Enable this optional configuration.
enabled: true
# -- Configure failure threshold.
failureThreshold: 3
# -- Configure period seconds.
periodSeconds: 20
# -- Configure timeout seconds.
timeoutSeconds: 5
# -- Rails CPU and memory requests and limits.
resources:
# -- Reserved CPU and memory.
requests:
# -- CPU quantity.
cpu: 500m
# -- Memory quantity.
memory: 768Mi
# -- Maximum CPU and memory.
limits:
# -- CPU quantity.
cpu: '2'
# -- Memory quantity.
memory: 2Gi
# -- UID/GID and filesystem group for the shared application Pod.
podSecurityContext:
# -- Configure run as non root.
runAsNonRoot: true
# -- Configure run as user.
runAsUser: 1000
# -- Configure run as group.
runAsGroup: 1000
# -- Configure fs group.
fsGroup: 1000
# -- Configure fs group change policy.
fsGroupChangePolicy: OnRootMismatch
# -- Configure seccomp profile.
seccompProfile:
# -- Configure type.
type: RuntimeDefault
# -- Restricted container security context for Rails, worker and proxy.
securityContext:
# -- Configure allow privilege escalation.
allowPrivilegeEscalation: false
# -- Configure read only root filesystem.
readOnlyRootFilesystem: true
# -- Configure capabilities.
capabilities:
# -- Configure drop.
drop:
- ALL
# -- Additional Pod labels; chart selectors cannot be overwritten.
podLabels: {}
# -- Additional Pod annotations.
podAnnotations: {}
# -- Application scheduling selectors; bundled PostGIS independently requires amd64.
nodeSelector: {}
# -- Application tolerations.
tolerations: []
# -- Application affinity rules.
affinity: {}
# -- Application topology constraints.
topologySpreadConstraints: []
# -- Existing workload priority class.
priorityClassName: ''
# -- Grace period for Rails and Sidekiq to stop before container termination.
terminationGracePeriodSeconds: 60
# -- Durable local objects, public assets, watched imports and identity fingerprint.
persistence:
# -- Enable this optional configuration.
enabled: true
# -- Configure existing claim.
existingClaim: ''
# -- Configure storage class.
storageClass: ''
# -- Requested storage capacity.
size: 20Gi
# -- Configure access modes.
accessModes:
- ReadWriteOnce
# -- Configure retain.
retain: true
# -- Additional resource annotations.
annotations: {}
# -- Bounded temporary storage and native Rails concurrency.
runtime:
# -- Capacity of each application temporary emptyDir.
temporarySize: 1Gi
# -- Native Rails thread and database-pool limit; must be at least worker.concurrency.
threads: 5
# -- Configure image.
image:
# -- Configure repository.
repository: docker.io/freikin/dawarich
# -- Configure tag.
tag: 1.14.4
# -- Configure pull policy.
pullPolicy: IfNotPresent
# -- Public origin and application listener.
server:
# -- Public NGINX port; native Rails stays on loopback 3010.
port: 3000
# -- Stable browser-visible HTTP(S) origin; use HTTPS behind production ingress.
publicUrl: ''
# -- Configure time zone.
timeZone: Etc/UTC
# -- Private native administrator provisioning before upstream seeds.
bootstrap:
# -- Initial administrator email; existing users are never renamed.
email: [email protected]
# -- Optional initial password; prefer an existing Secret. Use 16 to 72 characters and no more than 72 UTF-8 bytes.
password: ''
# -- Existing initial administrator Secret; otherwise generate and retain one.
existingSecret: ''
# -- Secret key containing the initial administrator password.
passwordKey: admin-password
# -- Application, metrics and bundled Redis network isolation.
networkPolicy:
# -- Enable this optional configuration.
enabled: true
# -- Configure ingress from.
ingressFrom: []
# -- Configure egress isolation.
egressIsolation: true
# -- Configure dns egress.
dnsEgress:
# -- Configure namespace selector.
- namespaceSelector:
# -- Configure match labels.
matchLabels:
# -- Configure kubernetes.io/metadata.name.
kubernetes.io/metadata.name: kube-system
# -- Configure pod selector.
podSelector:
# -- Configure match labels.
matchLabels:
# -- Configure k8s-app.
k8s-app: kube-dns
# -- Configure extra egress.
extraEgress: []
# -- External PostGIS connection; used when postgresql.enabled=false.
database:
# -- External PostgreSQL hostname matching its TLS certificate.
host: ''
# -- External PostgreSQL port.
port: 5432
# -- External application database with postgis and pgcrypto installed.
name: dawarich
# -- Application role with migration privileges, without superuser access.
username: dawarich
# -- Secret containing the external database password.
passwordSecret: ''
# -- Key containing the database password.
passwordKey: password
# -- libpq verified TLS; requires an explicit CA Secret.
tls:
# -- Use sslmode=verify-full for external PostGIS.
enabled: true
# -- Secret containing the trusted PostgreSQL CA bundle.
caSecret: ''
# -- Secret key containing the PEM CA bundle.
caKey: ca.crt
# -- Redis credentials, verified TLS and distinct cache/queue logical databases.
cache:
# -- External Redis hostname.
host: ''
# -- External Redis port.
port: 6379
# -- Optional Redis ACL username.
username: ''
# -- Secret containing the external Redis password.
passwordSecret: ''
# -- Key containing the Redis password.
passwordKey: redis-password
# -- Native Rails cache logical database.
database: 0
# -- Verified external Redis TLS.
tls:
# -- Use rediss with certificate and hostname verification.
enabled: true
# -- Optional private CA added to the Ruby/OpenSSL process trust bundle.
caSecret: ''
# -- Secret key containing the PEM Redis CA bundle.
caKey: ca.crt
# -- Native Sidekiq logical database; must differ from cache.database.
queueDatabase: 1
# -- HelmForge PostgreSQL with official pinned amd64 PostGIS image and DBA extension initialization.
postgresql:
# -- Configure initdb.
initdb:
# -- Configure scripts.
scripts:
# -- Configure 20-dawarich-postgis.sh.
20-dawarich-postgis.sh: |
#!/bin/bash
set -euo pipefail
export PGPASSWORD="${POSTGRES_PASSWORD}"
psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --dbname "${APP_DATABASE}" <<'SQL'
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
SQL
# -- Configure security context.
securityContext:
# -- Configure read only root filesystem.
readOnlyRootFilesystem: true
# -- Configure extra volumes.
extraVolumes:
# -- Resource name.
- name: postgres-tmp
# -- Configure empty dir.
emptyDir:
# -- Configure size limit.
sizeLimit: 1Gi
# -- Resource name.
- name: postgres-socket
# -- Configure empty dir.
emptyDir:
# -- Configure medium.
medium: Memory
# -- Configure size limit.
sizeLimit: 16Mi
# -- Configure extra volume mounts.
extraVolumeMounts:
# -- Resource name.
- name: postgres-tmp
# -- Configure mount path.
mountPath: /tmp
# -- Resource name.
- name: postgres-socket
# -- Configure mount path.
mountPath: /var/run/postgresql
# -- Configure network policy.
networkPolicy:
# -- Enable this optional configuration.
enabled: true
# -- Configure egress.
egress:
# -- Enable this optional configuration.
enabled: true
# -- Configure allow dns.
allowDNS: true
# -- Configure allow same namespace postgre sql.
allowSameNamespacePostgreSQL: false
# -- Configure allow https.
allowHTTPS: false
# -- Enable this optional configuration.
enabled: true
# -- Configure architecture.
architecture: standalone
# -- Configure auth.
auth:
# -- Configure database.
database: dawarich
# -- Configure username.
username: dawarich
# -- Existing externally managed Secret.
existingSecret: ''
# -- Configure existing secret user password key.
existingSecretUserPasswordKey: user-password
# -- Configure image.
image:
# -- Configure repository.
repository: postgis/postgis
# -- Configure tag.
tag: 18-3.6@sha256:7e00e8c3539fdd43f513b98806c8204714dcd09dea683c259e333d7690317119
# -- Configure node selector.
nodeSelector:
# -- Configure kubernetes.io/arch.
kubernetes.io/arch: amd64
# -- HelmForge authenticated standalone Redis with persistence and noeviction.
redis:
# -- Configure service account.
serviceAccount:
# -- Create this resource.
create: true
# -- Configure security context.
securityContext:
# -- Configure read only root filesystem.
readOnlyRootFilesystem: true
# -- Configure capabilities.
capabilities:
# -- Configure drop.
drop:
- ALL
# -- Configure seccomp profile.
seccompProfile:
# -- Configure type.
type: RuntimeDefault
# -- Enable this optional configuration.
enabled: true
# -- Configure architecture.
architecture: standalone
# -- Configure auth.
auth:
# -- Enable this optional configuration.
enabled: true
# -- Configure password.
password: ''
# -- Existing externally managed Secret.
existingSecret: ''
# -- Configure existing secret password key.
existingSecretPasswordKey: redis-password
# -- Configure config.
config:
# -- Configure redis.
redis: |
maxmemory-policy noeviction
appendonly yes
# -- Configure standalone.
standalone:
# -- Configure persistence.
persistence:
# -- Enable this optional configuration.
enabled: true
# -- Requested storage capacity.
size: 5Gi
# -- CPU and memory requests and limits.
resources:
# -- Reserved CPU and memory.
requests:
# -- CPU quantity.
cpu: 100m
# -- Memory quantity.
memory: 128Mi
# -- Maximum CPU and memory.
limits:
# -- CPU quantity.
cpu: 500m
# -- Memory quantity.
memory: 512Mi
# -- Official unprivileged NGINX for public policy and private metrics.
proxy:
# -- Configure image.
image:
# -- Configure repository.
repository: docker.io/nginxinc/nginx-unprivileged
# -- Configure tag.
tag: 1.30.4-alpine
# -- Configure pull policy.
pullPolicy: IfNotPresent
# -- CPU and memory requests and limits.
resources:
# -- Reserved CPU and memory.
requests:
# -- CPU quantity.
cpu: 50m
# -- Memory quantity.
memory: 32Mi
# -- Maximum CPU and memory.
limits:
# -- CPU quantity.
cpu: 500m
# -- Memory quantity.
memory: 128Mi
# -- Maximum incoming request body accepted by NGINX.
bodySize: 100m
# -- Retained Rails and OTP identity keys.
identity:
# -- Existing Secret containing all four documented native identity keys.
existingSecret: ''
# -- Co-located native Sidekiq process.
worker:
# -- Maximum concurrent jobs; must not exceed runtime.threads.
concurrency: 3
# -- Worker CPU and memory budget.
resources:
# -- Reserved CPU and memory.
requests:
# -- CPU quantity.
cpu: 250m
# -- Memory quantity.
memory: 512Mi
# -- Maximum CPU and memory.
limits:
# -- CPU quantity.
cpu: '2'
# -- Memory quantity.
memory: 2Gi
# -- Authenticated native web and Sidekiq metrics.
metrics:
# -- Enable both native exporters and their private Service.
enabled: false
# -- Private web metrics proxy port; worker uses 9394.
port: 9464
# -- NetworkPolicy peers allowed to reach both metrics ports.
ingressFrom:
# -- Configure namespace selector.
- namespaceSelector:
# -- Configure match labels.
matchLabels:
# -- Configure kubernetes.io/metadata.name.
kubernetes.io/metadata.name: monitoring
# -- Two-target Prometheus Operator ServiceMonitor.
serviceMonitor:
# -- Enable this optional configuration.
enabled: false
# -- Additional selector-compatible labels.
labels: {}
# -- Configure interval.
interval: 30s
# -- Configure scrape timeout.
scrapeTimeout: 10s
# -- Target availability rule and optional workload-specific alerts.
prometheusRule:
# -- Enable this optional configuration.
enabled: false
# -- Additional selector-compatible labels.
labels: {}
# -- Configure additional rules.
additionalRules: []
# -- Native Basic authentication shared by web, worker and ServiceMonitor.
auth:
# -- Existing metrics credentials; otherwise retain a generated password.
existingSecret: ''
# -- Username for chart-generated monitoring credentials.
username: prometheus
# -- Secret key containing the metrics username.
usernameKey: username
# -- Secret key containing the metrics password.
passwordKey: password
# -- Native ActiveStorage backend; a local application PVC remains required.
storage:
# -- Native local or s3 object storage.
driver: local
# -- Native AWS SDK object-storage configuration.
s3:
# -- Existing private S3 bucket.
bucket: ''
# -- AWS signing region.
region: us-east-1
# -- Optional HTTPS S3-compatible endpoint; native SDK addressing rules apply.
endpoint: ''
# -- Secret containing static object-storage credentials.
existingSecret: ''
# -- Secret key containing the S3 access key ID.
accessKeyIdKey: access-key-id
# -- Secret key containing the S3 secret access key.
secretAccessKeyKey: secret-access-key
# -- Optional custom CA bundle scoped to the native AWS client.
caSecret: ''
# -- Secret key containing the S3 CA bundle.
caKey: ca.crt